@@ -2092,7 +2092,7 @@ static Type getRequirementTypeForDisplay(ModuleDecl *module,
20922092 return FunctionType::get (params, result, fnTy->getExtInfo ());
20932093 }
20942094
2095- return substType (type, /* result*/ false );
2095+ return substType (type, /* result*/ true );
20962096}
20972097
20982098diag::RequirementKind
@@ -3361,41 +3361,36 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
33613361 emitDeclaredHereIfNeeded (diags, diagLoc, witness);
33623362 });
33633363 } else if (selfKind.result ) {
3364- // The reference to Self occurs in the result type. A non-final class
3365- // can satisfy this requirement with a method that returns Self.
3364+ // The reference to Self occurs in the result type of a method/subscript
3365+ // or the type of a property. A non-final class can satisfy this requirement
3366+ // by holding onto Self accordingly.
3367+ if (witness->getDeclContext ()->getSelfClassDecl ()) {
3368+ const bool hasDynamicSelfResult = [&] {
3369+ if (auto func = dyn_cast<AbstractFunctionDecl>(witness)) {
3370+ return func->hasDynamicSelfResult ();
3371+ } else if (auto var = dyn_cast<VarDecl>(witness)) {
3372+ return var->getInterfaceType ()->hasDynamicSelfType ();
3373+ }
33663374
3367- // If the function has a dynamic Self, it's okay.
3368- if (auto func = dyn_cast<FuncDecl>(witness)) {
3369- if (func->getDeclContext ()->getSelfClassDecl () &&
3370- !func->hasDynamicSelfResult ()) {
3375+ return cast<SubscriptDecl>(witness)
3376+ ->getElementInterfaceType ()
3377+ ->hasDynamicSelfType ();
3378+ }();
3379+
3380+ if (!hasDynamicSelfResult) {
33713381 diagnoseOrDefer (requirement, false ,
33723382 [witness, requirement](NormalProtocolConformance *conformance) {
33733383 auto proto = conformance->getProtocol ();
33743384 auto &diags = proto->getASTContext ().Diags ;
33753385 SourceLoc diagLoc = getLocForDiagnosingWitness (conformance,witness);
3376- diags.diagnose (diagLoc,
3377- diag::witness_requires_dynamic_self ,
3386+ diags.diagnose (diagLoc, diag::witness_requires_dynamic_self,
3387+ getProtocolRequirementKind (requirement) ,
33783388 requirement->getName (),
33793389 conformance->getType (),
33803390 proto->getDeclaredInterfaceType ());
33813391 emitDeclaredHereIfNeeded (diags, diagLoc, witness);
33823392 });
33833393 }
3384-
3385- // Constructors conceptually also have a dynamic Self
3386- // return type, so they're okay.
3387- } else if (!isa<ConstructorDecl>(witness)) {
3388- diagnoseOrDefer (requirement, false ,
3389- [witness, requirement](NormalProtocolConformance *conformance) {
3390- auto proto = conformance->getProtocol ();
3391- auto &diags = proto->getASTContext ().Diags ;
3392- SourceLoc diagLoc = getLocForDiagnosingWitness (conformance, witness);
3393- diags.diagnose (diagLoc, diag::witness_self_non_subtype,
3394- proto->getDeclaredInterfaceType (),
3395- requirement->getName (),
3396- conformance->getType ());
3397- emitDeclaredHereIfNeeded (diags, diagLoc, witness);
3398- });
33993394 }
34003395 } else if (selfKind.requirement ) {
34013396 if (auto targetPair = getAdopteeSelfSameTypeConstraint (classDecl,
@@ -3431,8 +3426,8 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
34313426 // constraint that either the requirement not produce 'Self' in a
34323427 // covariant position, or the type of the requirement does not involve
34333428 // associated types.
3434- if (auto func = dyn_cast<FuncDecl >(witness)) {
3435- if (func ->getDeclContext ()->getExtendedProtocolDecl ()) {
3429+ if (isa<FuncDecl>(witness) || isa<SubscriptDecl >(witness)) {
3430+ if (witness ->getDeclContext ()->getExtendedProtocolDecl ()) {
34363431 auto selfKindWithAssocTypes = Proto->findProtocolSelfReferences (
34373432 requirement,
34383433 /* allowCovariantParameters=*/ false ,
@@ -3445,6 +3440,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
34453440 auto &diags = proto->getASTContext ().Diags ;
34463441 diags.diagnose (conformance->getLoc (),
34473442 diag::witness_requires_class_implementation,
3443+ getProtocolRequirementKind (requirement),
34483444 requirement->getName (),
34493445 conformance->getType ());
34503446 diags.diagnose (witness, diag::decl_declared_here,
0 commit comments