Skip to content

Commit 68d22b0

Browse files
committed
[CS] Eagerly bind hole in recordInvalidNode
We know this is where the issue is so we can immediately bind to a hole, ensuring we don't produce unnecessary downstream diagnostics from things we can't infer.
1 parent a8e2fba commit 68d22b0

12 files changed

+29
-18
lines changed

lib/Sema/CSGen.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,14 +1308,17 @@ namespace {
13081308
CS.setType(expr, expansionType);
13091309
}
13101310

1311-
/// Records a fix for an invalid AST node, and returns a potential hole
1312-
/// type variable for it.
1311+
/// Records a fix for an invalid AST node, and returns a hole for it.
13131312
Type recordInvalidNode(ASTNode node) {
13141313
CS.recordFix(
13151314
IgnoreInvalidASTNode::create(CS, CS.getConstraintLocator(node)));
13161315

1317-
return CS.createTypeVariable(CS.getConstraintLocator(node),
1318-
TVO_CanBindToHole);
1316+
// Ideally we wouldn't need a type variable here, but we don't have a
1317+
// suitable placeholder originator for all the cases here.
1318+
auto ty = CS.createTypeVariable(CS.getConstraintLocator(node),
1319+
TVO_CanBindToHole);
1320+
CS.recordTypeVariablesAsHoles(ty);
1321+
return ty;
13191322
}
13201323

13211324
virtual Type visitErrorExpr(ErrorExpr *E) {

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6694,6 +6694,10 @@ bool ConstraintSystem::repairFailures(
66946694
}
66956695

66966696
case ConstraintLocator::Condition: {
6697+
// If the condition is already a hole, we're done.
6698+
if (lhs->isPlaceholder())
6699+
return true;
6700+
66976701
if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes,
66986702
locator))
66996703
return true;

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3581,12 +3581,13 @@ void constraints::simplifyLocator(ASTNode &anchor,
35813581
}
35823582
case ConstraintLocator::AutoclosureResult:
35833583
case ConstraintLocator::LValueConversion:
3584+
case ConstraintLocator::OptionalInjection:
35843585
case ConstraintLocator::DynamicType:
35853586
case ConstraintLocator::UnresolvedMember:
35863587
case ConstraintLocator::ImplicitCallAsFunction:
35873588
// Arguments in autoclosure positions, lvalue and rvalue adjustments,
3588-
// unresolved members, and implicit callAsFunction references are
3589-
// implicit.
3589+
// optional injections, unresolved members, and implicit callAsFunction
3590+
// references are implicit.
35903591
path = path.slice(1);
35913592
continue;
35923593

@@ -3913,7 +3914,6 @@ void constraints::simplifyLocator(ASTNode &anchor,
39133914

39143915
case ConstraintLocator::Witness:
39153916
case ConstraintLocator::WrappedValue:
3916-
case ConstraintLocator::OptionalInjection:
39173917
case ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice:
39183918
case ConstraintLocator::FallbackType:
39193919
case ConstraintLocator::KeyPathSubscriptIndex:

test/Constraints/ternary_expr.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ _ = true ? x : 1.2 // expected-error {{result values in '? :' expression have mi
5959
_ = (x: true) ? true : false // expected-error {{cannot convert value of type '(x: Bool)' to expected condition type 'Bool'}}
6060
_ = (x: 1) ? true : false // expected-error {{cannot convert value of type '(x: Int)' to expected condition type 'Bool'}}
6161

62+
_ = undefined ? 0 : 1 // expected-error {{cannot find 'undefined' in scope}}
63+
_ = [undefined] ? 0 : 1 // expected-error {{cannot find 'undefined' in scope}}
64+
// expected-error@-1 {{cannot convert value of type '[Element]' to expected condition type 'Bool'}}
65+
6266
func resultBool() -> Bool { true }
6367
_ = resultBool ? true : false // expected-error {{function 'resultBool' was used as a property; add () to call it}} {{15-15=()}}
6468

test/Parse/subscripting.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ struct A6 {
179179
// expected-note@-2 {{did you mean}}
180180
get {
181181
return i + j // expected-error {{cannot find 'j' in scope}}
182-
// expected-error@-1 {{cannot convert return expression of type 'Int' to return type '(Int) -> Int'}}
183182
}
184183
}
185184
}

test/stmt/statements.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,9 @@ func bad_if() {
560560
if (x: false) {} // expected-error {{cannot convert value of type '(x: Bool)' to expected condition type 'Bool'}}
561561
if (x: 1) {} // expected-error {{cannot convert value of type '(x: Int)' to expected condition type 'Bool'}}
562562
if nil {} // expected-error {{'nil' is not compatible with expected condition type 'Bool'}}
563+
if undefined {} // expected-error {{cannot find 'undefined' in scope}}
564+
if [undefined] {} // expected-error {{cannot find 'undefined' in scope}}
565+
// expected-error@-1 {{cannot convert value of type '[Element]' to expected condition type 'Bool'}}
563566
}
564567

565568
// Typo correction for loop labels

test/type/protocol_composition.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,9 @@ takesP1AndP2([AnyObject & P1 & P2]())
191191
takesP1AndP2([Swift.AnyObject & P1 & P2]())
192192
takesP1AndP2([AnyObject & protocol_composition.P1 & P2]())
193193
takesP1AndP2([AnyObject & P1 & protocol_composition.P2]())
194-
takesP1AndP2([DoesNotExist & P1 & P2]()) // expected-error {{cannot find 'DoesNotExist' in scope}}
195-
// expected-error@-1 {{binary operator '&' cannot be applied to operands of type 'UInt8' and '(any P2).Type'}}
196-
// expected-error@-2 {{binary operator '&' cannot be applied to operands of type 'UInt8' and '(any P1).Type'}}
197-
// expected-note@-3 2 {{overloads for '&' exist with these partially matching parameter lists}}
198-
// expected-error@-4 {{cannot call value of non-function type '[UInt8]'}}
194+
takesP1AndP2([DoesNotExist & P1 & P2]())
195+
// expected-error@-1 {{cannot find 'DoesNotExist' in scope}}
196+
// expected-error@-2 {{cannot call value of non-function type '[Element]'}}
199197
takesP1AndP2([Swift.DoesNotExist & P1 & P2]())
200198
// expected-error@-1 {{module 'Swift' has no member named 'DoesNotExist'}}
201199
// expected-error@-2 {{cannot call value of non-function type '[Element]'}}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// {"kind":"typecheck","signature":"(anonymous namespace)::ConnectedComponents::unionSets(swift::TypeVariableType*, swift::TypeVariableType*)","signatureAssert":"Assertion failed: (validComponentCount > 0), function unionSets"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
let b = ( c , d a {
44
e b
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// {"kind":"typecheck","signature":"swift::constraints::ConstraintGraph::computeConnectedComponents(llvm::ArrayRef<swift::TypeVariableType*>)","signatureAssert":"Assertion failed: (component != components.end()), function operator()"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
let i = Array(... a { " ? \(i Array* )" }
44
, b 1

validation-test/compiler_crashers/ConstraintWalker-walkToExprPost-c956e0.swift renamed to validation-test/compiler_crashers_fixed/ConstraintWalker-walkToExprPost-c956e0.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"typecheck","original":"1562769e","signature":"(anonymous namespace)::ConstraintWalker::walkToExprPost(swift::Expr*)"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
enum c
44
func d() e {
55
if let

0 commit comments

Comments
 (0)