Skip to content

Commit c06216c

Browse files
committed
[Macros] Disable macro expansion within the definition of macros.
... and once we do that, ensure that `#externalMacro` can only be expanded as the definition of another macro.
1 parent 535aecb commit c06216c

File tree

7 files changed

+24
-5
lines changed

7 files changed

+24
-5
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6779,6 +6779,8 @@ ERROR(external_macro_not_found,none,
67796779
"'-load-plugin-library'", (StringRef, StringRef, DeclName))
67806780
ERROR(macro_must_be_defined,none,
67816781
"macro %0 requires a definition", (DeclName))
6782+
ERROR(external_macro_outside_macro_definition,none,
6783+
"macro 'externalMacro' can only be used to define another macro", ())
67826784
NOTE(macro_note, none,
67836785
"%1 (in macro %0)", (DeclName, StringRef))
67846786
WARNING(macro_warning, none,

include/swift/Sema/ConstraintSystem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,6 +1794,9 @@ enum class ConstraintSystemFlags {
17941794

17951795
/// When set, ignore async/sync mismatches
17961796
IgnoreAsyncSyncMismatch = 0x80,
1797+
1798+
/// Disable macro expansions.
1799+
DisableMacroExpansions = 0x100,
17971800
};
17981801

17991802
/// Options that affect the constraint system as a whole.

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5397,11 +5397,13 @@ namespace {
53975397
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
53985398
E->setMacroRef(macroRef);
53995399

5400-
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5401-
E->setRewritten(newExpr);
5402-
cs.cacheExprTypes(E);
5400+
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
5401+
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5402+
E->setRewritten(newExpr);
5403+
}
54035404
}
54045405

5406+
cs.cacheExprTypes(E);
54055407
return E;
54065408
}
54075409

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ TypeChecker::typeCheckTarget(SolutionApplicationTarget &target,
422422
if (options.contains(TypeCheckExprFlags::LeaveClosureBodyUnchecked))
423423
csOptions |= ConstraintSystemFlags::LeaveClosureBodyUnchecked;
424424

425+
if (options.contains(TypeCheckExprFlags::DisableMacroExpansions))
426+
csOptions |= ConstraintSystemFlags::DisableMacroExpansions;
427+
425428
ConstraintSystem cs(dc, csOptions);
426429

427430
if (auto *expr = target.getAsExpr()) {

lib/Sema/TypeCheckMacros.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ MacroDefinition MacroDefinitionRequest::evaluate(
234234

235235
PrettyStackTraceDecl debugStack("type checking macro definition", macro);
236236
Type typeCheckedType = TypeChecker::typeCheckExpression(
237-
definition, macro, contextualType);
237+
definition, macro, contextualType,
238+
TypeCheckExprFlags::DisableMacroExpansions);
238239
if (!typeCheckedType)
239240
return MacroDefinition::forInvalid();
240241

@@ -352,7 +353,8 @@ Expr *swift::expandMacroExpr(
352353
case MacroDefinition::Kind::Builtin: {
353354
switch (macroDef.getBuiltinKind()) {
354355
case BuiltinMacroKind::ExternalMacro:
355-
// FIXME: Error here.
356+
ctx.Diags.diagnose(
357+
expr->getLoc(), diag::external_macro_outside_macro_definition);
356358
return nullptr;
357359
}
358360
}

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ enum class TypeCheckExprFlags {
138138

139139
/// Don't type check expressions for correct availability.
140140
DisableExprAvailabilityChecking = 0x08,
141+
142+
/// Don't expansino macros.
143+
DisableMacroExpansions = 0x10,
141144
};
142145

143146
using TypeCheckExprOptions = OptionSet<TypeCheckExprFlags>;

test/Macros/macros_diagnostics.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,7 @@ func testMissing() {
102102

103103
@expression macro undefined() // expected-error{{macro 'undefined()' requires a definition}}
104104

105+
func testExternalMacroOutOfPlace() {
106+
let _: Int = #externalMacro(module: "A", type: "B")
107+
// expected-error@-1{{macro 'externalMacro' can only be used to define another macro}}
108+
}

0 commit comments

Comments
 (0)