Skip to content

Commit 94abc25

Browse files
committed
[Macros] Type-check attached macro arguments.
1 parent 0ca5b8a commit 94abc25

File tree

5 files changed

+33
-21
lines changed

5 files changed

+33
-21
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3590,7 +3590,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
35903590
if (auto macro = dyn_cast<MacroDecl>(decl)) {
35913591
// Macro can only be used in an expansion. If we end up here, it's
35923592
// because we found a macro but are missing the leading '#'.
3593-
if (!locator->isForMacroExpansion()) {
3593+
if (!(locator->isForMacroExpansion() || locator->getAnchor().isImplicit())) {
35943594
// Record a fix here
35953595
(void)recordFix(MacroMissingPound::create(*this, macro, locator));
35963596
}

lib/Sema/TypeCheckMacros.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ swift::findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc) {
10921092
// Look for macros at module scope. They can only occur at module scope, and
10931093
// we need to be sure not to trigger name lookup into type contexts along
10941094
// the way.
1095-
llvm::TinyPtrVector<MacroDecl *> macros;
1095+
llvm::TinyPtrVector<ValueDecl *> macros;
10961096
auto moduleScopeDC = dc->getModuleScopeContext();
10971097
ASTContext &ctx = moduleScopeDC->getASTContext();
10981098
UnqualifiedLookupDescriptor descriptor(
@@ -1110,16 +1110,28 @@ swift::findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc) {
11101110
if (macros.empty())
11111111
return nullptr;
11121112

1113-
if (macros.size() > 1) {
1114-
ctx.Diags.diagnose(attr->getLocation(), diag::ambiguous_macro_reference,
1115-
identTypeRepr->getNameRef().getFullName());
1116-
1117-
for (auto macro : macros) {
1118-
macro->diagnose(
1119-
diag::kind_declname_declared_here, macro->getDescriptiveKind(),
1120-
macro->getName());
1121-
}
1113+
// Extract macro arguments from the attribute, or create an empty list.
1114+
ArgumentList *attrArgs;
1115+
if (attr->hasArgs()) {
1116+
attrArgs = attr->getArgs();
1117+
} else {
1118+
attrArgs = ArgumentList::createImplicit(ctx, {});
11221119
}
11231120

1124-
return macros.front();
1121+
// Form an `OverloadedDeclRefExpr` with the filtered lookup result above
1122+
// to ensure @freestanding macros are not considered in overload resolution.
1123+
FunctionRefKind functionRefKind = FunctionRefKind::SingleApply;
1124+
auto macroRefExpr = new (ctx) OverloadedDeclRefExpr(
1125+
macros, identTypeRepr->getNameLoc(), functionRefKind,
1126+
/*implicit*/true);
1127+
auto *call = CallExpr::createImplicit(ctx, macroRefExpr, attrArgs);
1128+
1129+
Expr *result = call;
1130+
TypeChecker::typeCheckExpression(result, dc);
1131+
1132+
if (auto *fn = dyn_cast<DeclRefExpr>(call->getFn()))
1133+
if (auto *macro = dyn_cast<MacroDecl>(fn->getDecl()))
1134+
return macro;
1135+
1136+
return dyn_cast<MacroDecl>(macros.front());
11251137
}

test/Macros/accessor_macros.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// REQUIRES: OS=macosx
1818

1919
@attached(accessor)
20-
macro myPropertyWrapper: Void =
20+
macro myPropertyWrapper() =
2121
#externalMacro(module: "MacroDefinition", type: "PropertyWrapperMacro")
2222

2323
struct Date { }
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Macros -module-name MacrosTest
22

3-
@attached(accessor) macro m1: Void = #externalMacro(module: "MyMacros", type: "Macro1")
4-
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro1' could not be found for macro 'm1'}}
5-
// expected-note@-2{{'m1' declared here}}
3+
@attached(accessor) macro m1() = #externalMacro(module: "MyMacros", type: "Macro1")
4+
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro1' could not be found for macro 'm1()'}}
5+
// expected-note@-2{{'m1()' declared here}}
66

77
@attached(accessor) macro m2(_: Int) -> Void = #externalMacro(module: "MyMacros", type: "Macro2")
88
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro2' could not be found for macro 'm2'}}
9-
// expected-note@-2 2{{macro 'm2' declared here}}
9+
// expected-note@-2 2{{candidate has partially matching parameter list (Int)}}
1010

1111
@attached(accessor) macro m2(_: Double) -> Void = #externalMacro(module: "MyMacros", type: "Macro2")
1212
// expected-warning@-1{{external macro implementation type 'MyMacros.Macro2' could not be found for macro 'm2'}}
13-
// expected-note@-2 2{{macro 'm2' declared here}}
13+
// expected-note@-2 2{{candidate has partially matching parameter list (Double)}}
1414

1515
@m1 struct X1 { }
1616

1717
// FIXME: Redundant diagnostic
18-
@m2 struct X2 { } // expected-error 2{{ambiguous reference to macro 'm2'}}
18+
@m2 struct X2 { } // expected-error 2{{no exact matches in call to macro 'm2'}}
1919

2020
// Check for nesting rules.
2121
struct SkipNestedType {
@@ -28,5 +28,5 @@ struct SkipNestedType {
2828

2929
// We select the macro, not the property wrapper.
3030
@m1 var x: Int = 0
31-
// expected-error@-1{{external macro implementation type 'MyMacros.Macro1' could not be found for macro 'm1'; the type must be public and provided via '-load-plugin-library'}}
31+
// expected-error@-1{{external macro implementation type 'MyMacros.Macro1' could not be found for macro 'm1()'; the type must be public and provided via '-load-plugin-library'}}
3232
}

test/Serialization/Inputs/def_macros.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
@expression macro internalStringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
44

5-
@attached(accessor) public macro myWrapper: Void = #externalMacro(module: "MacroDefinition", type: "MyWrapperMacro")
5+
@attached(accessor) public macro myWrapper() = #externalMacro(module: "MacroDefinition", type: "MyWrapperMacro")
66

77
@attached(memberAttributes) public macro wrapAllProperties() = #externalMacro(module: "MacroDefinition", type: "WrapAllProperties")
88

0 commit comments

Comments
 (0)