@@ -1640,13 +1640,16 @@ ConformanceAccessScope ConformanceAccessScopeRequest::evaluate(
16401640 return std::make_pair (result, witnessesMustBeUsableFromInline);
16411641}
16421642
1643- bool WitnessChecker::checkWitnessAccess (ValueDecl *requirement,
1644- ValueDecl *witness,
1645- bool *isSetter) {
1643+ static bool checkWitnessAccess (DeclContext *dc,
1644+ ValueDecl *requirement,
1645+ ValueDecl *witness,
1646+ bool *isSetter) {
16461647 *isSetter = false ;
16471648
1649+ auto *proto = cast<ProtocolDecl>(requirement->getDeclContext ());
1650+
16481651 auto requiredAccessScope = evaluateOrDefault (
1649- Context .evaluator , ConformanceAccessScopeRequest{DC, Proto },
1652+ dc-> getASTContext () .evaluator , ConformanceAccessScopeRequest{dc, proto },
16501653 std::make_pair (AccessScope::getPublic (), false ));
16511654
16521655 auto actualScopeToCheck = requiredAccessScope.first ;
@@ -1662,7 +1665,7 @@ bool WitnessChecker::checkWitnessAccess(ValueDecl *requirement,
16621665 // allow us to see it anywhere, because any other client could also add
16631666 // their own `@testable import`.
16641667 // Same with @_private(sourceFile:) import.
1665- if (auto parentFile = dyn_cast<SourceFile>(DC-> getModuleScopeContext () )) {
1668+ if (auto parentFile = dc-> getParentSourceFile ( )) {
16661669 const ModuleDecl *witnessModule = witness->getModuleContext ();
16671670 if (parentFile->getParentModule () != witnessModule &&
16681671 parentFile->hasTestableOrPrivateImport (witness->getFormalAccess (),
@@ -1677,7 +1680,7 @@ bool WitnessChecker::checkWitnessAccess(ValueDecl *requirement,
16771680 }
16781681
16791682 if (auto *requirementASD = dyn_cast<AbstractStorageDecl>(requirement)) {
1680- if (requirementASD->isSettable (DC )) {
1683+ if (requirementASD->isSettable (dc )) {
16811684 *isSetter = true ;
16821685
16831686 auto witnessASD = cast<AbstractStorageDecl>(witness);
@@ -1711,7 +1714,7 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
17111714 std::make_pair (AccessScope::getPublic (), false ));
17121715
17131716 bool isSetter = false ;
1714- if (checkWitnessAccess (requirement, match.Witness , &isSetter)) {
1717+ if (checkWitnessAccess (DC, requirement, match.Witness , &isSetter)) {
17151718 CheckKind kind = (isSetter
17161719 ? CheckKind::AccessOfSetter
17171720 : CheckKind::Access);
@@ -3303,18 +3306,21 @@ ConformanceChecker::checkActorIsolation(ValueDecl *requirement,
33033306 return llvm::None;
33043307}
33053308
3306- bool ConformanceChecker::checkObjCTypeErasedGenerics (
3307- AssociatedTypeDecl *assocType,
3308- Type type,
3309- TypeDecl *typeDecl) {
3309+ // / Check for ill-formed uses of Objective-C generics in a type witness.
3310+ static bool checkObjCTypeErasedGenerics (NormalProtocolConformance *conformance,
3311+ AssociatedTypeDecl *assocType,
3312+ Type type, TypeDecl *typeDecl) {
3313+ auto *dc = conformance->getDeclContext ();
3314+ auto *proto = conformance->getProtocol ();
3315+
33103316 // Objective-C's type-erased generics don't allow the type arguments
33113317 // to be extracted from an instance (or a metatype), so we cannot refer to
33123318 // the type parameters from an associated type. Check that here.
3313- auto &ctx = assocType ->getASTContext ();
3319+ auto &ctx = dc ->getASTContext ();
33143320 if (!ctx.LangOpts .EnableObjCInterop && type->hasError ())
33153321 return false ;
33163322
3317- auto classDecl = DC ->getSelfClassDecl ();
3323+ auto classDecl = dc ->getSelfClassDecl ();
33183324 if (!classDecl) return false ;
33193325
33203326 if (!classDecl->isTypeErasedGenericClass ()) return false ;
@@ -3335,10 +3341,10 @@ bool ConformanceChecker::checkObjCTypeErasedGenerics(
33353341 });
33363342
33373343 // Diagnose the problem.
3338- SourceLoc diagLoc = getLocForDiagnosingWitness (Conformance , typeDecl);
3344+ SourceLoc diagLoc = getLocForDiagnosingWitness (conformance , typeDecl);
33393345 ctx.Diags .diagnose (diagLoc, diag::type_witness_objc_generic_parameter,
33403346 type, genericParam, !genericParam.isNull (), assocType,
3341- Proto );
3347+ proto );
33423348 emitDeclaredHereIfNeeded (ctx.Diags , diagLoc, typeDecl);
33433349
33443350 return true ;
@@ -4667,14 +4673,19 @@ static void diagnoseInvariantSelfRequirement(
46674673 .warnUntilSwiftVersion (6 );
46684674}
46694675
4670- void ConformanceChecker::ensureRequirementsAreSatisfied () {
4671- auto proto = Conformance->getProtocol ();
4672- auto &diags = proto->getASTContext ().Diags ;
4676+ // / Check whether the type witnesses satisfy the protocol's requirement
4677+ // / signature. Also checks access level of type witnesses and availiability
4678+ // / of associated conformances.
4679+ static void ensureRequirementsAreSatisfied (ASTContext &ctx,
4680+ NormalProtocolConformance *conformance) {
4681+ auto *dc = conformance->getDeclContext ();
4682+ auto proto = conformance->getProtocol ();
4683+ auto &diags = ctx.Diags ;
46734684
4674- auto *const module = DC ->getParentModule ();
4675- auto substitutingType = DC ->mapTypeIntoContext (Conformance ->getType ());
4685+ auto *const module = dc ->getParentModule ();
4686+ auto substitutingType = dc ->mapTypeIntoContext (conformance ->getType ());
46764687 auto substitutions = SubstitutionMap::getProtocolSubstitutions (
4677- proto, substitutingType, ProtocolConformanceRef (Conformance ));
4688+ proto, substitutingType, ProtocolConformanceRef (conformance ));
46784689
46794690 auto reqSig = proto->getRequirementSignature ().getRequirements ();
46804691
@@ -4684,10 +4695,12 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
46844695 // an error, we can handle it as part of the above checkGenericArguments()
46854696 // call by passing in a superclass-bound archetype for the 'self' type
46864697 // instead of the concrete class type itself.
4687- if (auto *classDecl = DC ->getSelfClassDecl ()) {
4698+ if (auto *classDecl = dc ->getSelfClassDecl ()) {
46884699 if (!classDecl->isSemanticallyFinal ()) {
46894700 if (auto req = hasInvariantSelfRequirement (proto, reqSig)) {
4690- diagnoseInvariantSelfRequirement (Loc, Adoptee, proto, *req, diags);
4701+ diagnoseInvariantSelfRequirement (conformance->getLoc (),
4702+ dc->getSelfInterfaceType (),
4703+ proto, *req, diags);
46914704 }
46924705 }
46934706 }
@@ -4703,60 +4716,57 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
47034716 case CheckRequirementsResult::SubstitutionFailure:
47044717 // Diagnose the failure generically.
47054718 // FIXME: Would be nice to give some more context here!
4706- if (!Conformance ->isInvalid ()) {
4719+ if (!conformance ->isInvalid ()) {
47074720 if (result.getKind () == CheckRequirementsResult::RequirementFailure) {
4708- auto Loc = this ->Loc ;
4709- getASTContext ().addDelayedConformanceDiag (Conformance, /* isError=*/ true ,
4710- [Loc, result, proto, substitutions, module ](NormalProtocolConformance *conformance) {
4721+ ctx.addDelayedConformanceDiag (conformance, /* isError=*/ true ,
4722+ [result, proto, substitutions, module ](NormalProtocolConformance *conformance) {
47114723 TypeChecker::diagnoseRequirementFailure (
4712- result.getRequirementFailureInfo (), Loc, Loc,
4724+ result.getRequirementFailureInfo (),
4725+ conformance->getLoc (), conformance->getLoc (),
47134726 proto->getDeclaredInterfaceType (),
47144727 {proto->getSelfInterfaceType ()->castTo <GenericTypeParamType>()},
47154728 QuerySubstitutionMap{substitutions}, module );
47164729 });
47174730 }
47184731
4719- Conformance ->setInvalid ();
4732+ conformance ->setInvalid ();
47204733 }
47214734 return ;
47224735 }
47234736
47244737 // Now check that our associated conformances are at least as visible as
47254738 // the conformance itself.
4726- auto where = ExportContext::forConformance (DC , proto);
4739+ auto where = ExportContext::forConformance (dc , proto);
47274740 if (where.isImplicit ())
47284741 return ;
47294742
4730- Conformance ->forEachTypeWitness ([&](AssociatedTypeDecl *assocType,
4743+ conformance ->forEachTypeWitness ([&](AssociatedTypeDecl *assocType,
47314744 Type type, TypeDecl *typeDecl) -> bool {
4732- checkObjCTypeErasedGenerics (assocType, type, typeDecl);
4745+ checkObjCTypeErasedGenerics (conformance, assocType, type, typeDecl);
47334746
47344747 if (typeDecl && !typeDecl->isImplicit ()) {
47354748 auto requiredAccessScope = evaluateOrDefault (
4736- Context .evaluator , ConformanceAccessScopeRequest{DC, Proto },
4749+ ctx .evaluator , ConformanceAccessScopeRequest{dc, proto },
47374750 std::make_pair (AccessScope::getPublic (), false ));
47384751
47394752 // Check access.
47404753 bool isSetter = false ;
4741- if (checkWitnessAccess (assocType, typeDecl, &isSetter)) {
4754+ if (checkWitnessAccess (dc, assocType, typeDecl, &isSetter)) {
47424755 assert (!isSetter);
47434756
4744- // Note: you must not capture 'this' in the below closure.
4745- auto *DC = this ->DC ;
4746-
4747- getASTContext ().addDelayedConformanceDiag (Conformance, false ,
4748- [DC, requiredAccessScope, typeDecl](
4757+ ctx.addDelayedConformanceDiag (conformance, false ,
4758+ [dc, requiredAccessScope, typeDecl](
47494759 NormalProtocolConformance *conformance) {
47504760 AccessLevel requiredAccess =
47514761 requiredAccessScope.first .requiredAccessForDiagnostics ();
47524762 auto proto = conformance->getProtocol ();
4753- auto protoAccessScope = proto->getFormalAccessScope (DC );
4763+ auto protoAccessScope = proto->getFormalAccessScope (dc );
47544764 bool protoForcesAccess =
47554765 requiredAccessScope.first .hasEqualDeclContextWith (protoAccessScope);
47564766 auto diagKind = protoForcesAccess
47574767 ? diag::type_witness_not_accessible_proto
47584768 : diag::type_witness_not_accessible_type;
4759- auto &diags = DC ->getASTContext ().Diags ;
4769+ auto &diags = dc ->getASTContext ().Diags ;
47604770 diags.diagnose (getLocForDiagnosingWitness (conformance, typeDecl),
47614771 diagKind, typeDecl, requiredAccess, proto);
47624772 diagnoseWitnessFixAccessLevel (diags, typeDecl, requiredAccess);
@@ -4765,10 +4775,10 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
47654775
47664776 if (requiredAccessScope.second ) {
47674777 bool witnessIsUsableFromInline = typeDecl->getFormalAccessScope (
4768- DC , /* usableFromInlineAsPublic*/ true ).isPublic ();
4778+ dc , /* usableFromInlineAsPublic*/ true ).isPublic ();
47694779 if (!witnessIsUsableFromInline)
4770- getASTContext () .addDelayedConformanceDiag (Conformance , false ,
4771- DiagnoseUsableFromInline (typeDecl));
4780+ ctx .addDelayedConformanceDiag (conformance , false ,
4781+ DiagnoseUsableFromInline (typeDecl));
47724782 }
47734783 }
47744784
@@ -4781,14 +4791,14 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
47814791 return false ;
47824792 });
47834793
4784- Conformance ->forEachAssociatedConformance (
4794+ conformance ->forEachAssociatedConformance (
47854795 [&](Type depTy, ProtocolDecl *proto, unsigned index) {
4786- auto conformance = Conformance ->getAssociatedConformance (depTy, proto);
4787- if (conformance .isConcrete ()) {
4788- auto *concrete = conformance .getConcrete ();
4789- auto replacementTy = DC ->mapTypeIntoContext (concrete->getType ());
4790- diagnoseConformanceAvailability (Conformance ->getLoc (),
4791- conformance , where,
4796+ auto assocConf = conformance ->getAssociatedConformance (depTy, proto);
4797+ if (assocConf .isConcrete ()) {
4798+ auto *concrete = assocConf .getConcrete ();
4799+ auto replacementTy = dc ->mapTypeIntoContext (concrete->getType ());
4800+ diagnoseConformanceAvailability (conformance ->getLoc (),
4801+ assocConf , where,
47924802 depTy, replacementTy);
47934803 }
47944804
@@ -5057,7 +5067,7 @@ void ConformanceChecker::checkConformance() {
50575067 evaluator::SideEffect ());
50585068
50595069 // Check the requirements from the requirement signature.
5060- ensureRequirementsAreSatisfied ();
5070+ ensureRequirementsAreSatisfied (getASTContext (), Conformance );
50615071
50625072 // Check non-type requirements.
50635073 resolveValueWitnesses ();
0 commit comments