Skip to content

Commit b14dc22

Browse files
authored
Merge pull request #84855 from hamishknight/loc-ness-monster
[Parse] Avoid setting closure `in` SourceLoc if missing
2 parents 70d9add + b83cf1e commit b14dc22

File tree

6 files changed

+45
-9
lines changed

6 files changed

+45
-9
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2897,7 +2897,6 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
28972897
diagnose(Tok, diag::expected_closure_in)
28982898
.fixItInsert(Tok.getLoc(), "in ");
28992899
}
2900-
inLoc = Tok.getLoc();
29012900
}
29022901
}
29032902

lib/Sema/TypeCheckMacros.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -977,14 +977,14 @@ static CharSourceRange getExpansionInsertionRange(MacroRole role,
977977
if (auto *expr = target.dyn_cast<Expr *>()) {
978978
ASSERT(isa<ClosureExpr>(expr));
979979

980-
auto *closure = cast<ClosureExpr>(expr);
981980
// A closure body macro expansion replaces the full source
982-
// range of the closure body starting from `in` and ending right
983-
// before the closing brace.
984-
return Lexer::getCharSourceRangeFromSourceRange(
985-
sourceMgr, SourceRange(Lexer::getLocForEndOfToken(
986-
sourceMgr, closure->getInLoc()),
987-
closure->getEndLoc()));
981+
// range of the closure body's contents.
982+
auto *closure = cast<ClosureExpr>(expr);
983+
if (auto range = closure->getBody()->getContentRange())
984+
return Lexer::getCharSourceRangeFromSourceRange(sourceMgr, range);
985+
986+
// If we have an empty body, just use the end loc.
987+
return CharSourceRange(closure->getEndLoc(), 0);
988988
}
989989

990990
// If the function has a body, that's what's being replaced.

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,6 +2725,24 @@ struct ThrowCancellationMacro: BodyMacro {
27252725
}
27262726
}
27272727

2728+
struct EmptyBodyMacro: BodyMacro {
2729+
static func expansion(
2730+
of node: AttributeSyntax,
2731+
providingBodyFor declaration: some DeclSyntaxProtocol & WithOptionalCodeBlockSyntax,
2732+
in context: some MacroExpansionContext
2733+
) throws -> [CodeBlockItemSyntax] {
2734+
[]
2735+
}
2736+
2737+
static func expansion(
2738+
of node: AttributeSyntax,
2739+
providingBodyFor closure: ClosureExprSyntax,
2740+
in context: some MacroExpansionContext
2741+
) throws -> [CodeBlockItemSyntax] {
2742+
[]
2743+
}
2744+
}
2745+
27282746
@_spi(ExperimentalLanguageFeature)
27292747
public struct TracedPreambleMacro: PreambleMacro {
27302748
public static func expansion(
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// REQUIRES: swift_swift_parser
2+
// REQUIRES: swift_feature_ClosureBodyMacro
3+
4+
// RUN: %empty-directory(%t)
5+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath -swift-version 5
6+
7+
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -enable-experimental-feature ClosureBodyMacro
8+
9+
@attached(body)
10+
macro Empty() = #externalMacro(module: "MacroDefinition", type: "EmptyBodyMacro")
11+
12+
// Make sure we can handle the lack of 'in' here.
13+
_ = { @Empty x -> // expected-error {{cannot infer type of closure parameter 'x' without a type annotation}}
14+
0 // expected-error {{expected closure result type after '->'}} expected-error {{expected 'in' after the closure signature}}
15+
}
16+
17+
_ = { @Empty in }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// RUN: %target-swift-ide-test -code-completion -batch-code-completion -skip-filecheck -code-completion-diagnostics -source-filename %s
2+
{ k -> #^^#
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// {"kind":"typecheck","signature":"swift::ast_scope::ASTScopeImpl::checkSourceRangeBeforeAddingChild(swift::ast_scope::ASTScopeImpl*, swift::ASTContext const&) const","signatureAssert":"Assertion failed: ((SM.isBefore(range.Start, range.End) || range.Start == range.End) && \"scope source range ends before start\"), function getCharSourceRangeOfScope"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
{
44
@in

0 commit comments

Comments
 (0)