@@ -3442,45 +3442,8 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
34423442
34433443 assert (!type->hasArchetype () && " Got a contextual type here?" );
34443444
3445- checkObjCTypeErasedGenerics (assocType, type, typeDecl);
3446-
3447- if (typeDecl) {
3448- // Check access.
3449- bool isSetter = false ;
3450- if (checkWitnessAccess (assocType, typeDecl, &isSetter)) {
3451- assert (!isSetter);
3452-
3453- // Note: you must not capture 'this' in the below closure.
3454- const DeclContext *DC = this ->DC ;
3455- auto requiredAccessScope = getRequiredAccessScope ();
3456-
3457- diagnoseOrDefer (assocType, false ,
3458- [DC, requiredAccessScope, typeDecl](
3459- NormalProtocolConformance *conformance) {
3460- AccessLevel requiredAccess =
3461- requiredAccessScope.requiredAccessForDiagnostics ();
3462- auto proto = conformance->getProtocol ();
3463- auto protoAccessScope = proto->getFormalAccessScope (DC);
3464- bool protoForcesAccess =
3465- requiredAccessScope.hasEqualDeclContextWith (protoAccessScope);
3466- auto diagKind = protoForcesAccess
3467- ? diag::type_witness_not_accessible_proto
3468- : diag::type_witness_not_accessible_type;
3469- auto &diags = DC->getASTContext ().Diags ;
3470- diags.diagnose (getLocForDiagnosingWitness (conformance, typeDecl),
3471- diagKind, typeDecl, requiredAccess, proto);
3472- diagnoseWitnessFixAccessLevel (diags, typeDecl, requiredAccess);
3473- });
3474- }
3475-
3476- if (isUsableFromInlineRequired ()) {
3477- bool witnessIsUsableFromInline = typeDecl->getFormalAccessScope (
3478- DC, /* usableFromInlineAsPublic*/ true ).isPublic ();
3479- if (!witnessIsUsableFromInline)
3480- diagnoseOrDefer (assocType, false , DiagnoseUsableFromInline (typeDecl));
3481- }
3482- } else {
3483- // If there was no type declaration, synthesize one.
3445+ // If there was no type declaration, synthesize one.
3446+ if (typeDecl == nullptr ) {
34843447 auto aliasDecl = new (getASTContext ()) TypeAliasDecl (
34853448 SourceLoc (), SourceLoc (), assocType->getName (), SourceLoc (),
34863449 /* genericparams*/ nullptr , DC);
@@ -3490,55 +3453,48 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
34903453 aliasDecl->setSynthesized ();
34913454
34923455 // Inject the typealias into the nominal decl that conforms to the protocol.
3493- if ( auto nominal = DC->getSelfNominalTypeDecl ()) {
3494- AccessScope requiredAccessScope = getRequiredAccessScope ();
3495-
3496- if (!getASTContext ().isSwiftVersionAtLeast (5 ) &&
3497- !DC->getParentModule ()->isResilient ()) {
3498- // HACK: In pre-Swift-5, these typealiases were synthesized with the
3499- // same access level as the conforming type, which might be more
3500- // visible than the associated type witness. Preserve that behavior
3501- // when the underlying type has sufficient access, but only in
3502- // non-resilient modules.
3503- llvm::Optional<AccessScope> underlyingTypeScope =
3504- TypeAccessScopeChecker::getAccessScope (type, DC,
3505- /* usableFromInline*/ false );
3506- assert (underlyingTypeScope.has_value () &&
3507- " the type is already invalid and we shouldn't have gotten here" );
3508-
3509- AccessScope nominalAccessScope = nominal->getFormalAccessScope (DC);
3510- llvm::Optional<AccessScope> widestPossibleScope =
3511- underlyingTypeScope->intersectWith (nominalAccessScope);
3512- assert (widestPossibleScope.has_value () &&
3513- " we found the nominal and the type witness, didn't we?" );
3514- requiredAccessScope = widestPossibleScope.value ();
3515- }
3516-
3517- // An associated type witness can never be less than fileprivate, since
3518- // it must always be at least as visible as the enclosing type.
3519- AccessLevel requiredAccess =
3520- std::max (requiredAccessScope.accessLevelForDiagnostics (),
3521- AccessLevel::FilePrivate);
3522-
3523- aliasDecl->setAccess (requiredAccess);
3524- if (isUsableFromInlineRequired ()) {
3525- auto *attr =
3526- new (getASTContext ()) UsableFromInlineAttr (/* implicit=*/ true );
3527- aliasDecl->getAttrs ().add (attr);
3528- }
3456+ auto nominal = DC->getSelfNominalTypeDecl ();
3457+ AccessScope requiredAccessScope = getRequiredAccessScope ();
3458+
3459+ if (!getASTContext ().isSwiftVersionAtLeast (5 ) &&
3460+ !DC->getParentModule ()->isResilient ()) {
3461+ // HACK: In pre-Swift-5, these typealiases were synthesized with the
3462+ // same access level as the conforming type, which might be more
3463+ // visible than the associated type witness. Preserve that behavior
3464+ // when the underlying type has sufficient access, but only in
3465+ // non-resilient modules.
3466+ llvm::Optional<AccessScope> underlyingTypeScope =
3467+ TypeAccessScopeChecker::getAccessScope (type, DC,
3468+ /* usableFromInline*/ false );
3469+ assert (underlyingTypeScope.has_value () &&
3470+ " the type is already invalid and we shouldn't have gotten here" );
3471+
3472+ AccessScope nominalAccessScope = nominal->getFormalAccessScope (DC);
3473+ llvm::Optional<AccessScope> widestPossibleScope =
3474+ underlyingTypeScope->intersectWith (nominalAccessScope);
3475+ assert (widestPossibleScope.has_value () &&
3476+ " we found the nominal and the type witness, didn't we?" );
3477+ requiredAccessScope = widestPossibleScope.value ();
3478+ }
3479+
3480+ // An associated type witness can never be less than fileprivate, since
3481+ // it must always be at least as visible as the enclosing type.
3482+ AccessLevel requiredAccess =
3483+ std::max (requiredAccessScope.accessLevelForDiagnostics (),
3484+ AccessLevel::FilePrivate);
3485+
3486+ aliasDecl->setAccess (requiredAccess);
3487+ if (isUsableFromInlineRequired ()) {
3488+ auto *attr =
3489+ new (getASTContext ()) UsableFromInlineAttr (/* implicit=*/ true );
3490+ aliasDecl->getAttrs ().add (attr);
3491+ }
35293492
3530- if (nominal == DC) {
3531- nominal->addMember (aliasDecl);
3532- } else {
3533- auto ext = cast<ExtensionDecl>(DC);
3534- ext->addMember (aliasDecl);
3535- }
3493+ if (nominal == DC) {
3494+ nominal->addMember (aliasDecl);
35363495 } else {
3537- // If the declcontext is a Module, then we're in a special error recovery
3538- // situation. Mark the typealias as an error and don't inject it into any
3539- // DeclContext.
3540- assert (isa<ModuleDecl>(DC) && " Not an UnresolvedType conformance?" );
3541- aliasDecl->setInvalid ();
3496+ auto ext = cast<ExtensionDecl>(DC);
3497+ ext->addMember (aliasDecl);
35423498 }
35433499
35443500 typeDecl = aliasDecl;
@@ -5186,8 +5142,47 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
51865142 if (where.isImplicit ())
51875143 return ;
51885144
5189- Conformance->forEachTypeWitness ([&](const AssociatedTypeDecl *assoc ,
5145+ Conformance->forEachTypeWitness ([&](AssociatedTypeDecl *assocType ,
51905146 Type type, TypeDecl *typeDecl) -> bool {
5147+ checkObjCTypeErasedGenerics (assocType, type, typeDecl);
5148+
5149+ if (typeDecl && !typeDecl->isImplicit ()) {
5150+ // Check access.
5151+ bool isSetter = false ;
5152+ if (checkWitnessAccess (assocType, typeDecl, &isSetter)) {
5153+ assert (!isSetter);
5154+
5155+ // Note: you must not capture 'this' in the below closure.
5156+ const DeclContext *DC = this ->DC ;
5157+ auto requiredAccessScope = getRequiredAccessScope ();
5158+
5159+ diagnoseOrDefer (assocType, false ,
5160+ [DC, requiredAccessScope, typeDecl](
5161+ NormalProtocolConformance *conformance) {
5162+ AccessLevel requiredAccess =
5163+ requiredAccessScope.requiredAccessForDiagnostics ();
5164+ auto proto = conformance->getProtocol ();
5165+ auto protoAccessScope = proto->getFormalAccessScope (DC);
5166+ bool protoForcesAccess =
5167+ requiredAccessScope.hasEqualDeclContextWith (protoAccessScope);
5168+ auto diagKind = protoForcesAccess
5169+ ? diag::type_witness_not_accessible_proto
5170+ : diag::type_witness_not_accessible_type;
5171+ auto &diags = DC->getASTContext ().Diags ;
5172+ diags.diagnose (getLocForDiagnosingWitness (conformance, typeDecl),
5173+ diagKind, typeDecl, requiredAccess, proto);
5174+ diagnoseWitnessFixAccessLevel (diags, typeDecl, requiredAccess);
5175+ });
5176+ }
5177+
5178+ if (isUsableFromInlineRequired ()) {
5179+ bool witnessIsUsableFromInline = typeDecl->getFormalAccessScope (
5180+ DC, /* usableFromInlineAsPublic*/ true ).isPublic ();
5181+ if (!witnessIsUsableFromInline)
5182+ diagnoseOrDefer (assocType, false , DiagnoseUsableFromInline (typeDecl));
5183+ }
5184+ }
5185+
51915186 // Make sure any associated type witnesses don't make reference to a
51925187 // parameterized existential type, or we're going to have trouble at
51935188 // runtime.
0 commit comments