Skip to content

Commit 9585582

Browse files
committed
[Sema] Assert we don't type-check bindings independently of closures
Bindings in closures must be type-checked together with the surrounding closure, add an assertion to make sure we don't try this. Carve out an exception for code completion which may still kick lazy type-checking on failure.
1 parent 84742d8 commit 9585582

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,22 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
841841
initializer, DC, patternType, pattern,
842842
/*bindPatternVarsOneWay=*/false);
843843

844+
// Bindings cannot be type-checked independently from their context in a
845+
// closure, make sure we don't ever attempt to do this. If we want to be able
846+
// to lazily type-check these we'll need to type-check the entire surrounding
847+
// expression.
848+
if (auto *CE = dyn_cast<ClosureExpr>(DC)) {
849+
if (!PBD || !isPlaceholderVar(PBD)) {
850+
// Completion may trigger lazy type-checking as part of fallback
851+
// unqualified lookup, just decline to type-check.
852+
if (CE->getASTContext().SourceMgr.hasIDEInspectionTargetBuffer()) {
853+
target.markInvalid();
854+
return true;
855+
}
856+
ABORT("Cannot type-check PatternBindingDecl without closure context");
857+
}
858+
}
859+
844860
// Type-check the initializer.
845861
auto resultTarget = typeCheckExpression(target, options);
846862

test/IDE/complete_unqualified_fallback.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %batch-code-completion
1+
// RUN: %batch-code-completion -solver-scope-threshold=50
22

33
protocol P0 {}
44
protocol P1 {}
@@ -47,8 +47,14 @@ S {
4747
S {
4848
S {
4949
S {
50+
let x = 0
5051
#^COMPLETE^#
51-
// COMPLETE: Decl[Struct]/CurrModule: FooBar[#FooBar#]; name=FooBar
52+
// COMPLETE-DAG: Decl[Struct]/CurrModule: FooBar[#FooBar#]; name=FooBar
53+
54+
// We decline to type-check a variable indepedently of the surrounding
55+
// closure, so this has an ErrorType. If this changes, you either need
56+
// to make this test case more complex or tweak the limits.
57+
// COMPLETE-DAG: Decl[LocalVar]/Local: x[#_#]; name=x
5258
}
5359
}
5460
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// {"kind":"typecheck","original":"22c204bc","signature":"swift::TypeChecker::typeCheckBinding(swift::Pattern*&, swift::Expr*&, swift::DeclContext*, swift::Type, swift::PatternBindingDecl*, unsigned int, swift::optionset::OptionSet<swift::TypeCheckExprFlags, unsigned int>)"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
struct a: ExpressibleByIntegerLiteral
4+
func *** (a , a )
5+
}
6+
{
7+
let b = 3 *** 4

0 commit comments

Comments
 (0)