Skip to content

Commit 0b2fe8f

Browse files
committed
[Macros] Ensure that overloading a type and macro doesn't break type references
Fixes rdar://106044286
1 parent a9e5075 commit 0b2fe8f

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

lib/Sema/PreCheckExpr.cpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,8 +1391,9 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
13911391

13921392
// Qualified type lookup with a module base is represented as a DeclRefExpr
13931393
// and not a TypeExpr.
1394-
if (auto *DRE = dyn_cast<DeclRefExpr>(UDE->getBase())) {
1395-
if (auto *TD = dyn_cast<TypeDecl>(DRE->getDecl())) {
1394+
auto handleNestedTypeLookup = [&](
1395+
TypeDecl *TD, DeclNameLoc ParentNameLoc
1396+
) -> TypeExpr * {
13961397
// See if the type has a member type with this name.
13971398
auto Result = TypeChecker::lookupMemberType(
13981399
DC, TD->getDeclaredInterfaceType(), Name,
@@ -1402,10 +1403,43 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
14021403
// a non-type member, so leave the expression as-is.
14031404
if (Result.size() == 1) {
14041405
return TypeExpr::createForMemberDecl(
1405-
DRE->getNameLoc(), TD, UDE->getNameLoc(), Result.front().Member);
1406+
ParentNameLoc, TD, UDE->getNameLoc(), Result.front().Member);
14061407
}
1408+
1409+
return nullptr;
1410+
};
1411+
1412+
if (auto *DRE = dyn_cast<DeclRefExpr>(UDE->getBase())) {
1413+
if (auto *TD = dyn_cast<TypeDecl>(DRE->getDecl()))
1414+
return handleNestedTypeLookup(TD, DRE->getNameLoc());
1415+
1416+
return nullptr;
1417+
}
1418+
1419+
// Determine whether there is exactly one type declaration, where all
1420+
// other declarations are macros.
1421+
if (auto *ODRE = dyn_cast<OverloadedDeclRefExpr>(UDE->getBase())) {
1422+
TypeDecl *FoundTD = nullptr;
1423+
for (auto *D : ODRE->getDecls()) {
1424+
if (auto *TD = dyn_cast<TypeDecl>(D)) {
1425+
if (FoundTD)
1426+
return nullptr;
1427+
1428+
FoundTD = TD;
1429+
continue;
1430+
}
1431+
1432+
// Ignore macros; they can't have any nesting.
1433+
if (isa<MacroDecl>(D))
1434+
continue;
1435+
1436+
// Anything else prevents folding.
1437+
return nullptr;
14071438
}
14081439

1440+
if (FoundTD)
1441+
return handleNestedTypeLookup(FoundTD, ODRE->getNameLoc());
1442+
14091443
return nullptr;
14101444
}
14111445

test/Macros/macros_diagnostics.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,17 @@ func testExternalMacroOutOfPlace() {
139139
public macro macroWithDefaults(_: Int = 17) = #externalMacro(module: "A", type: "B")
140140
// expected-error@-1{{default arguments are not allowed in macros}}
141141
// expected-warning@-2{{external macro implementation type 'A.B' could not be found for macro 'macroWithDefaults'}}
142+
143+
// Make sure we don't allow macros to prevent type folding.
144+
@attached(member)
145+
public macro MacroOrType() = #externalMacro(module: "A", type: "MacroOrType")
146+
// expected-warning@-1{{external macro implementation type}}
147+
148+
struct MacroOrType {
149+
typealias Nested = Int
150+
}
151+
152+
func test() {
153+
let _: [MacroOrType.Nested] = []
154+
_ = [MacroOrType.Nested]()
155+
}

0 commit comments

Comments
 (0)