Skip to content

Commit a4fbb3e

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 ac89df5 commit a4fbb3e

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
@@ -2286,11 +2286,18 @@ namespace {
22862286
return setType(type);
22872287
}
22882288
case PatternKind::Any: {
2289-
return setType(
2290-
externalPatternType
2291-
? externalPatternType
2292-
: CS.createTypeVariable(CS.getConstraintLocator(locator),
2293-
TVO_CanBindToNoEscape));
2289+
Type type;
2290+
2291+
// Always prefer a contextual type when it's available.
2292+
if (externalPatternType) {
2293+
type = externalPatternType;
2294+
} else {
2295+
type = CS.createTypeVariable(
2296+
CS.getConstraintLocator(pattern,
2297+
ConstraintLocator::AnyPatternDecl),
2298+
TVO_CanBindToNoEscape | TVO_CanBindToHole);
2299+
}
2300+
return setType(type);
22942301
}
22952302

22962303
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)