Skip to content

Commit 55badd6

Browse files
authored
Merge pull request swiftlang#26223 from rjmccall/function-builder-locs
Fill in locs in implicit function builder exprs to satisfy code coverage
2 parents e5e469f + db4c7d2 commit 55badd6

File tree

3 files changed

+57
-12
lines changed

3 files changed

+57
-12
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,30 @@ class BuilderClosureVisitor
6060
// to get diagnostics if something about this builder call fails,
6161
// e.g. if there isn't a matching overload for `buildBlock`.
6262
// But we can only do this if there isn't a type variable in the type.
63-
TypeLoc typeLoc(nullptr,
64-
builderType->hasTypeVariable() ? Type() : builderType);
63+
TypeLoc typeLoc;
64+
if (!builderType->hasTypeVariable()) {
65+
typeLoc = TypeLoc(new (ctx) FixedTypeRepr(builderType, loc), builderType);
66+
}
6567

6668
auto typeExpr = new (ctx) TypeExpr(typeLoc);
6769
if (cs) {
6870
cs->setType(typeExpr, MetatypeType::get(builderType));
6971
cs->setType(&typeExpr->getTypeLoc(), builderType);
7072
}
7173

74+
SmallVector<SourceLoc, 4> argLabelLocs;
75+
for (auto i : indices(argLabels)) {
76+
argLabelLocs.push_back(args[i]->getStartLoc());
77+
}
78+
7279
typeExpr->setImplicit();
7380
auto memberRef = new (ctx) UnresolvedDotExpr(
7481
typeExpr, loc, fnName, DeclNameLoc(loc), /*implicit=*/true);
75-
return CallExpr::createImplicit(ctx, memberRef, args, argLabels);
82+
SourceLoc openLoc = args.empty() ? loc : args.front()->getStartLoc();
83+
SourceLoc closeLoc = args.empty() ? loc : args.back()->getEndLoc();
84+
return CallExpr::create(ctx, memberRef, openLoc, args,
85+
argLabels, argLabelLocs, closeLoc,
86+
/*trailing closure*/ nullptr, /*implicit*/true);
7687
}
7788

7889
/// Check whether the builder supports the given operation.
@@ -400,18 +411,21 @@ class BuilderClosureVisitor
400411
auto optionalDecl = ctx.getOptionalDecl();
401412
auto optionalType = optionalDecl->getDeclaredType();
402413

403-
auto optionalTypeExpr = TypeExpr::createImplicit(optionalType, ctx);
414+
auto loc = arg->getStartLoc();
415+
auto optionalTypeExpr =
416+
TypeExpr::createImplicitHack(loc, optionalType, ctx);
404417
auto someRef = new (ctx) UnresolvedDotExpr(
405-
optionalTypeExpr, SourceLoc(), ctx.getIdentifier("some"),
406-
DeclNameLoc(), /*implicit=*/true);
418+
optionalTypeExpr, loc, ctx.getIdentifier("some"),
419+
DeclNameLoc(loc), /*implicit=*/true);
407420
return CallExpr::createImplicit(ctx, someRef, arg, { });
408421
}
409422

410423
Expr *buildNoneExpr(SourceLoc endLoc) {
411424
auto optionalDecl = ctx.getOptionalDecl();
412425
auto optionalType = optionalDecl->getDeclaredType();
413426

414-
auto optionalTypeExpr = TypeExpr::createImplicit(optionalType, ctx);
427+
auto optionalTypeExpr =
428+
TypeExpr::createImplicitHack(endLoc, optionalType, ctx);
415429
return new (ctx) UnresolvedDotExpr(
416430
optionalTypeExpr, endLoc, ctx.getIdentifier("none"),
417431
DeclNameLoc(endLoc), /*implicit=*/true);
@@ -492,7 +506,9 @@ TypeChecker::applyFunctionBuilderBodyTransform(FuncDecl *FD,
492506
if (!returnType || returnType->hasError())
493507
return nullptr;
494508

495-
auto returnStmt = new (Context) ReturnStmt(SourceLoc(), returnExpr);
509+
auto loc = returnExpr->getStartLoc();
510+
auto returnStmt =
511+
new (Context) ReturnStmt(loc, returnExpr, /*implicit*/ true);
496512
return BraceStmt::create(Context, body->getLBraceLoc(), { returnStmt },
497513
body->getRBraceLoc());
498514
}

test/IDE/complete_function_builder.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_CLOSURE_COLOR_CONTEXT | %FileCheck %s -check-prefix=IN_CLOSURE_COLOR_CONTEXT
44
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_CLOSURE_COLOR_CONTEXT_DOT | %FileCheck %s -check-prefix=IN_CLOSURE_COLOR_CONTEXT_DOT
55

6-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_1 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_INVALID
7-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_2 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_INVALID
6+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_1 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
7+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_2 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
88
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_3 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
99
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_4 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
1010
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_5 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_INVALID
@@ -123,11 +123,9 @@ func acceptBuilder(@EnumToVoidBuilder body: () -> Void) {}
123123

124124
func testContextualType() {
125125
acceptBuilder {
126-
// FIXME: This should suggest enum values.
127126
.#^CONTEXTUAL_TYPE_1^#
128127
}
129128
acceptBuilder {
130-
// FIXME: This should suggest enum values.
131129
.#^CONTEXTUAL_TYPE_2^#;
132130
.north;
133131
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_functon_builder %s | %FileCheck %s
2+
3+
@_functionBuilder
4+
struct Summer {
5+
static func buildBlock(_ x: Int...) -> Int {
6+
return x.reduce(0, +)
7+
}
8+
static func buildIf(_ x: Int?) -> Int {
9+
return x ?? 0
10+
}
11+
}
12+
13+
// CHECK-LABEL: sil_coverage_map {{.*}} "$s24coverage_functon_builder5test0SiyF"
14+
@Summer
15+
func test0() -> Int {
16+
// CHECK: [[@LINE-1]]:21 -> [[@LINE+3]]:2 : 0
17+
18
18+
12
19+
}
20+
21+
// CHECK-LABEL: sil_coverage_map {{.*}} "$s24coverage_functon_builder5test1SiyF"
22+
@Summer
23+
func test1() -> Int {
24+
// CHECK: [[@LINE-1]]:21 -> [[@LINE+7]]:2 : 0
25+
18
26+
12
27+
if 7 < 23 {
28+
11
29+
8
30+
}
31+
}

0 commit comments

Comments
 (0)