@@ -512,8 +512,7 @@ checkEffects(AbstractStorageDecl *witness, AbstractStorageDecl *req) {
512512// / to be used by `matchWitness`.
513513static std::optional<RequirementMatch>
514514matchWitnessStructureImpl (ValueDecl *req, ValueDecl *witness,
515- bool &decomposeFunctionType, bool &ignoreReturnType,
516- Type &reqThrownError, Type &witnessThrownError) {
515+ bool &decomposeFunctionType, bool &ignoreReturnType) {
517516 assert (!req->isInvalid () && " Cannot have an invalid requirement here" );
518517
519518 // / Make sure the witness is of the same kind as the requirement.
@@ -658,23 +657,6 @@ matchWitnessStructureImpl(ValueDecl *req, ValueDecl *witness,
658657
659658 // Decompose the parameters for subscript declarations.
660659 decomposeFunctionType = isa<SubscriptDecl>(req);
661-
662- // Dig out the thrown error types from the getter so we can compare them
663- // later.
664- auto getThrownErrorType = [](AbstractStorageDecl *asd) -> Type {
665- if (auto getter = asd->getEffectfulGetAccessor ()) {
666- if (Type thrownErrorType = getter->getThrownInterfaceType ()) {
667- return thrownErrorType;
668- } else if (getter->hasThrows ()) {
669- return asd->getASTContext ().getAnyExistentialType ();
670- }
671- }
672-
673- return asd->getASTContext ().getNeverType ();
674- };
675-
676- reqThrownError = getThrownErrorType (reqASD);
677- witnessThrownError = getThrownErrorType (witnessASD);
678660 } else if (isa<ConstructorDecl>(witness)) {
679661 decomposeFunctionType = true ;
680662 ignoreReturnType = true ;
@@ -713,39 +695,33 @@ bool swift::TypeChecker::witnessStructureMatches(ValueDecl *req,
713695 const ValueDecl *witness) {
714696 bool decomposeFunctionType = false ;
715697 bool ignoreReturnType = false ;
716- Type reqThrownError;
717- Type witnessThrownError;
718698 return matchWitnessStructureImpl (req, const_cast <ValueDecl *>(witness),
719- decomposeFunctionType, ignoreReturnType,
720- reqThrownError,
721- witnessThrownError) == std::nullopt ;
699+ decomposeFunctionType, ignoreReturnType)
700+ == std::nullopt ;
722701}
723702
724703RequirementMatch swift::matchWitness (
725704 DeclContext *dc, ValueDecl *req, ValueDecl *witness,
726705 llvm::function_ref<
727- std::tuple<std::optional<RequirementMatch>, Type, Type>(void )>
706+ std::tuple<std::optional<RequirementMatch>, Type, Type, Type, Type >(void )>
728707 setup,
729708 llvm::function_ref<std::optional<RequirementMatch>(Type, Type)> matchTypes,
730709 llvm::function_ref<RequirementMatch(bool , ArrayRef<OptionalAdjustment>)>
731710 finalize) {
732711 bool decomposeFunctionType = false ;
733712 bool ignoreReturnType = false ;
734- Type reqThrownError;
735- Type witnessThrownError;
736713
737714 if (auto StructuralMismatch = matchWitnessStructureImpl (
738- req, witness, decomposeFunctionType, ignoreReturnType, reqThrownError,
739- witnessThrownError)) {
715+ req, witness, decomposeFunctionType, ignoreReturnType)) {
740716 return *StructuralMismatch;
741717 }
742718
743719 // Set up the match, determining the requirement and witness types
744720 // in the process.
745- Type reqType, witnessType;
721+ Type reqType, witnessType, reqThrownError, witnessThrownError ;
746722 {
747723 std::optional<RequirementMatch> result;
748- std::tie (result, reqType, witnessType) = setup ();
724+ std::tie (result, reqType, witnessType, reqThrownError, witnessThrownError ) = setup ();
749725 if (result) {
750726 return std::move (result.value ());
751727 }
@@ -936,7 +912,8 @@ RequirementMatch swift::matchWitness(
936912
937913 case ThrownErrorSubtyping::Subtype:
938914 // If there were no type parameters, we're done.
939- if (!reqThrownError->hasTypeParameter ())
915+ if (!reqThrownError->hasTypeVariable () &&
916+ !reqThrownError->hasTypeParameter ())
940917 break ;
941918
942919 LLVM_FALLTHROUGH;
@@ -1186,7 +1163,7 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
11861163
11871164 // Set up the constraint system for matching.
11881165 auto setup =
1189- [&]() -> std::tuple<std::optional<RequirementMatch>, Type, Type> {
1166+ [&]() -> std::tuple<std::optional<RequirementMatch>, Type, Type, Type, Type > {
11901167 // Construct a constraint system to use to solve the equality between
11911168 // the required type and the witness type.
11921169 cs.emplace (dc, ConstraintSystemFlags::AllowFixes);
@@ -1199,10 +1176,12 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
11991176 if (syntheticEnv)
12001177 selfTy = syntheticEnv->mapTypeIntoContext (selfTy);
12011178
1179+
12021180 // Open up the type of the requirement.
1181+ SmallVector<OpenedType, 4 > reqReplacements;
1182+
12031183 reqLocator =
12041184 cs->getConstraintLocator (req, ConstraintLocator::ProtocolRequirement);
1205- SmallVector<OpenedType, 4 > reqReplacements;
12061185 reqType =
12071186 cs->getTypeOfMemberReference (selfTy, req, dc,
12081187 /* isDynamicResult=*/ false ,
@@ -1235,14 +1214,17 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
12351214 }
12361215
12371216 // Open up the witness type.
1217+ SmallVector<OpenedType, 4 > witnessReplacements;
1218+
12381219 witnessType = witness->getInterfaceType ();
12391220 witnessLocator =
12401221 cs->getConstraintLocator (req, LocatorPathElt::Witness (witness));
12411222 if (witness->getDeclContext ()->isTypeContext ()) {
12421223 openWitnessType =
1243- cs->getTypeOfMemberReference (
1244- selfTy, witness, dc, /* isDynamicResult=*/ false ,
1245- FunctionRefInfo::doubleBaseNameApply (), witnessLocator)
1224+ cs->getTypeOfMemberReference (selfTy, witness, dc,
1225+ /* isDynamicResult=*/ false ,
1226+ FunctionRefInfo::doubleBaseNameApply (),
1227+ witnessLocator, &witnessReplacements)
12461228 .adjustedReferenceType ;
12471229 } else {
12481230 openWitnessType =
@@ -1253,7 +1235,37 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
12531235 }
12541236 openWitnessType = openWitnessType->getRValueType ();
12551237
1256- return std::make_tuple (std::nullopt , reqType, openWitnessType);
1238+ Type reqThrownError;
1239+ Type witnessThrownError;
1240+
1241+ if (auto *witnessASD = dyn_cast<AbstractStorageDecl>(witness)) {
1242+ auto *reqASD = cast<AbstractStorageDecl>(req);
1243+
1244+ // Dig out the thrown error types from the getter so we can compare them
1245+ // later.
1246+ auto getThrownErrorType = [](AbstractStorageDecl *asd) -> Type {
1247+ if (auto getter = asd->getEffectfulGetAccessor ()) {
1248+ if (Type thrownErrorType = getter->getThrownInterfaceType ()) {
1249+ return thrownErrorType;
1250+ } else if (getter->hasThrows ()) {
1251+ return asd->getASTContext ().getErrorExistentialType ();
1252+ }
1253+ }
1254+
1255+ return asd->getASTContext ().getNeverType ();
1256+ };
1257+
1258+ reqThrownError = getThrownErrorType (reqASD);
1259+ reqThrownError = cs->openType (reqThrownError, reqReplacements,
1260+ reqLocator);
1261+
1262+ witnessThrownError = getThrownErrorType (witnessASD);
1263+ witnessThrownError = cs->openType (witnessThrownError, witnessReplacements,
1264+ witnessLocator);
1265+ }
1266+
1267+ return std::make_tuple (std::nullopt , reqType, openWitnessType,
1268+ reqThrownError, witnessThrownError);
12571269 };
12581270
12591271 // Match a type in the requirement to a type in the witness.
0 commit comments