@@ -6488,39 +6488,112 @@ void ConstraintSystem::diagnoseFailureForExpr(Expr *expr) {
64886488 diagnosis.diagnoseAmbiguity (expr);
64896489}
64906490
6491+ static bool hasArchetype (const GenericTypeDecl *generic,
6492+ const ArchetypeType *archetype) {
6493+ return std::any_of (generic->getInnermostGenericParamTypes ().begin (),
6494+ generic->getInnermostGenericParamTypes ().end (),
6495+ [archetype](const GenericTypeParamType *genericParamTy) {
6496+ return genericParamTy->getDecl ()->getArchetype () == archetype;
6497+ });
6498+ }
6499+
64916500static void noteArchetypeSource (const TypeLoc &loc, ArchetypeType *archetype,
6492- TypeChecker &tc) {
6493- GenericTypeDecl *FoundDecl = nullptr ;
6494-
6501+ ConstraintSystem &cs) {
6502+ const GenericTypeDecl *FoundDecl = nullptr ;
6503+ const ComponentIdentTypeRepr *FoundGenericTypeBase = nullptr ;
6504+
64956505 // Walk the TypeRepr to find the type in question.
64966506 if (auto typerepr = loc.getTypeRepr ()) {
64976507 struct FindGenericTypeDecl : public ASTWalker {
6498- GenericTypeDecl *&FoundDecl;
6499- FindGenericTypeDecl (GenericTypeDecl *&FoundDecl) : FoundDecl(FoundDecl) {
6500- }
6508+ const GenericTypeDecl *FoundDecl = nullptr ;
6509+ const ComponentIdentTypeRepr *FoundGenericTypeBase = nullptr ;
6510+ const ArchetypeType *Archetype;
6511+
6512+ FindGenericTypeDecl (const ArchetypeType *Archetype)
6513+ : Archetype(Archetype) {}
65016514
65026515 bool walkToTypeReprPre (TypeRepr *T) override {
65036516 // If we already emitted the note, we're done.
65046517 if (FoundDecl) return false ;
65056518
6506- if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T))
6507- FoundDecl = dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl ());
6519+ if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
6520+ auto *generic =
6521+ dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl ());
6522+ if (hasArchetype (generic, Archetype)) {
6523+ FoundDecl = generic;
6524+ FoundGenericTypeBase = ident;
6525+ return false ;
6526+ }
6527+ }
65086528 // Keep walking.
65096529 return true ;
65106530 }
6511- } findGenericTypeDecl (FoundDecl );
6512-
6531+ } findGenericTypeDecl (archetype );
6532+
65136533 typerepr->walk (findGenericTypeDecl);
6534+ FoundDecl = findGenericTypeDecl.FoundDecl ;
6535+ FoundGenericTypeBase = findGenericTypeDecl.FoundGenericTypeBase ;
65146536 }
6515-
6537+
65166538 // If we didn't find the type in the TypeRepr, fall back to the type in the
65176539 // type checked expression.
6518- if (!FoundDecl)
6519- FoundDecl = loc.getType ()->getAnyGeneric ();
6520-
6521- if (FoundDecl)
6522- tc.diagnose (FoundDecl, diag::archetype_declared_in_type, archetype,
6523- FoundDecl->getDeclaredType ());
6540+ if (!FoundDecl) {
6541+ if (const GenericTypeDecl *generic = loc.getType ()->getAnyGeneric ())
6542+ if (hasArchetype (generic, archetype))
6543+ FoundDecl = generic;
6544+ }
6545+
6546+ auto &tc = cs.getTypeChecker ();
6547+ if (FoundDecl) {
6548+ tc.diagnose (FoundDecl, diag::archetype_declared_in_type,
6549+ archetype, FoundDecl->getDeclaredType ());
6550+ }
6551+
6552+ if (FoundGenericTypeBase && !isa<GenericIdentTypeRepr>(FoundGenericTypeBase)){
6553+ assert (FoundDecl);
6554+
6555+ // If we can, prefer using any types already fixed by the constraint system.
6556+ // This lets us produce fixes like `Pair<Int, Any>` instead of defaulting to
6557+ // `Pair<Any, Any>`.
6558+ // Right now we only handle this when the type that's at fault is the
6559+ // top-level type passed to this function.
6560+ ArrayRef<Type> genericArgs;
6561+ if (auto *boundGenericTy = loc.getType ()->getAs <BoundGenericType>()) {
6562+ if (boundGenericTy->getDecl () == FoundDecl)
6563+ genericArgs = boundGenericTy->getGenericArgs ();
6564+ }
6565+
6566+ auto getPreferredType =
6567+ [&](const GenericTypeParamDecl *genericParam) -> Type {
6568+ // If we were able to get the generic arguments (i.e. the types used at
6569+ // FoundDecl's use site), we can prefer those...
6570+ if (genericArgs.empty ())
6571+ return Type ();
6572+
6573+ Type preferred = genericArgs[genericParam->getIndex ()];
6574+ if (!preferred || preferred->is <ErrorType>())
6575+ return Type ();
6576+
6577+ // ...but only if they were actually resolved by the constraint system
6578+ // despite the failure.
6579+ TypeVariableType *unused;
6580+ Type maybeFixedType = cs.getFixedTypeRecursive (preferred, unused,
6581+ /* wantRValue*/ true );
6582+ if (maybeFixedType->hasTypeVariable () ||
6583+ maybeFixedType->hasUnresolvedType ()) {
6584+ return Type ();
6585+ }
6586+ return maybeFixedType;
6587+ };
6588+
6589+ SmallString<64 > genericParamBuf;
6590+ if (tc.getDefaultGenericArgumentsString (genericParamBuf, FoundDecl,
6591+ getPreferredType)) {
6592+ tc.diagnose (FoundGenericTypeBase->getLoc (),
6593+ diag::unbound_generic_parameter_explicit_fix)
6594+ .fixItInsertAfter (FoundGenericTypeBase->getEndLoc (), genericParamBuf);
6595+ }
6596+ }
65246597}
65256598
65266599
@@ -6636,11 +6709,7 @@ void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
66366709 .highlight (ECE->getCastTypeLoc ().getSourceRange ());
66376710
66386711 // Emit a note specifying where this came from, if we can find it.
6639- noteArchetypeSource (ECE->getCastTypeLoc (), archetype, tc);
6640- if (auto *ND = ECE->getCastTypeLoc ().getType ()
6641- ->getNominalOrBoundGenericNominal ())
6642- tc.diagnose (ND, diag::archetype_declared_in_type, archetype,
6643- ND->getDeclaredType ());
6712+ noteArchetypeSource (ECE->getCastTypeLoc (), archetype, *CS);
66446713 return ;
66456714 }
66466715
@@ -6670,7 +6739,7 @@ void FailureDiagnosis::diagnoseUnboundArchetype(ArchetypeType *archetype,
66706739
66716740 if (auto TE = dyn_cast<TypeExpr>(anchor)) {
66726741 // Emit a note specifying where this came from, if we can find it.
6673- noteArchetypeSource (TE->getTypeLoc (), archetype, tc );
6742+ noteArchetypeSource (TE->getTypeLoc (), archetype, *CS );
66746743 return ;
66756744 }
66766745
0 commit comments