Skip to content

Commit 97ee702

Browse files
authored
Merge pull request swiftlang#62917 from DougGregor/macro-expansion-diags
2 parents 2f8751c + c06216c commit 97ee702

12 files changed

+113
-27
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6786,6 +6786,10 @@ ERROR(external_macro_not_found,none,
67866786
"external macro implementation type '%0.%1' could not be found for "
67876787
"macro %2; the type must be public and provided via "
67886788
"'-load-plugin-library'", (StringRef, StringRef, DeclName))
6789+
ERROR(macro_must_be_defined,none,
6790+
"macro %0 requires a definition", (DeclName))
6791+
ERROR(external_macro_outside_macro_definition,none,
6792+
"macro 'externalMacro' can only be used to define another macro", ())
67896793
NOTE(macro_note, none,
67906794
"%1 (in macro %0)", (DeclName, StringRef))
67916795
WARNING(macro_warning, none,

include/swift/AST/MacroDefinition.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class MacroDefinition {
112112
return data.builtin;
113113
}
114114

115-
explicit operator bool() const { return kind != Kind::Invalid; }
115+
operator Kind() const { return kind; }
116116
};
117117

118118
}

include/swift/Sema/ConstraintSystem.h

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

17991799
/// When set, ignore async/sync mismatches
18001800
IgnoreAsyncSyncMismatch = 0x80,
1801+
1802+
/// Disable macro expansions.
1803+
DisableMacroExpansions = 0x100,
18011804
};
18021805

18031806
/// 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
@@ -5406,11 +5406,13 @@ namespace {
54065406
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
54075407
E->setMacroRef(macroRef);
54085408

5409-
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5410-
E->setRewritten(newExpr);
5411-
cs.cacheExprTypes(E);
5409+
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
5410+
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5411+
E->setRewritten(newExpr);
5412+
}
54125413
}
54135414

5415+
cs.cacheExprTypes(E);
54145416
return E;
54155417
}
54165418

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/TypeCheckDeclPrimary.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "swift/AST/ForeignErrorConvention.h"
4040
#include "swift/AST/GenericEnvironment.h"
4141
#include "swift/AST/Initializer.h"
42+
#include "swift/AST/MacroDefinition.h"
4243
#include "swift/AST/NameLookup.h"
4344
#include "swift/AST/NameLookupRequests.h"
4445
#include "swift/AST/PrettyStackTrace.h"
@@ -2004,6 +2005,39 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20042005
MD->diagnose(diag::macro_in_nested, MD->getName());
20052006
if (!MD->getMacroContexts())
20062007
MD->diagnose(diag::macro_without_context, MD->getName());
2008+
2009+
// Check the macro definition.
2010+
switch (auto macroDef = MD->getDefinition()) {
2011+
case MacroDefinition::Kind::Undefined:
2012+
MD->diagnose(diag::macro_must_be_defined, MD->getName());
2013+
break;
2014+
2015+
case MacroDefinition::Kind::Invalid:
2016+
case MacroDefinition::Kind::Builtin:
2017+
// Nothing else to check here.
2018+
break;
2019+
2020+
case MacroDefinition::Kind::External: {
2021+
// Retrieve the external definition of the macro.
2022+
auto external = macroDef.getExternalMacro();
2023+
ExternalMacroDefinitionRequest request{
2024+
&Ctx, external.moduleName, external.macroTypeName
2025+
};
2026+
auto externalDef = evaluateOrDefault(
2027+
Ctx.evaluator, request, ExternalMacroDefinition()
2028+
);
2029+
if (!externalDef.opaqueHandle) {
2030+
MD->diagnose(
2031+
diag::external_macro_not_found,
2032+
external.moduleName.str(),
2033+
external.macroTypeName.str(),
2034+
MD->getName()
2035+
).limitBehavior(DiagnosticBehavior::Warning);
2036+
}
2037+
2038+
break;
2039+
}
2040+
}
20072041
}
20082042

20092043
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {

lib/Sema/TypeCheckMacros.cpp

Lines changed: 5 additions & 3 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,13 +353,14 @@ 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
}
359361

360362
case MacroDefinition::Kind::External: {
361-
// Retrieve the extternal definition of the macro.
363+
// Retrieve the external definition of the macro.
362364
auto external = macroDef.getExternalMacro();
363365
ExternalMacroDefinitionRequest request{
364366
&ctx, external.moduleName, external.macroTypeName

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/macro_availability_macosx.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
@available(macOS 12.0, *)
55
struct X { }
66

7-
@expression macro m1: X = A.B // expected-error{{'X' is only available in macOS 12.0 or newer}}
7+
@expression macro m1: X = #externalMacro(module: "A", type: "B") // expected-error{{'X' is only available in macOS 12.0 or newer}}
8+
// expected-warning@-1{{external macro implementation type 'A.B' could not be found for macro 'm1'}}
89
910
@available(macOS 12.0, *)
10-
@expression macro m2: X = A.B
11+
@expression macro m2: X = #externalMacro(module: "A", type: "B")
12+
// expected-warning@-1{{external macro implementation type 'A.B' could not be found for macro 'm2'}}

test/Macros/macro_expand.swift

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

1919
@expression macro customFileID: String = #externalMacro(module: "MacroDefinition", type: "FileIDMacro")
2020
@expression macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
21-
@expression macro fileID<T: _ExpressibleByStringLiteral>: T = #externalMacro(module: "MacroDefinition", type: "FileIDMacro")
21+
@expression macro fileID<T: ExpressibleByStringLiteral>: T = #externalMacro(module: "MacroDefinition", type: "FileIDMacro")
2222
@expression macro recurse(_: Bool) = #externalMacro(module: "MacroDefinition", type: "RecursiveMacro")
2323

2424
func testFileID(a: Int, b: Int) {

0 commit comments

Comments
 (0)