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,
|
ERROR(expr_swift_keypath_not_starting_with_dot,none,
|
||||||
"a Swift key path with contextual root must begin with a leading dot",
|
"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",
|
"key path value type %0 cannot be converted to contextual type %1",
|
||||||
(Type, Type))
|
(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,
|
ERROR(expr_swift_keypath_empty, none,
|
||||||
"key path must have at least one component", ())
|
"key path must have at least one component", ())
|
||||||
ERROR(expr_string_interpolation_outside_string,none,
|
ERROR(expr_string_interpolation_outside_string,none,
|
||||||
|
|||||||
@@ -2497,7 +2497,7 @@ bool ContextualFailure::diagnoseAsError() {
|
|||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
if (auto *KPE = getAsExpr<KeyPathExpr>(anchor)) {
|
if (auto *KPE = getAsExpr<KeyPathExpr>(anchor)) {
|
||||||
emitDiagnosticAt(KPE->getLoc(),
|
emitDiagnosticAt(KPE->getLoc(),
|
||||||
diag::expr_smart_keypath_value_covert_to_contextual_type,
|
diag::expr_keypath_type_covert_to_contextual_type,
|
||||||
getFromType(), getToType());
|
getFromType(), getToType());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2744,6 +2744,11 @@ bool ContextualFailure::diagnoseAsError() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ConstraintLocator::KeyPathValue: {
|
||||||
|
diagnostic = diag::expr_keypath_value_covert_to_contextual_type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -7646,7 +7651,7 @@ bool ArgumentMismatchFailure::diagnoseKeyPathAsFunctionResultMismatch() const {
|
|||||||
paramFnType->getParams().front().getPlainType()->isEqual(kpRootType)))
|
paramFnType->getParams().front().getPlainType()->isEqual(kpRootType)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
emitDiagnostic(diag::expr_smart_keypath_value_covert_to_contextual_type,
|
emitDiagnostic(diag::expr_keypath_value_covert_to_contextual_type,
|
||||||
kpValueType, paramFnType->getResult());
|
kpValueType, paramFnType->getResult());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6693,7 +6693,8 @@ bool ConstraintSystem::repairFailures(
|
|||||||
}
|
}
|
||||||
|
|
||||||
conversionsOrFixes.push_back(IgnoreContextualType::create(
|
conversionsOrFixes.push_back(IgnoreContextualType::create(
|
||||||
*this, lhs, rhs, keyPathLoc));
|
*this, lhs, rhs,
|
||||||
|
getConstraintLocator(keyPathLoc, ConstraintLocator::KeyPathValue)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -230,11 +230,11 @@ func issue_65965() {
|
|||||||
|
|
||||||
let refKP: ReferenceWritableKeyPath<S, String>
|
let refKP: ReferenceWritableKeyPath<S, String>
|
||||||
refKP = \.s
|
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>
|
let writeKP: WritableKeyPath<S, String>
|
||||||
writeKP = \.v
|
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() {
|
func test_any_key_path() {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ struct S {
|
|||||||
let i: Int
|
let i: Int
|
||||||
|
|
||||||
init() {
|
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
|
S()[keyPath: \.i] = 1
|
||||||
// expected-error@-1 {{cannot assign through subscript: key path is read-only}}
|
// expected-error@-1 {{cannot assign through subscript: key path is read-only}}
|
||||||
@@ -12,7 +12,7 @@ struct S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func test() {
|
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
|
C()[keyPath: \.i] = 1
|
||||||
// expected-error@-1 {{cannot assign through subscript: key path is read-only}}
|
// 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 _: KeyPath<A, Prop> = \.property
|
||||||
let _: WritableKeyPath<A, Prop> = \.property
|
let _: WritableKeyPath<A, Prop> = \.property
|
||||||
let _: ReferenceWritableKeyPath<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 _: (A) -> A = \.[sub]
|
||||||
let _: PartialKeyPath<A> = \.[sub]
|
let _: PartialKeyPath<A> = \.[sub]
|
||||||
let _: KeyPath<A, A> = \.[sub]
|
let _: KeyPath<A, A> = \.[sub]
|
||||||
let _: WritableKeyPath<A, A> = \.[sub]
|
let _: WritableKeyPath<A, A> = \.[sub]
|
||||||
let _: ReferenceWritableKeyPath<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 _: (A) -> Prop? = \.optProperty?
|
||||||
let _: PartialKeyPath<A> = \.optProperty?
|
let _: PartialKeyPath<A> = \.optProperty?
|
||||||
@@ -162,7 +162,7 @@ func testKeyPath(sub: Sub, optSub: OptSub,
|
|||||||
let _: KeyPath<C<A>, A> = \.value
|
let _: KeyPath<C<A>, A> = \.value
|
||||||
let _: WritableKeyPath<C<A>, A> = \.value
|
let _: WritableKeyPath<C<A>, A> = \.value
|
||||||
let _: ReferenceWritableKeyPath<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 _: (C<A>) -> A = \C.value
|
||||||
let _: PartialKeyPath<C<A>> = \C.value
|
let _: PartialKeyPath<C<A>> = \C.value
|
||||||
|
|||||||
Reference in New Issue
Block a user