-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Type-checker] Improve diagnostic for keypath used without 'keyPath:' label #31716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Oi! Just noticed that this issue is also being tackled in: #31671 |
At a glance I think this is actually a solution we want :) /cc @LucianoPAlmeida |
Humm... I think that is the way you suggested changing the implementation right @xedin ? |
var x : Int = 0 | ||
} | ||
var s = S() | ||
s[\.x] = 10 // expected-error {{missing argument label 'keyPath:' in subscript}} {{3-3=keyPath: }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's going to happen when there is another subscript (with a different label) which also takes the same type of key path as an argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's going to be an ambiguity failure but we should probably add a test-case regardless.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See example in keypath_subscript_nolabel_ambiguous.swift
, surprisingly, this does not result in an ambiguity error. It produces the exact same missing argument label 'keypath:' in subscript
error. At the use site, trying both keyPath:
and kp:
works; but, without an explicit label, the compiler seems unaware of the ambiguity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a suspicion that this might be un-related to the fix though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@artemcm I think example you have committed produces correct diagnostic, but as @varungandhi-apple mentioned it would be interesting if declared subscript would actually have an argument of (correct) key path type:
struct S {
var x : Int = 0
subscript(v v: KeyPath<S, Int>) -> Int { get { 0 } set(newValue) {} }
}
var s = S()
s[\.x] = 10
Correct key path type but missing label, should be diagnosed as - missing argument label 'v:' in subscript
struct S {
var x : Int = 0
subscript(v: KeyPath<S, String>) -> Int { get { 0 } set(newValue) {} }
}
var s = S()
s[\.x] = 10
No label but incorrect key path type, should be diagnosed as key path value type 'Int' cannot be converted to contextual type 'String'
I think if there is a subscript which has a key path parameter we should always prefer that over keyPath:
one so there is probably only one way to make this ambiguous:
struct S {
var x : Int = 0
subscript(v: KeyPath<S, Double>) -> Int { get { 0 } set(newValue) {} }
subscript(v: KeyPath<S, String>) -> Int { get { 0 } set(newValue) {} }
}
var s = S()
s[\.x] = 10
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @xedin, I was writing up similar examples and I am seeing that for the first code snippet:
struct S {
var x : Int = 0
subscript(v v: KeyPath<S, Int>) -> Int { get { 0 } set(newValue) {} }
}
var s = S()
s[\.x] = 10
This PR changes the produced diagnostic from:
missing argument label 'v:' in subscript
to
missing argument label 'keyPath:' in subscript
Which, as you suggest, isn't right, so I am trying to figure out why that may be changing here.
(This means that the corresponding test test/Sema/keypath_subscript_nolabel_overload.swift
in this PR is currently failing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copying comment from the TODO inserted in the test here, as a summary of this problem:
This should actually be a diagnostic that correctly identifies that in the case of a missing label, there are two options for resolution: 'keyPath:' and 'v:' and to offer the user a choice. Today, the ExprTypeChecker identifies the disjunction with two of these possibilities, but filters out some of the terms based on label mismatch (but not implicit keypath terms, for example). It should probably not do that.
ec76570
to
4a75049
Compare
4a75049
to
d67d2b3
Compare
e5f7d55
to
4265943
Compare
4265943
to
97e32ab
Compare
@swift-ci test |
Build failed |
@swift-ci Please test |
Upon finding a keypath subscript without a prerequisite
keyPath:
label, continue type-checking as usual. If the keyPath type gets verified, it will eventually be caught with a "missing argument" error, which will suggest a fix-it of adding the missing label.Resolves SR-12745
Resolves rdar://problem/62957095