@@ -1000,50 +1000,64 @@ findMissingGenericRequirementForSolutionFix(
10001000 type = solution.simplifyType (type);
10011001 missingType = solution.simplifyType (missingType);
10021002
1003- if (auto *env = conformance->getGenericEnvironment ()) {
1004- // We use subst() with LookUpConformanceInModule here, because
1005- // associated type inference failures mean that we can end up
1006- // here with a DependentMemberType with an ArchetypeType base.
1007- missingType = missingType.subst (
1008- [&](SubstitutableType *type) -> Type {
1009- return env->mapTypeIntoContext (type->mapTypeOutOfContext ());
1010- },
1011- LookUpConformanceInModule (),
1012- SubstFlags::SubstitutePrimaryArchetypes);
1013- }
1014-
10151003 auto missingRequirementMatch = [&](Type type) -> RequirementMatch {
10161004 Requirement requirement (requirementKind, type, missingType);
10171005 return RequirementMatch (witness, MatchKind::MissingRequirement,
10181006 requirement);
10191007 };
10201008
1021- if (type-> is <DependentMemberType>() )
1022- return missingRequirementMatch (type );
1009+ auto selfTy = conformance-> getProtocol ()-> getSelfInterfaceType ( )
1010+ . subst (reqEnvironment. getRequirementToWitnessThunkSubs () );
10231011
1024- type = type->mapTypeOutOfContext ();
1025- if (type->hasTypeParameter ())
1026- if (auto env = conformance->getGenericEnvironment ())
1027- if (auto assocType = env->mapTypeIntoContext (type))
1028- return missingRequirementMatch (assocType);
1012+ auto sig = conformance->getGenericSignature ();
1013+ auto *env = conformance->getGenericEnvironment ();
10291014
1030- auto reqSubMap = reqEnvironment.getRequirementToWitnessThunkSubs ();
1031- auto proto = conformance->getProtocol ();
1032- Type selfTy = proto->getSelfInterfaceType ().subst (reqSubMap);
1033- if (type->isEqual (selfTy)) {
1034- type = conformance->getType ();
1015+ auto &ctx = conformance->getDeclContext ()->getASTContext ();
10351016
1017+ if (type->is <ArchetypeType>() &&
1018+ type->mapTypeOutOfContext ()->isEqual (selfTy) &&
1019+ missingType->isEqual (conformance->getType ())) {
10361020 // e.g. `extension P where Self == C { func foo() { ... } }`
10371021 // and `C` doesn't actually conform to `P`.
1038- if (type->isEqual (missingType)) {
1039- requirementKind = RequirementKind::Conformance;
1040- missingType = proto->getDeclaredInterfaceType ();
1041- }
1022+ requirementKind = RequirementKind::Conformance;
1023+ missingType = conformance->getProtocol ()->getDeclaredInterfaceType ();
1024+ }
1025+
1026+ // Map the interface types of the witness thunk signature back to
1027+ // sugared generic parameter types of the conformance, for printing.
1028+ auto getTypeInConformanceContext = [&](Type type) -> Type {
1029+ return type.subst ([&](SubstitutableType *t) -> Type {
1030+ auto *gp = cast<GenericTypeParamType>(t);
1031+ if (selfTy->is <GenericTypeParamType>()) {
1032+ if (gp->isEqual (selfTy))
1033+ return conformance->getType ();
1034+
1035+ ASSERT (gp->getDepth () > 0 );
1036+ gp = GenericTypeParamType::get (gp->getParamKind (),
1037+ gp->getDepth () - 1 ,
1038+ gp->getIndex (),
1039+ gp->getValueType (),
1040+ ctx);
1041+ }
1042+
1043+ if (!sig)
1044+ return ErrorType::get (ctx);
10421045
1043- if (auto agt = type->getAs <AnyGenericType>())
1044- type = agt->getDecl ()->getDeclaredInterfaceType ();
1046+ auto params = sig.getGenericParams ();
1047+ unsigned ordinal = sig->getGenericParamOrdinal (gp);
1048+ if (ordinal == params.size ())
1049+ return ErrorType::get (ctx);
1050+
1051+ return env->mapTypeIntoContext (gp);
1052+ },
1053+ LookUpConformanceInModule ());
1054+ };
1055+
1056+ type = getTypeInConformanceContext (type);
1057+ missingType = getTypeInConformanceContext (missingType);
1058+
1059+ if (!type->hasError () && !missingType->hasError ())
10451060 return missingRequirementMatch (type);
1046- }
10471061
10481062 return std::optional<RequirementMatch>();
10491063}
0 commit comments