mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSDiagnostics] Differentiate between key path type and value issues
Make sure that contextual mismatch uses a correct locator when the issue is with key path value type instead of the key path type.
This commit is contained in:
@@ -678,9 +678,12 @@ ERROR(expr_swift_keypath_not_starting_with_type,none,
|
||||
ERROR(expr_swift_keypath_not_starting_with_dot,none,
|
||||
"a Swift key path with contextual root must begin with a leading dot",
|
||||
())
|
||||
ERROR(expr_smart_keypath_value_covert_to_contextual_type,none,
|
||||
ERROR(expr_keypath_value_covert_to_contextual_type,none,
|
||||
"key path value type %0 cannot be converted to contextual type %1",
|
||||
(Type, Type))
|
||||
ERROR(expr_keypath_type_covert_to_contextual_type,none,
|
||||
"cannot convert key path type %0 to contextual type %1",
|
||||
(Type, Type))
|
||||
ERROR(expr_swift_keypath_empty, none,
|
||||
"key path must have at least one component", ())
|
||||
ERROR(expr_string_interpolation_outside_string,none,
|
||||
|
||||
@@ -2497,7 +2497,7 @@ bool ContextualFailure::diagnoseAsError() {
|
||||
if (path.empty()) {
|
||||
if (auto *KPE = getAsExpr<KeyPathExpr>(anchor)) {
|
||||
emitDiagnosticAt(KPE->getLoc(),
|
||||
diag::expr_smart_keypath_value_covert_to_contextual_type,
|
||||
diag::expr_keypath_type_covert_to_contextual_type,
|
||||
getFromType(), getToType());
|
||||
return true;
|
||||
}
|
||||
@@ -2744,6 +2744,11 @@ bool ContextualFailure::diagnoseAsError() {
|
||||
break;
|
||||
}
|
||||
|
||||
case ConstraintLocator::KeyPathValue: {
|
||||
diagnostic = diag::expr_keypath_value_covert_to_contextual_type;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -7646,7 +7651,7 @@ bool ArgumentMismatchFailure::diagnoseKeyPathAsFunctionResultMismatch() const {
|
||||
paramFnType->getParams().front().getPlainType()->isEqual(kpRootType)))
|
||||
return false;
|
||||
|
||||
emitDiagnostic(diag::expr_smart_keypath_value_covert_to_contextual_type,
|
||||
emitDiagnostic(diag::expr_keypath_value_covert_to_contextual_type,
|
||||
kpValueType, paramFnType->getResult());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6693,7 +6693,8 @@ bool ConstraintSystem::repairFailures(
|
||||
}
|
||||
|
||||
conversionsOrFixes.push_back(IgnoreContextualType::create(
|
||||
*this, lhs, rhs, keyPathLoc));
|
||||
*this, lhs, rhs,
|
||||
getConstraintLocator(keyPathLoc, ConstraintLocator::KeyPathValue)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -230,11 +230,11 @@ func issue_65965() {
|
||||
|
||||
let refKP: ReferenceWritableKeyPath<S, String>
|
||||
refKP = \.s
|
||||
// expected-error@-1 {{key path value type 'WritableKeyPath<S, String>' cannot be converted to contextual type 'ReferenceWritableKeyPath<S, String>'}}
|
||||
// expected-error@-1 {{cannot convert key path type 'WritableKeyPath<S, String>' to contextual type 'ReferenceWritableKeyPath<S, String>'}}
|
||||
|
||||
let writeKP: WritableKeyPath<S, String>
|
||||
writeKP = \.v
|
||||
// expected-error@-1 {{key path value type 'KeyPath<S, String>' cannot be converted to contextual type 'WritableKeyPath<S, String>'}}
|
||||
// expected-error@-1 {{cannot convert key path type 'KeyPath<S, String>' to contextual type 'WritableKeyPath<S, String>'}}
|
||||
}
|
||||
|
||||
func test_any_key_path() {
|
||||
|
||||
@@ -4,7 +4,7 @@ struct S {
|
||||
let i: Int
|
||||
|
||||
init() {
|
||||
let _: WritableKeyPath<S, Int> = \.i // expected-error {{cannot convert value of type 'KeyPath<S, Int>' to specified type 'WritableKeyPath<S, Int>'}}
|
||||
let _: WritableKeyPath<S, Int> = \.i // expected-error {{cannot convert key path type 'KeyPath<S, Int>' to contextual type 'WritableKeyPath<S, Int>'}}
|
||||
|
||||
S()[keyPath: \.i] = 1
|
||||
// expected-error@-1 {{cannot assign through subscript: key path is read-only}}
|
||||
@@ -12,7 +12,7 @@ struct S {
|
||||
}
|
||||
|
||||
func test() {
|
||||
let _: WritableKeyPath<C, Int> = \.i // expected-error {{cannot convert value of type 'KeyPath<C, Int>' to specified type 'WritableKeyPath<C, Int>'}}
|
||||
let _: WritableKeyPath<C, Int> = \.i // expected-error {{cannot convert key path type 'KeyPath<C, Int>' to contextual type 'WritableKeyPath<C, Int>'}}
|
||||
|
||||
C()[keyPath: \.i] = 1
|
||||
// expected-error@-1 {{cannot assign through subscript: key path is read-only}}
|
||||
|
||||
@@ -127,14 +127,14 @@ func testKeyPath(sub: Sub, optSub: OptSub,
|
||||
let _: KeyPath<A, Prop> = \.property
|
||||
let _: WritableKeyPath<A, Prop> = \.property
|
||||
let _: ReferenceWritableKeyPath<A, Prop> = \.property
|
||||
//expected-error@-1 {{cannot convert value of type 'WritableKeyPath<A, Prop>' to specified type 'ReferenceWritableKeyPath<A, Prop>'}}
|
||||
//expected-error@-1 {{cannot convert key path type 'WritableKeyPath<A, Prop>' to contextual type 'ReferenceWritableKeyPath<A, Prop>'}}
|
||||
|
||||
let _: (A) -> A = \.[sub]
|
||||
let _: PartialKeyPath<A> = \.[sub]
|
||||
let _: KeyPath<A, A> = \.[sub]
|
||||
let _: WritableKeyPath<A, A> = \.[sub]
|
||||
let _: ReferenceWritableKeyPath<A, A> = \.[sub]
|
||||
//expected-error@-1 {{cannot convert value of type 'WritableKeyPath<A, A>' to specified type 'ReferenceWritableKeyPath<A, A>'}}
|
||||
//expected-error@-1 {{cannot convert key path type 'WritableKeyPath<A, A>' to contextual type 'ReferenceWritableKeyPath<A, A>'}}
|
||||
|
||||
let _: (A) -> Prop? = \.optProperty?
|
||||
let _: PartialKeyPath<A> = \.optProperty?
|
||||
@@ -162,7 +162,7 @@ func testKeyPath(sub: Sub, optSub: OptSub,
|
||||
let _: KeyPath<C<A>, A> = \.value
|
||||
let _: WritableKeyPath<C<A>, A> = \.value
|
||||
let _: ReferenceWritableKeyPath<C<A>, A> = \.value
|
||||
// expected-error@-1 {{cannot convert value of type 'WritableKeyPath<C<A>, A>' to specified type 'ReferenceWritableKeyPath<C<A>, A>'}}
|
||||
// expected-error@-1 {{cannot convert key path type 'WritableKeyPath<C<A>, A>' to contextual type 'ReferenceWritableKeyPath<C<A>, A>'}}
|
||||
|
||||
let _: (C<A>) -> A = \C.value
|
||||
let _: PartialKeyPath<C<A>> = \C.value
|
||||
|
||||
Reference in New Issue
Block a user