Skip to content

Commit 45a8f60

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents a895020 + da45b8d commit 45a8f60

File tree

7 files changed

+65
-5
lines changed

7 files changed

+65
-5
lines changed

include/swift/Sema/IDETypeChecking.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ namespace swift {
3939
/// Typecheck a declaration parsed during code completion.
4040
void typeCheckCompletionDecl(Decl *D);
4141

42+
/// Typecheck binding initializer at \p bindingIndex.
43+
void typeCheckPatternBinding(PatternBindingDecl *PBD, unsigned bindingIndex);
44+
4245
/// Check if T1 is convertible to T2.
4346
///
4447
/// \returns true on convertible, false on not.

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,27 @@ void typeCheckContextImpl(DeclContext *DC, SourceLoc Loc) {
9393
// Type-check this context.
9494
switch (DC->getContextKind()) {
9595
case DeclContextKind::AbstractClosureExpr:
96-
case DeclContextKind::Initializer:
9796
case DeclContextKind::Module:
9897
case DeclContextKind::SerializedLocal:
9998
case DeclContextKind::TopLevelCodeDecl:
10099
case DeclContextKind::EnumElementDecl:
101100
// Nothing to do for these.
102101
break;
103102

103+
case DeclContextKind::Initializer:
104+
if (auto *patternInit = dyn_cast<PatternBindingInitializer>(DC)) {
105+
auto *PBD = patternInit->getBinding();
106+
auto i = patternInit->getBindingIndex();
107+
if (PBD->getInit(i)) {
108+
PBD->getPattern(i)->forEachVariable([](VarDecl *VD) {
109+
typeCheckCompletionDecl(VD);
110+
});
111+
if (!PBD->isInitializerChecked(i))
112+
typeCheckPatternBinding(PBD, i);
113+
}
114+
}
115+
break;
116+
104117
case DeclContextKind::AbstractFunctionDecl: {
105118
auto *AFD = cast<AbstractFunctionDecl>(DC);
106119

lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2802,6 +2802,8 @@ Parser::parseDecl(ParseDeclOptions Flags,
28022802
StaticSpelling, tryLoc);
28032803
StaticLoc = SourceLoc(); // we handled static if present.
28042804
MayNeedOverrideCompletion = true;
2805+
if (DeclResult.hasCodeCompletion() && isCodeCompletionFirstPass())
2806+
break;
28052807
std::for_each(Entries.begin(), Entries.end(), Handler);
28062808
if (auto *D = DeclResult.getPtrOrNull())
28072809
markWasHandled(D);
@@ -2824,6 +2826,8 @@ Parser::parseDecl(ParseDeclOptions Flags,
28242826
llvm::SmallVector<Decl *, 4> Entries;
28252827
DeclParsingContext.setCreateSyntax(SyntaxKind::EnumCaseDecl);
28262828
DeclResult = parseDeclEnumCase(Flags, Attributes, Entries);
2829+
if (DeclResult.hasCodeCompletion() && isCodeCompletionFirstPass())
2830+
break;
28272831
std::for_each(Entries.begin(), Entries.end(), Handler);
28282832
if (auto *D = DeclResult.getPtrOrNull())
28292833
markWasHandled(D);
@@ -2873,6 +2877,8 @@ Parser::parseDecl(ParseDeclOptions Flags,
28732877
}
28742878
llvm::SmallVector<Decl *, 4> Entries;
28752879
DeclResult = parseDeclSubscript(Flags, Attributes, Entries);
2880+
if (DeclResult.hasCodeCompletion() && isCodeCompletionFirstPass())
2881+
break;
28762882
std::for_each(Entries.begin(), Entries.end(), Handler);
28772883
MayNeedOverrideCompletion = true;
28782884
if (auto *D = DeclResult.getPtrOrNull())
@@ -2995,7 +3001,8 @@ Parser::parseDecl(ParseDeclOptions Flags,
29953001
}
29963002

29973003
if (DeclResult.hasCodeCompletion() && isCodeCompletionFirstPass() &&
2998-
!CurDeclContext->isModuleScopeContext()) {
3004+
!CurDeclContext->isModuleScopeContext() &&
3005+
!isa<TopLevelCodeDecl>(CurDeclContext)) {
29993006
// Only consume non-toplevel decls.
30003007
consumeDecl(BeginParserPosition, Flags, /*IsTopLevel=*/false);
30013008

lib/Parse/ParseStmt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
405405
ParserResult<Decl> DeclResult =
406406
parseDecl(IsTopLevel ? PD_AllowTopLevel : PD_Default,
407407
[&](Decl *D) {TmpDecls.push_back(D);});
408+
BraceItemsStatus |= DeclResult;
408409
if (DeclResult.isParseError()) {
409410
NeedParseErrorRecovery = true;
410411
if (DeclResult.hasCodeCompletion() && IsTopLevel &&
@@ -429,6 +430,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
429430
}
430431

431432
ParserStatus Status = parseExprOrStmt(Result);
433+
BraceItemsStatus |= Status;
432434
if (Status.hasCodeCompletion() && isCodeCompletionFirstPass()) {
433435
consumeTopLevelDecl(BeginParserPosition, TLCD);
434436
auto Brace = BraceStmt::create(Context, StartLoc, {}, PreviousLoc);
@@ -461,6 +463,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
461463
diagnose(StartLoc, diag::invalid_nested_init, isSelf)
462464
.fixItInsert(StartLoc, isSelf ? "self." : "super.");
463465
NeedParseErrorRecovery = true;
466+
BraceItemsStatus.setIsParseError();
464467
} else {
465468
ParserStatus ExprOrStmtStatus = parseExprOrStmt(Result);
466469
BraceItemsStatus |= ExprOrStmtStatus;

lib/Sema/TypeChecker.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,17 @@ void swift::typeCheckCompletionDecl(Decl *D) {
645645
TC.validateDecl(cast<ValueDecl>(D));
646646
}
647647

648+
void swift::typeCheckPatternBinding(PatternBindingDecl *PBD,
649+
unsigned bindingIndex) {
650+
assert(!PBD->isInitializerChecked(bindingIndex) &&
651+
PBD->getInit(bindingIndex));
652+
653+
auto &Ctx = PBD->getASTContext();
654+
DiagnosticSuppression suppression(Ctx.Diags);
655+
TypeChecker &TC = createTypeChecker(Ctx);
656+
TC.typeCheckPatternBinding(PBD, bindingIndex);
657+
}
658+
648659
static Optional<Type> getTypeOfCompletionContextExpr(
649660
TypeChecker &TC,
650661
DeclContext *DC,

test/IDE/complete_value_expr.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@
190190
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOLTYPE_DOT_2 | %FileCheck %s -check-prefix=PROTOCOLTYPE_DOT_2
191191
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOLTYPE_DOT_3 | %FileCheck %s -check-prefix=PROTOCOLTYPE_DOT_3
192192

193+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLOSURE_IN_MEMBERDECLINIT_1 | %FileCheck %s -check-prefix=FOO_OBJECT_DOT
194+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLOSURE_IN_MEMBERDECLINIT_2 | %FileCheck %s -check-prefix=FOO_OBJECT_DOT
195+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLOSURE_IN_MEMBERDECLINIT_3 | %FileCheck %s -check-prefix=FOO_OBJECT_DOT
196+
193197
// Test code completion of expressions that produce a value.
194198

195199
struct FooStruct {
@@ -2119,3 +2123,22 @@ class TestChain {
21192123
// COMPLEX_CHAIN_1: End completions
21202124
}
21212125
}
2126+
2127+
// rdar://problem/48453760
2128+
struct InitializerTest {
2129+
let value1: FooStruct = {
2130+
$0.#^CLOSURE_IN_MEMBERDECLINIT_1^#
2131+
return $0
2132+
}(FooStruct())
2133+
2134+
let value2: FooStruct = { (b: FooStruct ) -> FooStruct in
2135+
b.#^CLOSURE_IN_MEMBERDECLINIT_2^#
2136+
return b
2137+
}(FooStruct())
2138+
}
2139+
// rdar://problem/40944761
2140+
extension String {
2141+
static let v = { (obj: FooStruct) in
2142+
obj.#^CLOSURE_IN_MEMBERDECLINIT_3^#
2143+
}
2144+
}

test/Parse/recovery.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -622,9 +622,9 @@ func foo2(bar! = baz) {}// expected-note {{did you mean 'foo2'?}}
622622
// expected-error@+1{{use of unresolved identifier 'esp'; did you mean 'test'?}}
623623
switch esp {
624624
case let (jeb):
625-
// expected-error@+5{{operator with postfix spacing cannot start a subexpression}}
626-
// expected-error@+4{{consecutive statements on a line must be separated by ';'}} {{15-15=;}}
627-
// expected-error@+3{{'>' is not a prefix unary operator}}
625+
// expected-error@+5{{top-level statement cannot begin with a closure expression}}
626+
// expected-error@+4{{closure expression is unused}}
627+
// expected-note@+3{{did you mean to use a 'do' statement?}}
628628
// expected-error@+2{{expected an identifier to name generic parameter}}
629629
// expected-error@+1{{expected '{' in class}}
630630
class Ceac<}> {}

0 commit comments

Comments
 (0)