@@ -6478,39 +6478,112 @@ void ConstraintSystem::diagnoseFailureForExpr(Expr *expr) {
64786478 diagnosis.diagnoseAmbiguity (expr);
64796479}
64806480
6481+ static bool hasArchetype (const GenericTypeDecl *generic,
6482+ const ArchetypeType *archetype) {
6483+ return std::any_of (generic->getInnermostGenericParamTypes ().begin (),
6484+ generic->getInnermostGenericParamTypes ().end (),
6485+ [archetype](const GenericTypeParamType *genericParamTy) {
6486+ return genericParamTy->getDecl ()->getArchetype () == archetype;
6487+ });
6488+ }
6489+
64816490static void noteArchetypeSource (const TypeLoc &loc, ArchetypeType *archetype,
6482- TypeChecker &tc) {
6483- GenericTypeDecl *FoundDecl = nullptr ;
6484-
6491+ ConstraintSystem &cs) {
6492+ const GenericTypeDecl *FoundDecl = nullptr ;
6493+ const ComponentIdentTypeRepr *FoundGenericTypeBase = nullptr ;
6494+
64856495 // Walk the TypeRepr to find the type in question.
64866496 if (auto typerepr = loc.getTypeRepr ()) {
64876497 struct FindGenericTypeDecl : public ASTWalker {
6488- GenericTypeDecl *&FoundDecl;
6489- FindGenericTypeDecl (GenericTypeDecl *&FoundDecl) : FoundDecl(FoundDecl) {
6490- }
6498+ const GenericTypeDecl *FoundDecl = nullptr ;
6499+ const ComponentIdentTypeRepr *FoundGenericTypeBase = nullptr ;
6500+ const ArchetypeType *Archetype;
6501+
6502+ FindGenericTypeDecl (const ArchetypeType *Archetype)
6503+ : Archetype(Archetype) {}
64916504
64926505 bool walkToTypeReprPre (TypeRepr *T) override {
64936506 // If we already emitted the note, we're done.
64946507 if (FoundDecl) return false ;
64956508
6496- if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T))
6497- FoundDecl = dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl ());
6509+ if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
6510+ auto *generic =
6511+ dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl ());
6512+ if (hasArchetype (generic, Archetype)) {
6513+ FoundDecl = generic;
6514+ FoundGenericTypeBase = ident;
6515+ return false ;
6516+ }
6517+ }
64986518 // Keep walking.
64996519 return true ;
65006520 }
6501- } findGenericTypeDecl (FoundDecl );
6502-
6521+ } findGenericTypeDecl (archetype );
6522+
65036523 typerepr->walk (findGenericTypeDecl);
6524+ FoundDecl = findGenericTypeDecl.FoundDecl ;
6525+ FoundGenericTypeBase = findGenericTypeDecl.FoundGenericTypeBase ;
65046526 }
6505-
6527+
65066528 // If we didn't find the type in the TypeRepr, fall back to the type in the
65076529 // type checked expression.
6508- if (!FoundDecl)
6509- FoundDecl = loc.getType ()->getAnyGeneric ();
6510-
6511- if (FoundDecl)
6512- tc.diagnose (FoundDecl, diag::archetype_declared_in_type, archetype,
6513- FoundDecl->getDeclaredType ());
6530+ if (!FoundDecl) {
6531+ if (const GenericTypeDecl *generic = loc.getType ()->getAnyGeneric ())
6532+ if (hasArchetype (generic, archetype))
6533+ FoundDecl = generic;
6534+ }
6535+
6536+ auto &tc = cs.getTypeChecker ();
6537+ if (FoundDecl) {
6538+ tc.diagnose (FoundDecl, diag::archetype_declared_in_type,
6539+ archetype, FoundDecl->getDeclaredType ());
6540+ }
6541+
6542+ if (FoundGenericTypeBase && !isa<GenericIdentTypeRepr>(FoundGenericTypeBase)){
6543+ assert (FoundDecl);
6544+
6545+ // If we can, prefer using any types already fixed by the constraint system.
6546+ // This lets us produce fixes like `Pair<Int, Any>` instead of defaulting to
6547+ // `Pair<Any, Any>`.
6548+ // Right now we only handle this when the type that's at fault is the
6549+ // top-level type passed to this function.
6550+ ArrayRef<Type> genericArgs;
6551+ if (auto *boundGenericTy = loc.getType ()->getAs <BoundGenericType>()) {
6552+ if (boundGenericTy->getDecl () == FoundDecl)
6553+ genericArgs = boundGenericTy->getGenericArgs ();
6554+ }
6555+
6556+ auto getPreferredType =
6557+ [&](const GenericTypeParamDecl *genericParam) -> Type {
6558+ // If we were able to get the generic arguments (i.e. the types used at
6559+ // FoundDecl's use site), we can prefer those...
6560+ if (genericArgs.empty ())
6561+ return Type ();
6562+
6563+ Type preferred = genericArgs[genericParam->getIndex ()];
6564+ if (!preferred || preferred->is <ErrorType>())
6565+ return Type ();
6566+
6567+ // ...but only if they were actually resolved by the constraint system
6568+ // despite the failure.
6569+ TypeVariableType *unused;
6570+ Type maybeFixedType = cs.getFixedTypeRecursive (preferred, unused,
6571+ /* wantRValue*/ true );
6572+ if (maybeFixedType->hasTypeVariable () ||
6573+ maybeFixedType->hasUnresolvedType ()) {
6574+ return Type ();
6575+ }
6576+ return maybeFixedType;
6577+ };
6578+
6579+ SmallString<64 > genericParamBuf;
6580+ if (tc.getDefaultGenericArgumentsString (genericParamBuf, FoundDecl,
6581+ getPreferredType)) {
6582+ tc.diagnose (FoundGenericTypeBase->getLoc (),
6583+ diag::unbound_generic_parameter_explicit_fix)
6584+ .fixItInsertAfter (FoundGenericTypeBase->getEndLoc (), genericParamBuf);
6585+ }
6586+ }
65146587}
65156588
65166589
@@ -6626,11 +6699,7 @@ void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
66266699 .highlight (ECE->getCastTypeLoc ().getSourceRange ());
66276700
66286701 // Emit a note specifying where this came from, if we can find it.
6629- noteArchetypeSource (ECE->getCastTypeLoc (), archetype, tc);
6630- if (auto *ND = ECE->getCastTypeLoc ().getType ()
6631- ->getNominalOrBoundGenericNominal ())
6632- tc.diagnose (ND, diag::archetype_declared_in_type, archetype,
6633- ND->getDeclaredType ());
6702+ noteArchetypeSource (ECE->getCastTypeLoc (), archetype, *CS);
66346703 return ;
66356704 }
66366705
@@ -6660,7 +6729,7 @@ void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
66606729
66616730 if (auto TE = dyn_cast<TypeExpr>(anchor)) {
66626731 // Emit a note specifying where this came from, if we can find it.
6663- noteArchetypeSource (TE->getTypeLoc (), archetype, tc );
6732+ noteArchetypeSource (TE->getTypeLoc (), archetype, *CS );
66646733 return ;
66656734 }
66666735
0 commit comments