Skip to content

Commit 44e8004

Browse files
committed
[CSGen] Allow _ pattern to be a hole
In cases like `case .test(_)` it might not be possible to establish a type of `_` and hole cannot be propagated to it from context if condition of switch is incorrect, so `_` just like a named pattern should be allowed to become a hole. Resolves: rdar://96997534
1 parent 9fad8b1 commit 44e8004

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

lib/Sema/CSGen.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,11 +2290,18 @@ namespace {
22902290
return setType(type);
22912291
}
22922292
case PatternKind::Any: {
2293-
return setType(
2294-
externalPatternType
2295-
? externalPatternType
2296-
: CS.createTypeVariable(CS.getConstraintLocator(locator),
2297-
TVO_CanBindToNoEscape));
2293+
Type type;
2294+
2295+
// Always prefer a contextual type when it's available.
2296+
if (externalPatternType) {
2297+
type = externalPatternType;
2298+
} else {
2299+
type = CS.createTypeVariable(
2300+
CS.getConstraintLocator(pattern,
2301+
ConstraintLocator::AnyPatternDecl),
2302+
TVO_CanBindToNoEscape | TVO_CanBindToHole);
2303+
}
2304+
return setType(type);
22982305
}
22992306

23002307
case PatternKind::Named: {

test/Constraints/result_builder_diags.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,3 +855,40 @@ func test_invalid_result_is_diagnosed() {
855855
S<Int>()
856856
}
857857
}
858+
859+
func test_associated_values_dont_block_solver_when_unresolved() {
860+
@resultBuilder
861+
struct Builder {
862+
static func buildBlock<T>(_ t: T) -> T { t }
863+
static func buildEither<T>(first: T) -> T { first }
864+
static func buildEither<T>(second: T) -> T { second }
865+
}
866+
867+
struct Value {
868+
enum Kind {
869+
case a(String)
870+
case b
871+
}
872+
873+
var kind: Kind
874+
}
875+
876+
struct Container {
877+
var prop: Value? = nil
878+
}
879+
880+
struct TestWithAny {
881+
var container: Container
882+
883+
@Builder var body: String {
884+
let v = container.prop.kind // expected-error {{value of optional type 'Value?' must be unwrapped to refer to member 'kind' of wrapped base type 'Value'}}
885+
// expected-note@-1 {{chain the optional using '?' to access member 'kind' only for non-'nil' base values}}
886+
// expected-note@-2 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
887+
888+
switch v.kind { // expected-error {{value of type 'Value.Kind' has no member 'kind'}}
889+
case .a(_): "a"
890+
case .b: "b"
891+
}
892+
}
893+
}
894+
}

0 commit comments

Comments
 (0)