Skip to content

[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

Merged
merged 1 commit into from
May 13, 2020

Conversation

artemcm
Copy link
Contributor

@artemcm artemcm commented May 11, 2020

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

@artemcm artemcm requested a review from xedin May 11, 2020 21:55
@artemcm
Copy link
Contributor Author

artemcm commented May 11, 2020

Oi! Just noticed that this issue is also being tackled in: #31671

@xedin
Copy link
Contributor

xedin commented May 11, 2020

At a glance I think this is actually a solution we want :) /cc @LucianoPAlmeida

@LucianoPAlmeida
Copy link
Contributor

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: }}
Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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

Copy link
Contributor Author

@artemcm artemcm May 12, 2020

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

Copy link
Contributor Author

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.

@artemcm artemcm force-pushed the UnlabeledKeypathFix branch 3 times, most recently from ec76570 to 4a75049 Compare May 12, 2020 04:02
@artemcm artemcm force-pushed the UnlabeledKeypathFix branch from 4a75049 to d67d2b3 Compare May 12, 2020 16:18
@artemcm artemcm force-pushed the UnlabeledKeypathFix branch 2 times, most recently from e5f7d55 to 4265943 Compare May 12, 2020 22:55
@artemcm artemcm force-pushed the UnlabeledKeypathFix branch from 4265943 to 97e32ab Compare May 12, 2020 22:58
@artemcm
Copy link
Contributor Author

artemcm commented May 12, 2020

@swift-ci test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 97e32ab

@shahmishal
Copy link
Member

@swift-ci Please test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants