Skip to content
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

[SR-9213] Incorrect error message when trying to use keypath with tuple #51702

Closed
swift-ci opened this issue Nov 9, 2018 · 14 comments
Closed
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation good first issue Good for newcomers

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Nov 9, 2018

Previous ID SR-9213
Radar None
Original Reporter twof (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

swift 4.2.1
xcode 10.1

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, DiagnosticsQoI, StarterBug
Assignee @theblixguy
Priority Medium

md5: 1221485d8951fe5e52842c6c4d9c0b1d

Issue Description:

struct Hello {
    let things: (first: Int, second: Int)
}

let keypath: KeyPath<Hello, Int> = \Hello.things.first // type (first: Int, second: Int) has no member first
{\code}

The same thing happens when the autogenerated indexes are used

struct Hello {
let things: (Int, Int)
}

let keypath: KeyPath<Hello, Int> = \Hello.things.0 // type (Int, Int) has no member 0
{\code}

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

@xedin, @jckarter, think this would make a good Starter Bug?

@jckarter
Copy link
Member

jckarter commented Nov 9, 2018

I think so; this should be straightforward to check for and emit a custom "tuples not implemented yet" message for.

@theblixguy
Copy link
Collaborator

Can this be assigned to me? I would like to fix this issue 🙂

Never mind, JIRA was acting weird, I have now assigned it to myself!

@theblixguy
Copy link
Collaborator

I believe I need to emit a different diagnostic in

void PreCheckExpression::resolveKeyPathExpr(KeyPathExpr *KPE) {}

So:

if (auto TE = dyn_cast<TupleExpr>(expr)) { // emit custom diagnostic }

Just wondering if I am in the right path 🙂

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

It looks like the current message is coming from diagnoseKeyPathComponents in CSDiag.cpp, which makes sense because PreCheckExpression happens before we figure out the types of things.

@theblixguy
Copy link
Collaborator

@belkadan I see!

if (currentType) TC.diagnose(componentNameLoc, diag::could_not_find_type_member, currentType, componentName);

So, currentType is declared as:

Type currentType = rootType;

So, perhaps I can do:

if (isa<TupleType>(currentType)) { // emit custom diagnostics }

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

@jckarter's the real expert, but that approach seems reasonable to me!

@theblixguy
Copy link
Collaborator

@belkadan okay 🙂

My Mac is still building the compiler, so I haven't tested anything yet, so just waiting for it to finish building.

In the meantime, I think it's slightly better to do it before:

for (auto &component : KPE->getComponents()) {}

So before that for-loop, we can do:

if (state == ResolvingType && isa<TupleType>(currentType)) {
   // emit diagnostics
   return true
}

It could also probably be done even earlier, so just before this is declared:

SmallString<32> keyPathScratch;

because there's no point of continuing forward and we could return early from diagnoseKeyPathComponents if we know the rootType is TupleType.

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

Aha, but what if the second component is a tuple?

@theblixguy
Copy link
Collaborator

@belkadan Hmm, you mean if we had a nested tuple?

let things: (first: Int, second: (third: Int, fourth: Int))

I am under the assumption that rootType will be a tuple as things is a tuple. If that is true, then there is no need to inspect the components as the whole thing is a tuple?

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

I was thinking more about something like this:

struct Pointish {
  var value: (x: Int, y: Int)
}
let keyPath = \Pointish.value.x

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

Heh, in fact Alex's original example is one of those.

@theblixguy
Copy link
Collaborator

@belkadan: Here's the pull request: #20495

@theblixguy
Copy link
Collaborator

PR approved and merged.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants