@@ -3442,45 +3442,8 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
3442
3442
3443
3443
assert (!type->hasArchetype () && " Got a contextual type here?" );
3444
3444
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 ) {
3484
3447
auto aliasDecl = new (getASTContext ()) TypeAliasDecl (
3485
3448
SourceLoc (), SourceLoc (), assocType->getName (), SourceLoc (),
3486
3449
/* genericparams*/ nullptr , DC);
@@ -3490,55 +3453,48 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
3490
3453
aliasDecl->setSynthesized ();
3491
3454
3492
3455
// 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
+ }
3529
3492
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);
3536
3495
} 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);
3542
3498
}
3543
3499
3544
3500
typeDecl = aliasDecl;
@@ -5186,8 +5142,47 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
5186
5142
if (where.isImplicit ())
5187
5143
return ;
5188
5144
5189
- Conformance->forEachTypeWitness ([&](const AssociatedTypeDecl *assoc ,
5145
+ Conformance->forEachTypeWitness ([&](AssociatedTypeDecl *assocType ,
5190
5146
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
+
5191
5186
// Make sure any associated type witnesses don't make reference to a
5192
5187
// parameterized existential type, or we're going to have trouble at
5193
5188
// runtime.
0 commit comments