Skip to content

Commit fa3059e

Browse files
authored
Merge pull request #64302 from DougGregor/external-macro-without-decl
[Macros] Don't require a declaration of `#externalMacro`.
2 parents 31435b2 + 5d5a668 commit fa3059e

File tree

3 files changed

+96
-13
lines changed

3 files changed

+96
-13
lines changed

lib/Sema/TypeCheckMacros.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,24 @@ Optional<Identifier> getIdentifierFromStringLiteralArgument(
230230
return ctx.getIdentifier(contents);
231231
}
232232

233+
/// For a macro expansion expression that is known to be #externalMacro,
234+
/// handle the definition.
235+
static MacroDefinition handleExternalMacroDefinition(
236+
ASTContext &ctx, MacroExpansionExpr *expansion) {
237+
// Dig out the module and type name.
238+
auto moduleName = getIdentifierFromStringLiteralArgument(ctx, expansion, 0);
239+
if (!moduleName) {
240+
return MacroDefinition::forInvalid();
241+
}
242+
243+
auto typeName = getIdentifierFromStringLiteralArgument(ctx, expansion, 1);
244+
if (!typeName) {
245+
return MacroDefinition::forInvalid();
246+
}
247+
248+
return MacroDefinition::forExternal(*moduleName, *typeName);
249+
}
250+
233251
MacroDefinition MacroDefinitionRequest::evaluate(
234252
Evaluator &evaluator, MacroDecl *macro
235253
) const {
@@ -258,6 +276,14 @@ MacroDefinition MacroDefinitionRequest::evaluate(
258276
return MacroDefinition::forInvalid();
259277
}
260278

279+
// Handle #externalMacro without requiring a declaration at all.
280+
// Note: this is a workaround to allow newer compilers to work with
281+
// older standard libraries.
282+
if (expansion->getMacroName().getBaseName().userFacingName() ==
283+
"externalMacro") {
284+
return handleExternalMacroDefinition(ctx, expansion);
285+
}
286+
261287
// Type-check the macro expansion.
262288
Type resultType = macro->mapTypeIntoContext(macro->getResultInterfaceType());
263289

@@ -290,18 +316,7 @@ MacroDefinition MacroDefinitionRequest::evaluate(
290316
return MacroDefinition::forInvalid();
291317
}
292318

293-
// Dig out the module and type name.
294-
auto moduleName = getIdentifierFromStringLiteralArgument(ctx, expansion, 0);
295-
if (!moduleName) {
296-
return MacroDefinition::forInvalid();
297-
}
298-
299-
auto typeName = getIdentifierFromStringLiteralArgument(ctx, expansion, 1);
300-
if (!typeName) {
301-
return MacroDefinition::forInvalid();
302-
}
303-
304-
return MacroDefinition::forExternal(*moduleName, *typeName);
319+
return handleExternalMacroDefinition(ctx, expansion);
305320
}
306321

307322
/// Load a plugin library based on a module name.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -module-name Swift -parse-stdlib
2+
3+
// expected-warning@+2{{@expression has been removed in favor of @freestanding(expression)}}
4+
// expected-warning@+1{{external macro implementation type 'A.B' could not be found for macro 'myMacro()'; the type must be public and provided via '-load-plugin-library'}}
5+
@expression macro myMacro() = #externalMacro(module: "A", type: "B")
6+
7+
// Protocols needed for string literals to work
8+
public protocol ExpressibleByUnicodeScalarLiteral {
9+
associatedtype UnicodeScalarLiteralType: _ExpressibleByBuiltinUnicodeScalarLiteral
10+
11+
init(unicodeScalarLiteral value: UnicodeScalarLiteralType)
12+
}
13+
14+
public protocol _ExpressibleByBuiltinExtendedGraphemeClusterLiteral
15+
: _ExpressibleByBuiltinUnicodeScalarLiteral {
16+
17+
init(
18+
_builtinExtendedGraphemeClusterLiteral start: Builtin.RawPointer,
19+
utf8CodeUnitCount: Builtin.Word,
20+
isASCII: Builtin.Int1)
21+
}
22+
23+
public protocol ExpressibleByExtendedGraphemeClusterLiteral
24+
: ExpressibleByUnicodeScalarLiteral {
25+
26+
associatedtype ExtendedGraphemeClusterLiteralType
27+
: _ExpressibleByBuiltinExtendedGraphemeClusterLiteral
28+
29+
init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType)
30+
}
31+
32+
extension ExpressibleByExtendedGraphemeClusterLiteral
33+
where ExtendedGraphemeClusterLiteralType == UnicodeScalarLiteralType {
34+
35+
@_transparent
36+
public init(unicodeScalarLiteral value: ExtendedGraphemeClusterLiteralType) {
37+
self.init(extendedGraphemeClusterLiteral: value)
38+
}
39+
}
40+
41+
public protocol _ExpressibleByBuiltinStringLiteral
42+
: _ExpressibleByBuiltinExtendedGraphemeClusterLiteral {
43+
44+
init(
45+
_builtinStringLiteral start: Builtin.RawPointer,
46+
utf8CodeUnitCount: Builtin.Word,
47+
isASCII: Builtin.Int1)
48+
}
49+
50+
public protocol ExpressibleByStringLiteral
51+
: ExpressibleByExtendedGraphemeClusterLiteral {
52+
associatedtype StringLiteralType: _ExpressibleByBuiltinStringLiteral
53+
54+
init(stringLiteral value: StringLiteralType)
55+
}
56+
57+
extension ExpressibleByStringLiteral
58+
where StringLiteralType == ExtendedGraphemeClusterLiteralType {
59+
60+
@_transparent
61+
public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
62+
self.init(stringLiteral: value)
63+
}
64+
}
65+
66+
public protocol _ExpressibleByBuiltinUnicodeScalarLiteral {
67+
init(_builtinUnicodeScalarLiteral value: Builtin.Int32)
68+
}

test/Macros/macros_diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ protocol P { }
1414

1515
@freestanding(expression) macro tryToHide<T: P>(_: T) -> some P = #externalMacro(module: "BuiltinMacros", type: "Blah")
1616
// expected-error@-1{{some' types are only permitted in properties, subscripts, and functions}}
17-
// expected-error@-2{{generic parameter 'T' could not be inferred}}
17+
// expected-warning@-2{{external macro implementation type}}
1818

1919
internal struct X { } // expected-note{{type declared here}}
2020

0 commit comments

Comments
 (0)