File tree Expand file tree Collapse file tree 4 files changed +57
-2
lines changed Expand file tree Collapse file tree 4 files changed +57
-2
lines changed Original file line number Diff line number Diff line change @@ -1950,8 +1950,10 @@ bool ContextualFailure::diagnoseConversionToNil() const {
1950
1950
}
1951
1951
1952
1952
// `nil` is passed as an argument to a parameter which doesn't
1953
- // expect it e.g. `foo(a: nil)` or `s[x: nil]`.
1954
- if (isa<ApplyExpr>(enclosingExpr) || isa<SubscriptExpr>(enclosingExpr))
1953
+ // expect it e.g. `foo(a: nil)` or `s[x: nil]` or \S.[x: nil].
1954
+ // FIXME: Find a more robust way of checking this.
1955
+ if (isa<ApplyExpr>(enclosingExpr) || isa<SubscriptExpr>(enclosingExpr) ||
1956
+ isa<KeyPathExpr>(enclosingExpr))
1955
1957
CTP = CTP_CallArgument;
1956
1958
} else if (auto *CE = dyn_cast<CoerceExpr>(parentExpr)) {
1957
1959
// `nil` is passed as a left-hand side of the coercion
Original file line number Diff line number Diff line change @@ -2911,6 +2911,26 @@ void constraints::simplifyLocator(Expr *&anchor,
2911
2911
path = path.slice (1 );
2912
2912
continue ;
2913
2913
2914
+ case ConstraintLocator::KeyPathComponent: {
2915
+ auto elt = path[0 ].castTo <LocatorPathElt::KeyPathComponent>();
2916
+
2917
+ // If the next element is an ApplyArgument, we can simplify by looking
2918
+ // into the index expression.
2919
+ if (path.size () < 2 ||
2920
+ path[1 ].getKind () != ConstraintLocator::ApplyArgument)
2921
+ break ;
2922
+
2923
+ if (auto *kpe = dyn_cast<KeyPathExpr>(anchor)) {
2924
+ auto component = kpe->getComponents ()[elt.getIndex ()];
2925
+ auto indexExpr = component.getIndexExpr ();
2926
+ assert (indexExpr && " Trying to apply a component without an index?" );
2927
+ anchor = indexExpr;
2928
+ path = path.slice (2 );
2929
+ continue ;
2930
+ }
2931
+ break ;
2932
+ }
2933
+
2914
2934
default :
2915
2935
// FIXME: Lots of other cases to handle.
2916
2936
break ;
Original file line number Diff line number Diff line change @@ -321,3 +321,18 @@ func test_explicit_call_with_overloads() {
321
321
foo ( S ( ) . foo)
322
322
// expected-error@-1 {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{14-14=()}}
323
323
}
324
+
325
+ // SR-11476
326
+ func testKeyPathSubscriptArgFixes( _ fn: @escaping ( ) -> Int ) {
327
+ struct S {
328
+ subscript( x: Int ) -> Int { x }
329
+ }
330
+
331
+ var i : Int ?
332
+ _ = \S . [ i] // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
333
+ // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{12-12= ?? <#default value#>}}
334
+ // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{12-12=!}}
335
+
336
+ _ = \S . [ nil ] // expected-error {{'nil' is not compatible with expected argument type 'Int'}}
337
+ _ = \S . [ fn] // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{13-13=()}}
338
+ }
Original file line number Diff line number Diff line change @@ -1011,6 +1011,18 @@ struct Foo<T> { // expected-note {{arguments to generic parameter 'T' ('W' and '
1011
1011
}
1012
1012
}
1013
1013
1014
+ extension Foo : Equatable where T : Equatable {
1015
+ static func == ( lhs: Foo , rhs: Foo ) -> Bool {
1016
+ lhs. wrappedValue == rhs. wrappedValue
1017
+ }
1018
+ }
1019
+
1020
+ extension Foo : Hashable where T : Hashable {
1021
+ func hash( into hasher: inout Hasher ) {
1022
+ hasher. combine ( wrappedValue)
1023
+ }
1024
+ }
1025
+
1014
1026
@propertyWrapper
1015
1027
struct Bar < T, V> {
1016
1028
var wrappedValue : T
@@ -1059,6 +1071,8 @@ struct MissingPropertyWrapperUnwrap {
1059
1071
func d( _: W ) { }
1060
1072
func e( _: Foo < W > ) { }
1061
1073
1074
+ subscript< T : Hashable > ( takesFoo x: Foo < T > ) -> Foo < T > { x }
1075
+
1062
1076
func baz( ) {
1063
1077
self . x. foo ( ) // expected-error {{referencing instance method 'foo()' requires wrapper 'Foo<Int>'}}{{10-10=_}}
1064
1078
self . x. prop // expected-error {{referencing property 'prop' requires wrapper 'Foo<Int>'}} {{10-10=_}}
@@ -1092,6 +1106,10 @@ struct MissingPropertyWrapperUnwrap {
1092
1106
1093
1107
self . x [ q: " ultimate question " , 42 ] // expected-error {{referencing subscript 'subscript(q:_:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
1094
1108
self . x [ q: " ultimate question " , 42 ] = true // expected-error {{referencing subscript 'subscript(q:_:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
1109
+
1110
+ // SR-11476
1111
+ _ = \Self . [ takesFoo: self . x] // expected-error {{cannot convert value 'x' of type 'Int' to expected type 'Foo<Int>', use wrapper instead}}{{31-31=_}}
1112
+ _ = \Foo < W > . [ x: self . _x] // expected-error {{cannot convert value '_x' of type 'Foo<Int>' to expected type 'Int', use wrapped value instead}} {{26-27=}}
1095
1113
}
1096
1114
}
1097
1115
You can’t perform that action at this time.
0 commit comments