@@ -1086,7 +1086,8 @@ namespace {
1086
1086
static DirectlyReferencedTypeDecls
1087
1087
directReferencesForTypeRepr (Evaluator &evaluator, ASTContext &ctx,
1088
1088
TypeRepr *typeRepr, DeclContext *dc,
1089
- bool allowUsableFromInline=false );
1089
+ bool allowUsableFromInline,
1090
+ bool rhsOfSelfRequirement);
1090
1091
1091
1092
// / Retrieve the set of type declarations that are directly referenced from
1092
1093
// / the given type.
@@ -1118,13 +1119,6 @@ SelfBounds SelfBoundsFromWhereClauseRequest::evaluate(
1118
1119
const DeclContext *dc =
1119
1120
protoDecl ? (const DeclContext *)protoDecl : (const DeclContext *)extDecl;
1120
1121
1121
- // A protocol or extension 'where' clause can reference associated types of
1122
- // the protocol itself, so we have to start unqualified lookup from 'dc'.
1123
- //
1124
- // However, the right hand side of a 'Self' conformance constraint must be
1125
- // resolved before unqualified lookup into 'dc' can work, so we make an
1126
- // exception here and begin lookup from the parent context instead.
1127
- auto *lookupDC = dc->getParent ();
1128
1122
auto requirements = protoDecl ? protoDecl->getTrailingWhereClause ()
1129
1123
: extDecl->getTrailingWhereClause ();
1130
1124
@@ -1151,7 +1145,10 @@ SelfBounds SelfBoundsFromWhereClauseRequest::evaluate(
1151
1145
// Resolve the right-hand side.
1152
1146
DirectlyReferencedTypeDecls rhsDecls;
1153
1147
if (auto typeRepr = req.getConstraintRepr ()) {
1154
- rhsDecls = directReferencesForTypeRepr (evaluator, ctx, typeRepr, lookupDC);
1148
+ rhsDecls = directReferencesForTypeRepr (evaluator, ctx, typeRepr,
1149
+ const_cast <DeclContext *>(dc),
1150
+ /* allowUsableFromInline=*/ false ,
1151
+ /* rhsOfSelfRequirement=*/ true );
1155
1152
}
1156
1153
1157
1154
SmallVector<ModuleDecl *, 2 > modulesFound;
@@ -1213,7 +1210,9 @@ TypeDeclsFromWhereClauseRequest::evaluate(Evaluator &evaluator,
1213
1210
1214
1211
DirectlyReferencedTypeDecls result;
1215
1212
auto resolve = [&](TypeRepr *typeRepr) {
1216
- auto decls = directReferencesForTypeRepr (evaluator, ctx, typeRepr, ext);
1213
+ auto decls = directReferencesForTypeRepr (evaluator, ctx, typeRepr, ext,
1214
+ /* allowUsableFromInline=*/ false ,
1215
+ /* rhsOfSelfRequirement=*/ false );
1217
1216
result.first .insert (result.first .end (),
1218
1217
decls.first .begin (),
1219
1218
decls.first .end ());
@@ -2834,7 +2833,8 @@ static DirectlyReferencedTypeDecls
2834
2833
directReferencesForUnqualifiedTypeLookup (DeclNameRef name,
2835
2834
SourceLoc loc, DeclContext *dc,
2836
2835
LookupOuterResults lookupOuter,
2837
- bool allowUsableFromInline=false ) {
2836
+ bool allowUsableFromInline,
2837
+ bool rhsOfSelfRequirement) {
2838
2838
UnqualifiedLookupOptions options =
2839
2839
UnqualifiedLookupFlags::TypeLookup |
2840
2840
UnqualifiedLookupFlags::AllowProtocolMembers;
@@ -2856,23 +2856,17 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
2856
2856
//
2857
2857
// extension MyProto where AssocType == Int { ... }
2858
2858
//
2859
- // For this reason, ASTScope maps source locations inside the 'where'
2860
- // clause to a scope that performs the lookup into the protocol or
2861
- // protocol extension.
2862
- //
2863
- // However, protocol and protocol extensions can also put bounds on 'Self',
2864
- // for example:
2865
- //
2866
- // protocol MyProto where Self : MyClass { ... }
2867
- //
2868
- // We must start searching for 'MyClass' at the top level, otherwise
2869
- // we end up with a cycle, because qualified lookup wants to resolve
2870
- // 'Self' bounds to build the set of declarations to search inside of.
2871
- //
2872
- // To make this work, we handle the top-level lookup case explicitly
2873
- // here, bypassing unqualified lookup and ASTScope altogether.
2874
- if (dc->isModuleScopeContext ())
2875
- loc = SourceLoc ();
2859
+ // To avoid cycles when resolving the right-hand side, we perform the
2860
+ // lookup in the parent context (for a protocol), or a special mode where
2861
+ // we disregard 'Self' requirements (for a protocol extension).
2862
+ if (rhsOfSelfRequirement) {
2863
+ if (dc->getExtendedProtocolDecl ())
2864
+ options |= UnqualifiedLookupFlags::DisregardSelfBounds;
2865
+ else {
2866
+ dc = dc->getModuleScopeContext ();
2867
+ loc = SourceLoc ();
2868
+ }
2869
+ }
2876
2870
2877
2871
DirectlyReferencedTypeDecls results;
2878
2872
@@ -2956,10 +2950,12 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator,
2956
2950
static DirectlyReferencedTypeDecls
2957
2951
directReferencesForDeclRefTypeRepr (Evaluator &evaluator, ASTContext &ctx,
2958
2952
DeclRefTypeRepr *repr, DeclContext *dc,
2959
- bool allowUsableFromInline) {
2953
+ bool allowUsableFromInline,
2954
+ bool rhsOfSelfRequirement) {
2960
2955
if (auto *qualIdentTR = dyn_cast<QualifiedIdentTypeRepr>(repr)) {
2961
2956
auto result = directReferencesForTypeRepr (
2962
- evaluator, ctx, qualIdentTR->getBase (), dc, allowUsableFromInline);
2957
+ evaluator, ctx, qualIdentTR->getBase (), dc,
2958
+ allowUsableFromInline, rhsOfSelfRequirement);
2963
2959
2964
2960
// For a qualified identifier, perform qualified name lookup.
2965
2961
result.first = directReferencesForQualifiedTypeLookup (
@@ -2972,13 +2968,14 @@ directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx,
2972
2968
// For an unqualified identifier, perform unqualified name lookup.
2973
2969
return directReferencesForUnqualifiedTypeLookup (
2974
2970
repr->getNameRef (), repr->getLoc (), dc, LookupOuterResults::Excluded,
2975
- allowUsableFromInline);
2971
+ allowUsableFromInline, rhsOfSelfRequirement );
2976
2972
}
2977
2973
2978
2974
static DirectlyReferencedTypeDecls
2979
2975
directReferencesForTypeRepr (Evaluator &evaluator,
2980
2976
ASTContext &ctx, TypeRepr *typeRepr,
2981
- DeclContext *dc, bool allowUsableFromInline) {
2977
+ DeclContext *dc, bool allowUsableFromInline,
2978
+ bool rhsOfSelfRequirement) {
2982
2979
DirectlyReferencedTypeDecls result;
2983
2980
2984
2981
switch (typeRepr->getKind ()) {
@@ -2990,15 +2987,17 @@ directReferencesForTypeRepr(Evaluator &evaluator,
2990
2987
auto attributed = cast<AttributedTypeRepr>(typeRepr);
2991
2988
return directReferencesForTypeRepr (evaluator, ctx,
2992
2989
attributed->getTypeRepr (), dc,
2993
- allowUsableFromInline);
2990
+ allowUsableFromInline,
2991
+ rhsOfSelfRequirement);
2994
2992
}
2995
2993
2996
2994
case TypeReprKind::Composition: {
2997
2995
auto composition = cast<CompositionTypeRepr>(typeRepr);
2998
2996
for (auto component : composition->getTypes ()) {
2999
2997
auto componentResult =
3000
2998
directReferencesForTypeRepr (evaluator, ctx, component, dc,
3001
- allowUsableFromInline);
2999
+ allowUsableFromInline,
3000
+ rhsOfSelfRequirement);
3002
3001
result.first .insert (result.first .end (),
3003
3002
componentResult.first .begin (),
3004
3003
componentResult.first .end ());
@@ -3013,7 +3012,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
3013
3012
case TypeReprKind::UnqualifiedIdent:
3014
3013
return directReferencesForDeclRefTypeRepr (evaluator, ctx,
3015
3014
cast<DeclRefTypeRepr>(typeRepr),
3016
- dc, allowUsableFromInline);
3015
+ dc, allowUsableFromInline,
3016
+ rhsOfSelfRequirement);
3017
3017
3018
3018
case TypeReprKind::Dictionary:
3019
3019
result.first .push_back (ctx.getDictionaryDecl ());
@@ -3024,7 +3024,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
3024
3024
if (tupleRepr->isParenType ()) {
3025
3025
result = directReferencesForTypeRepr (evaluator, ctx,
3026
3026
tupleRepr->getElementType (0 ), dc,
3027
- allowUsableFromInline);
3027
+ allowUsableFromInline,
3028
+ rhsOfSelfRequirement);
3028
3029
} else {
3029
3030
result.first .push_back (ctx.getBuiltinTupleDecl ());
3030
3031
}
@@ -3035,21 +3036,24 @@ directReferencesForTypeRepr(Evaluator &evaluator,
3035
3036
auto packExpansionRepr = cast<VarargTypeRepr>(typeRepr);
3036
3037
return directReferencesForTypeRepr (evaluator, ctx,
3037
3038
packExpansionRepr->getElementType (), dc,
3038
- allowUsableFromInline);
3039
+ allowUsableFromInline,
3040
+ rhsOfSelfRequirement);
3039
3041
}
3040
3042
3041
3043
case TypeReprKind::PackExpansion: {
3042
3044
auto packExpansionRepr = cast<PackExpansionTypeRepr>(typeRepr);
3043
3045
return directReferencesForTypeRepr (evaluator, ctx,
3044
3046
packExpansionRepr->getPatternType (), dc,
3045
- allowUsableFromInline);
3047
+ allowUsableFromInline,
3048
+ rhsOfSelfRequirement);
3046
3049
}
3047
3050
3048
3051
case TypeReprKind::PackElement: {
3049
3052
auto packReferenceRepr = cast<PackElementTypeRepr>(typeRepr);
3050
3053
return directReferencesForTypeRepr (evaluator, ctx,
3051
3054
packReferenceRepr->getPackType (), dc,
3052
- allowUsableFromInline);
3055
+ allowUsableFromInline,
3056
+ rhsOfSelfRequirement);
3053
3057
}
3054
3058
3055
3059
case TypeReprKind::Inverse: {
@@ -3058,7 +3062,8 @@ directReferencesForTypeRepr(Evaluator &evaluator,
3058
3062
auto *inverseRepr = cast<InverseTypeRepr>(typeRepr);
3059
3063
auto innerResult = directReferencesForTypeRepr (evaluator, ctx,
3060
3064
inverseRepr->getConstraint (), dc,
3061
- allowUsableFromInline);
3065
+ allowUsableFromInline,
3066
+ rhsOfSelfRequirement);
3062
3067
if (innerResult.first .size () == 1 ) {
3063
3068
if (auto *proto = dyn_cast<ProtocolDecl>(innerResult.first [0 ])) {
3064
3069
if (auto ip = proto->getInvertibleProtocolKind ()) {
@@ -3169,7 +3174,9 @@ DirectlyReferencedTypeDecls InheritedDeclsReferencedRequest::evaluate(
3169
3174
dc = (DeclContext *)decl.get <const ExtensionDecl *>();
3170
3175
3171
3176
return directReferencesForTypeRepr (evaluator, dc->getASTContext (), typeRepr,
3172
- const_cast <DeclContext *>(dc));
3177
+ const_cast <DeclContext *>(dc),
3178
+ /* allowUsableFromInline=*/ false ,
3179
+ /* rhsOfSelfRequirement=*/ false );
3173
3180
}
3174
3181
3175
3182
// Fall back to semantic types.
@@ -3188,7 +3195,9 @@ DirectlyReferencedTypeDecls UnderlyingTypeDeclsReferencedRequest::evaluate(
3188
3195
// Prefer syntactic information when we have it.
3189
3196
if (auto typeRepr = typealias->getUnderlyingTypeRepr ()) {
3190
3197
return directReferencesForTypeRepr (evaluator, typealias->getASTContext (),
3191
- typeRepr, typealias);
3198
+ typeRepr, typealias,
3199
+ /* allowUsableFromInline=*/ false ,
3200
+ /* rhsOfSelfRequirement=*/ false );
3192
3201
}
3193
3202
3194
3203
// Fall back to semantic types.
@@ -3354,7 +3363,8 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,
3354
3363
ASTContext &ctx = ext->getASTContext ();
3355
3364
DirectlyReferencedTypeDecls referenced =
3356
3365
directReferencesForTypeRepr (evaluator, ctx, typeRepr, ext->getParent (),
3357
- ext->isInSpecializeExtensionContext ());
3366
+ ext->isInSpecializeExtensionContext (),
3367
+ /* rhsOfSelfRequirement=*/ false );
3358
3368
3359
3369
// Resolve those type declarations to nominal type declarations.
3360
3370
SmallVector<ModuleDecl *, 2 > modulesFound;
@@ -3402,7 +3412,9 @@ static bool declsAreProtocols(ArrayRef<TypeDecl *> decls) {
3402
3412
3403
3413
bool TypeRepr::isProtocolOrProtocolComposition (DeclContext *dc) {
3404
3414
auto &ctx = dc->getASTContext ();
3405
- auto references = directReferencesForTypeRepr (ctx.evaluator , ctx, this , dc);
3415
+ auto references = directReferencesForTypeRepr (ctx.evaluator , ctx, this , dc,
3416
+ /* allowUsableFromInline=*/ false ,
3417
+ /* rhsOfSelfRequirement=*/ false );
3406
3418
return declsAreProtocols (references.first );
3407
3419
}
3408
3420
@@ -3435,7 +3447,9 @@ createTupleExtensionGenericParams(ASTContext &ctx,
3435
3447
DirectlyReferencedTypeDecls referenced =
3436
3448
directReferencesForTypeRepr (ctx.evaluator , ctx,
3437
3449
extendedTypeRepr,
3438
- ext->getParent ());
3450
+ ext->getParent (),
3451
+ /* allowUsableFromInline=*/ false ,
3452
+ /* rhsOfSelfRequirement=*/ false );
3439
3453
assert (referenced.second .empty () && " Implement me" );
3440
3454
if (referenced.first .size () != 1 || !isa<TypeAliasDecl>(referenced.first [0 ]))
3441
3455
return nullptr ;
@@ -3708,7 +3722,9 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
3708
3722
DirectlyReferencedTypeDecls decls;
3709
3723
if (auto *typeRepr = attr->getTypeRepr ()) {
3710
3724
decls = directReferencesForTypeRepr (
3711
- evaluator, ctx, typeRepr, dc);
3725
+ evaluator, ctx, typeRepr, dc,
3726
+ /* allowUsableFromInline=*/ false ,
3727
+ /* rhsOfSelfRequirement=*/ false );
3712
3728
} else if (Type type = attr->getType ()) {
3713
3729
decls = directReferencesForType (type);
3714
3730
}
@@ -3737,7 +3753,9 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
3737
3753
modulesFound.clear ();
3738
3754
anyObject = false ;
3739
3755
decls = directReferencesForUnqualifiedTypeLookup (
3740
- name, loc, dc, LookupOuterResults::Included);
3756
+ name, loc, dc, LookupOuterResults::Included,
3757
+ /* allowUsableFromInline=*/ false ,
3758
+ /* rhsOfSelfRequirement=*/ false );
3741
3759
nominals = resolveTypeDeclsToNominal (evaluator, ctx, decls.first ,
3742
3760
ResolveToNominalOptions (),
3743
3761
modulesFound, anyObject);
@@ -3970,7 +3988,9 @@ ProtocolDecl *ImplementsAttrProtocolRequest::evaluate(
3970
3988
3971
3989
ASTContext &ctx = dc->getASTContext ();
3972
3990
DirectlyReferencedTypeDecls referenced =
3973
- directReferencesForTypeRepr (evaluator, ctx, typeRepr, dc);
3991
+ directReferencesForTypeRepr (evaluator, ctx, typeRepr, dc,
3992
+ /* allowUsableFromInline=*/ false ,
3993
+ /* rhsOfSelfRequirement=*/ false );
3974
3994
3975
3995
// Resolve those type declarations to nominal type declarations.
3976
3996
SmallVector<ModuleDecl *, 2 > modulesFound;
0 commit comments