Skip to content

Commit 2d4b259

Browse files
committed
Sema: Type variables for opened generic parameters store the generic parameter type and not an archetype
There's no need to instantiate archetypes in the generic environment of the declaration being opened. A couple of diagnostics changed. They were already misleading, and the new diagnostics, while different, are not any more misleading than before.
1 parent e080bab commit 2d4b259

File tree

11 files changed

+103
-101
lines changed

11 files changed

+103
-101
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
333333
// should be allowed to escape. As a result we allow anything
334334
// passed in to escape.
335335
if (auto *fnTy = type->getAs<AnyFunctionType>())
336-
if (typeVar->getImpl().getArchetype() && !shouldAttemptFixes())
336+
if (typeVar->getImpl().getGenericParameter() && !shouldAttemptFixes())
337337
type = fnTy->withExtInfo(fnTy->getExtInfo().withNoEscape(false));
338338

339339
// Check whether we can perform this binding.

lib/Sema/CSDiag.cpp

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -472,15 +472,16 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
472472
/// true.
473473
bool diagnoseAmbiguousMultiStatementClosure(ClosureExpr *closure);
474474

475-
/// Check the associated constraint system to see if it has any archetypes
476-
/// not properly resolved or missing. If so, diagnose the problem with
477-
/// an error and return true.
478-
bool diagnoseArchetypeAmbiguity();
475+
/// Check the associated constraint system to see if it has any opened generic
476+
/// parameters that were not bound to a fixed type. If so, diagnose the
477+
/// problem with an error and return true.
478+
bool diagnoseAmbiguousGenericParameters();
479479

480-
/// Emit an error message about an unbound generic parameter existing, and
481-
/// emit notes referring to the target of a diagnostic, e.g., the function
482-
/// or parameter being used.
483-
void diagnoseUnboundArchetype(ArchetypeType *archetype, Expr *anchor);
480+
/// Emit an error message about an unbound generic parameter, and emit notes
481+
/// referring to the target of a diagnostic, e.g., the function or parameter
482+
/// being used.
483+
void diagnoseAmbiguousGenericParameter(GenericTypeParamType *paramTy,
484+
Expr *anchor);
484485

485486
/// Produce a diagnostic for a general member-lookup failure (irrespective of
486487
/// the exact expression kind).
@@ -4687,9 +4688,12 @@ bool FailureDiagnosis::diagnoseArgumentGenericRequirements(
46874688
.getOldType()
46884689
->getWithoutSpecifierType();
46894690

4690-
if (argType->is<ArchetypeType>()) {
4691-
diagnoseUnboundArchetype(archetype, fnExpr);
4692-
return true;
4691+
if (auto *archetype = argType->getAs<ArchetypeType>()) {
4692+
auto interfaceTy = archetype->getInterfaceType();
4693+
if (auto *paramTy = interfaceTy->getAs<GenericTypeParamType>()) {
4694+
diagnoseAmbiguousGenericParameter(paramTy, fnExpr);
4695+
return true;
4696+
}
46934697
}
46944698

46954699
if (isUnresolvedOrTypeVarType(argType) || argType->hasError())
@@ -7735,22 +7739,18 @@ void ConstraintSystem::diagnoseFailureForExpr(Expr *expr) {
77357739
diagnosis.diagnoseAmbiguity(expr);
77367740
}
77377741

7738-
// FIXME: Instead of doing this, we should store the decl in the type
7739-
// variable, or in the locator.
7740-
static bool hasArchetype(const GenericTypeDecl *generic,
7741-
ArchetypeType *archetype) {
7742-
assert(!archetype->getOpenedExistentialType() &&
7743-
!archetype->getParent());
7744-
7745-
auto genericEnv = generic->getGenericEnvironment();
7746-
if (!genericEnv)
7742+
static bool hasGenericParameter(const GenericTypeDecl *generic,
7743+
GenericTypeParamType *paramTy) {
7744+
auto *decl = paramTy->getDecl();
7745+
if (!decl)
77477746
return false;
77487747

7749-
return archetype->getGenericEnvironment() == genericEnv;
7748+
return decl->getDeclContext() == generic;
77507749
}
77517750

7752-
static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
7753-
ConstraintSystem &cs) {
7751+
static void noteGenericParameterSource(const TypeLoc &loc,
7752+
GenericTypeParamType *paramTy,
7753+
ConstraintSystem &cs) {
77547754
const GenericTypeDecl *FoundDecl = nullptr;
77557755
const ComponentIdentTypeRepr *FoundGenericTypeBase = nullptr;
77567756

@@ -7759,10 +7759,10 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
77597759
struct FindGenericTypeDecl : public ASTWalker {
77607760
const GenericTypeDecl *FoundDecl = nullptr;
77617761
const ComponentIdentTypeRepr *FoundGenericTypeBase = nullptr;
7762-
ArchetypeType *Archetype;
7762+
GenericTypeParamType *ParamTy;
77637763

7764-
FindGenericTypeDecl(ArchetypeType *Archetype)
7765-
: Archetype(Archetype) {}
7764+
FindGenericTypeDecl(GenericTypeParamType *ParamTy)
7765+
: ParamTy(ParamTy) {}
77667766

77677767
bool walkToTypeReprPre(TypeRepr *T) override {
77687768
// If we already emitted the note, we're done.
@@ -7771,7 +7771,7 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
77717771
if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
77727772
auto *generic =
77737773
dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl());
7774-
if (generic && hasArchetype(generic, Archetype)) {
7774+
if (generic && hasGenericParameter(generic, ParamTy)) {
77757775
FoundDecl = generic;
77767776
FoundGenericTypeBase = ident;
77777777
return false;
@@ -7780,7 +7780,7 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
77807780
// Keep walking.
77817781
return true;
77827782
}
7783-
} findGenericTypeDecl(archetype);
7783+
} findGenericTypeDecl(paramTy);
77847784

77857785
typerepr->walk(findGenericTypeDecl);
77867786
FoundDecl = findGenericTypeDecl.FoundDecl;
@@ -7791,7 +7791,7 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
77917791
// type checked expression.
77927792
if (!FoundDecl) {
77937793
if (const GenericTypeDecl *generic = loc.getType()->getAnyGeneric())
7794-
if (hasArchetype(generic, archetype))
7794+
if (hasGenericParameter(generic, paramTy))
77957795
FoundDecl = generic;
77967796
}
77977797

@@ -7804,7 +7804,7 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
78047804
type = typeAlias->getUnboundGenericType();
78057805
else
78067806
type = FoundDecl->getDeclaredInterfaceType();
7807-
tc.diagnose(FoundDecl, diag::archetype_declared_in_type, archetype, type);
7807+
tc.diagnose(FoundDecl, diag::archetype_declared_in_type, paramTy, type);
78087808
}
78097809

78107810
if (FoundGenericTypeBase && !isa<GenericIdentTypeRepr>(FoundGenericTypeBase)){
@@ -8065,25 +8065,23 @@ diagnoseAmbiguousMultiStatementClosure(ClosureExpr *closure) {
80658065
/// Check the associated constraint system to see if it has any archetypes
80668066
/// not properly resolved or missing. If so, diagnose the problem with
80678067
/// an error and return true.
8068-
bool FailureDiagnosis::diagnoseArchetypeAmbiguity() {
8069-
using Archetype = std::tuple<ArchetypeType *, ConstraintLocator *, unsigned>;
8070-
8071-
llvm::SmallVector<Archetype, 2> unboundParams;
8072-
// Check out all of the type variables lurking in the system. If any are
8073-
// unbound archetypes, then the problem is that it couldn't be resolved.
8068+
bool FailureDiagnosis::diagnoseAmbiguousGenericParameters() {
8069+
using GenericParameter = std::tuple<GenericTypeParamType *,
8070+
ConstraintLocator *,
8071+
unsigned>;
8072+
8073+
llvm::SmallVector<GenericParameter, 2> unboundParams;
8074+
// Check out all of the type variables lurking in the system. If any free
8075+
// type variables were created when opening generic parameters, diagnose
8076+
// that the generic parameter could not be inferred.
80748077
for (auto tv : CS.getTypeVariables()) {
80758078
auto &impl = tv->getImpl();
80768079

80778080
if (impl.hasRepresentativeOrFixed())
80788081
continue;
80798082

8080-
// If this is a conversion to a type variable used to form an archetype,
8081-
// Then diagnose this as a generic parameter that could not be resolved.
8082-
auto archetype = impl.getArchetype();
8083-
8084-
// Only diagnose archetypes that don't have a parent, i.e., ones
8085-
// that correspond to generic parameters.
8086-
if (!archetype || archetype->getParent())
8083+
auto *paramTy = impl.getGenericParameter();
8084+
if (!paramTy)
80878085
continue;
80888086

80898087
// Number of constraints related to particular unbound parameter
@@ -8117,22 +8115,22 @@ bool FailureDiagnosis::diagnoseArchetypeAmbiguity() {
81178115
}
81188116

81198117
auto locator = impl.getLocator();
8120-
unboundParams.push_back(
8121-
std::make_tuple(archetype, locator, numConstraints));
8118+
unboundParams.emplace_back(paramTy, locator, numConstraints);
81228119
}
81238120

81248121
// We've found unbound generic parameters, let's diagnose
81258122
// based on the number of constraints each one is related to.
81268123
if (!unboundParams.empty()) {
8127-
// Let's prioritize archetypes that don't have any constraints associated.
8124+
// Let's prioritize generic parameters that don't have any constraints
8125+
// associated.
81288126
std::stable_sort(unboundParams.begin(), unboundParams.end(),
8129-
[](Archetype a, Archetype b) {
8127+
[](GenericParameter a, GenericParameter b) {
81308128
return std::get<2>(a) < std::get<2>(b);
81318129
});
81328130

81338131
auto param = unboundParams.front();
8134-
diagnoseUnboundArchetype(std::get<0>(param),
8135-
std::get<1>(param)->getAnchor());
8132+
diagnoseAmbiguousGenericParameter(std::get<0>(param),
8133+
std::get<1>(param)->getAnchor());
81368134
return true;
81378135
}
81388136

@@ -8142,18 +8140,19 @@ bool FailureDiagnosis::diagnoseArchetypeAmbiguity() {
81428140
/// Emit an error message about an unbound generic parameter existing, and
81438141
/// emit notes referring to the target of a diagnostic, e.g., the function
81448142
/// or parameter being used.
8145-
void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
8146-
Expr *anchor) {
8143+
void FailureDiagnosis::
8144+
diagnoseAmbiguousGenericParameter(GenericTypeParamType *paramTy,
8145+
Expr *anchor) {
81478146
auto &tc = CS.getTypeChecker();
81488147

8149-
// The archetype may come from the explicit type in a cast expression.
8148+
// The generic parameter may come from the explicit type in a cast expression.
81508149
if (auto *ECE = dyn_cast_or_null<ExplicitCastExpr>(anchor)) {
81518150
tc.diagnose(ECE->getLoc(), diag::unbound_generic_parameter_cast,
8152-
archetype, ECE->getCastTypeLoc().getType())
8151+
paramTy, ECE->getCastTypeLoc().getType())
81538152
.highlight(ECE->getCastTypeLoc().getSourceRange());
81548153

81558154
// Emit a note specifying where this came from, if we can find it.
8156-
noteArchetypeSource(ECE->getCastTypeLoc(), archetype, CS);
8155+
noteGenericParameterSource(ECE->getCastTypeLoc(), paramTy, CS);
81578156
return;
81588157
}
81598158

@@ -8173,17 +8172,17 @@ void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
81738172

81748173

81758174
// Otherwise, emit an error message on the expr we have, and emit a note
8176-
// about where the archetype came from.
8177-
tc.diagnose(expr->getLoc(), diag::unbound_generic_parameter, archetype);
8175+
// about where the generic parameter came from.
8176+
tc.diagnose(expr->getLoc(), diag::unbound_generic_parameter, paramTy);
81788177

81798178
// If we have an anchor, drill into it to emit a
8180-
// "note: archetype declared here".
8179+
// "note: generic parameter declared here".
81818180
if (!anchor) return;
81828181

81838182

81848183
if (auto TE = dyn_cast<TypeExpr>(anchor)) {
81858184
// Emit a note specifying where this came from, if we can find it.
8186-
noteArchetypeSource(TE->getTypeLoc(), archetype, CS);
8185+
noteGenericParameterSource(TE->getTypeLoc(), paramTy, CS);
81878186
return;
81888187
}
81898188

@@ -8232,8 +8231,8 @@ void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
82328231
/// Emit an ambiguity diagnostic about the specified expression.
82338232
void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
82348233
// First, let's try to diagnose any problems related to ambiguous
8235-
// archetypes (generic parameters) present in the constraint system.
8236-
if (diagnoseArchetypeAmbiguity())
8234+
// generic parameters present in the constraint system.
8235+
if (diagnoseAmbiguousGenericParameters())
82378236
return;
82388237

82398238
// Unresolved/Anonymous ClosureExprs are common enough that we should give

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,12 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseAsError() {
271271
return false;
272272

273273
auto &last = path.back();
274-
if (last.getKind() != ConstraintLocator::Archetype)
274+
if (last.getKind() != ConstraintLocator::GenericParameter)
275275
return false;
276276

277-
auto *archetype = last.getArchetype();
277+
auto *paramTy = last.getGenericParameter();
278278
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type,
279-
archetype);
279+
paramTy);
280280
return true;
281281
}
282282

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ ConstraintSystem::matchTypesBindTypeVar(
15321532
// represent an opened archetype. If we allowed this it would allow
15331533
// the noescape function to potentially escape.
15341534
if (auto *fnTy = type->getAs<FunctionType>()) {
1535-
if (fnTy->isNoEscape() && typeVar->getImpl().getArchetype()) {
1535+
if (fnTy->isNoEscape() && typeVar->getImpl().getGenericParameter()) {
15361536
if (shouldAttemptFixes()) {
15371537
auto *fix = MarkExplicitlyEscaping::create(
15381538
*this, getConstraintLocator(locator));

lib/Sema/ConstraintLocator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
3333
for (auto elt : path) {
3434
id.AddInteger(elt.getKind());
3535
switch (elt.getKind()) {
36-
case Archetype:
37-
id.AddPointer(elt.getArchetype()->getCanonicalType().getPointer());
36+
case GenericParameter:
37+
id.AddPointer(elt.getGenericParameter());
3838
break;
3939

4040
case Requirement:
@@ -109,8 +109,8 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
109109
for (auto elt : getPath()) {
110110
out << " -> ";
111111
switch (elt.getKind()) {
112-
case Archetype:
113-
out << "archetype '" << elt.getArchetype()->getString() << "'";
112+
case GenericParameter:
113+
out << "generic parameter '" << elt.getGenericParameter()->getString() << "'";
114114
break;
115115

116116
case ApplyArgument:

lib/Sema/ConstraintLocator.h

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ class ConstraintLocator : public llvm::FoldingSetNode {
5959
ApplyFunction,
6060
/// Matching an argument to a parameter.
6161
ApplyArgToParam,
62-
/// \brief An archetype being opened.
62+
/// \brief A generic parameter being opened.
6363
///
64-
/// Also contains the archetype itself.
65-
Archetype,
64+
/// Also contains the generic parameter type itself.
65+
GenericParameter,
6666
/// \brief The argument type of a function.
6767
FunctionArgument,
6868
/// \brief The result type of a function.
@@ -133,7 +133,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
133133
switch (kind) {
134134
case ApplyArgument:
135135
case ApplyFunction:
136-
case Archetype:
136+
case GenericParameter:
137137
case FunctionArgument:
138138
case FunctionResult:
139139
case OptionalPayload:
@@ -205,7 +205,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
205205
case RValueAdjustment:
206206
case SubscriptMember:
207207
case OpenedGeneric:
208-
case Archetype:
208+
case GenericParameter:
209209
case GenericArgument:
210210
case NamedTupleElement:
211211
case TupleElement:
@@ -233,7 +233,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
233233
class PathElement {
234234
/// \brief Describes the kind of data stored here.
235235
enum StoredKind : unsigned char {
236-
StoredArchetype,
236+
StoredGenericParameter,
237237
StoredRequirement,
238238
StoredWitness,
239239
StoredKindAndValue
@@ -291,13 +291,13 @@ class ConstraintLocator : public llvm::FoldingSetNode {
291291
"Path element requires value");
292292
}
293293

294-
PathElement(ArchetypeType *archetype)
295-
: storage((reinterpret_cast<uintptr_t>(archetype) >> 2)),
296-
storedKind(StoredArchetype)
294+
PathElement(GenericTypeParamType *type)
295+
: storage((reinterpret_cast<uintptr_t>(type) >> 2)),
296+
storedKind(StoredGenericParameter)
297297
{
298-
static_assert(alignof(ArchetypeType) >= 4,
298+
static_assert(alignof(GenericTypeParamType) >= 4,
299299
"archetypes insufficiently aligned");
300-
assert(getArchetype() == archetype);
300+
assert(getGenericParameter() == type);
301301
}
302302

303303
PathElement(PathElementKind kind, ValueDecl *decl)
@@ -353,8 +353,8 @@ class ConstraintLocator : public llvm::FoldingSetNode {
353353
/// \brief Retrieve the kind of path element.
354354
PathElementKind getKind() const {
355355
switch (static_cast<StoredKind>(storedKind)) {
356-
case StoredArchetype:
357-
return Archetype;
356+
case StoredGenericParameter:
357+
return GenericParameter;
358358

359359
case StoredRequirement:
360360
return Requirement;
@@ -400,10 +400,12 @@ class ConstraintLocator : public llvm::FoldingSetNode {
400400
return reinterpret_cast<ValueDecl *>(storage << 2);
401401
}
402402

403-
/// \brief Retrieve the actual archetype for an archetype path element.
404-
ArchetypeType *getArchetype() const {
405-
assert(getKind() == Archetype && "Not an archetype path element");
406-
return reinterpret_cast<ArchetypeType *>(storage << 2);
403+
/// \brief Retrieve the actual archetype for a generic parameter path
404+
/// element.
405+
GenericTypeParamType *getGenericParameter() const {
406+
assert(getKind() == GenericParameter &&
407+
"Not a generic parameter path element");
408+
return reinterpret_cast<GenericTypeParamType *>(storage << 2);
407409
}
408410

409411
/// Retrieve the declaration for a requirement path element.

0 commit comments

Comments
 (0)