@@ -648,6 +648,13 @@ void namelookup::recordLookupOfTopLevelName(DeclContext *topLevelContext,
648
648
nameTracker->addTopLevelName (name.getBaseName (), isCascading);
649
649
}
650
650
651
+ namespace {
652
+ // / Whether we're looking up outer results or not.
653
+ enum class LookupOuterResults {
654
+ Excluded,
655
+ Included
656
+ };
657
+ }
651
658
652
659
// / Retrieve the set of type declarations that are directly referenced from
653
660
// / the given parsed type representation.
@@ -1878,11 +1885,15 @@ resolveTypeDeclsToNominal(Evaluator &evaluator,
1878
1885
// / Perform unqualified name lookup for types at the given location.
1879
1886
static DirectlyReferencedTypeDecls
1880
1887
directReferencesForUnqualifiedTypeLookup (DeclName name,
1881
- SourceLoc loc, DeclContext *dc) {
1888
+ SourceLoc loc, DeclContext *dc,
1889
+ LookupOuterResults lookupOuter) {
1882
1890
DirectlyReferencedTypeDecls results;
1883
1891
UnqualifiedLookup::Options options =
1884
1892
UnqualifiedLookup::Flags::TypeLookup |
1885
1893
UnqualifiedLookup::Flags::AllowProtocolMembers;
1894
+ if (lookupOuter == LookupOuterResults::Included)
1895
+ options |= UnqualifiedLookup::Flags::IncludeOuterResults;
1896
+
1886
1897
UnqualifiedLookup lookup (name, dc, loc, options);
1887
1898
for (const auto &result : lookup.Results ) {
1888
1899
if (auto typeDecl = dyn_cast<TypeDecl>(result.getValueDecl ()))
@@ -1957,7 +1968,8 @@ directReferencesForIdentTypeRepr(Evaluator &evaluator,
1957
1968
current =
1958
1969
directReferencesForUnqualifiedTypeLookup (component->getIdentifier (),
1959
1970
component->getIdLoc (),
1960
- dc);
1971
+ dc,
1972
+ LookupOuterResults::Excluded);
1961
1973
1962
1974
// If we didn't find anything, fail now.
1963
1975
if (current.empty ())
@@ -2195,6 +2207,19 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,
2195
2207
return nominalTypes.empty () ? nullptr : nominalTypes[0 ];
2196
2208
}
2197
2209
2210
+ // / Whether there are only associated types in the set of declarations.
2211
+ static bool declsAreAssociatedTypes (ArrayRef<TypeDecl *> decls) {
2212
+ if (decls.empty ())
2213
+ return false ;
2214
+
2215
+ for (auto decl : decls) {
2216
+ if (!isa<AssociatedTypeDecl>(decl))
2217
+ return false ;
2218
+ }
2219
+
2220
+ return true ;
2221
+ }
2222
+
2198
2223
llvm::Expected<NominalTypeDecl *>
2199
2224
CustomAttrNominalRequest::evaluate (Evaluator &evaluator,
2200
2225
CustomAttr *attr, DeclContext *dc) const {
@@ -2217,6 +2242,48 @@ CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
2217
2242
if (nominals.size () == 1 && !isa<ProtocolDecl>(nominals.front ()))
2218
2243
return nominals.front ();
2219
2244
2245
+ // If we found declarations that are associated types, look outside of
2246
+ // the current context to see if we can recover.
2247
+ if (declsAreAssociatedTypes (decls)) {
2248
+ if (auto typeRepr = typeLoc.getTypeRepr ()) {
2249
+ if (auto identTypeRepr = dyn_cast<SimpleIdentTypeRepr>(typeRepr)) {
2250
+ auto assocType = cast<AssociatedTypeDecl>(decls.front ());
2251
+
2252
+ modulesFound.clear ();
2253
+ anyObject = false ;
2254
+ decls = directReferencesForUnqualifiedTypeLookup (
2255
+ identTypeRepr->getIdentifier (), identTypeRepr->getIdLoc (), dc,
2256
+ LookupOuterResults::Included);
2257
+ nominals = resolveTypeDeclsToNominal (evaluator, ctx, decls,
2258
+ modulesFound, anyObject);
2259
+ if (nominals.size () == 1 && !isa<ProtocolDecl>(nominals.front ())) {
2260
+ auto nominal = nominals.front ();
2261
+ if (nominal->getDeclContext ()->isModuleScopeContext ()) {
2262
+ // Complain, producing module qualification in a Fix-It.
2263
+ auto moduleName = nominal->getParentModule ()->getName ();
2264
+ ctx.Diags .diagnose (typeRepr->getLoc (),
2265
+ diag::warn_property_wrapper_module_scope,
2266
+ identTypeRepr->getIdentifier (),
2267
+ moduleName)
2268
+ .fixItInsert (typeRepr->getLoc (),
2269
+ moduleName.str ().str () + " ." );
2270
+ ctx.Diags .diagnose (assocType, diag::kind_declname_declared_here,
2271
+ assocType->getDescriptiveKind (),
2272
+ assocType->getFullName ());
2273
+
2274
+ ComponentIdentTypeRepr *components[2 ] = {
2275
+ new (ctx) SimpleIdentTypeRepr (typeRepr->getLoc (), moduleName),
2276
+ identTypeRepr
2277
+ };
2278
+
2279
+ typeLoc = TypeLoc (IdentTypeRepr::create (ctx, components));
2280
+ return nominal;
2281
+ }
2282
+ }
2283
+ }
2284
+ }
2285
+ }
2286
+
2220
2287
return nullptr ;
2221
2288
}
2222
2289
0 commit comments