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

Point error span at Some constructor argument when trait resolution fails #108557

Merged

Conversation

Nathan-Fenner
Copy link
Contributor

This is a follow up to #108254 and #106477 which extends error span refinement to handle a case which I mistakenly believed was handled in #106477. The goal is to refine the error span depicted below:

trait Fancy {}
impl <T> Fancy for Option<T> where T: Iterator {}

fn want_fancy<F>(f: F) where F: Fancy {}

fn example() {
    want_fancy(Some(5));
//  (BEFORE)   ^^^^^^^ `{integer}` is not an iterator 
//  (AFTER)         ^  `{integer}` is not an iterator
}

I had used a (slightly more complex) example as an illustrative example in #108254 , but hadn't actually turned it into a test, because I had (incorrectly) believed at the time it was covered by existing behavior. It turns out that Some is slightly "special" in that it resolves differently from the other enum constructors I had tried, and therefore this test was actually broken.

I've now updated the tests to include this example, and fixed the code to correctly resolve the Some constructor so that the span of the error is reduced.

@rustbot
Copy link
Collaborator

rustbot commented Feb 28, 2023

r? @davidtwco

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 28, 2023
@Nathan-Fenner
Copy link
Contributor Author

r? @WaffleLapkin you spotted this issue in the previous PR

@rustbot rustbot assigned WaffleLapkin and unassigned davidtwco Feb 28, 2023
Comment on lines +723 to +724
// The constructor definition refers to the "constructor" of the variant:
// For example, `Some(5)` triggers this case.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand... Does Some's def id refer to the use statement?

// (3) and then parent's parent refers to the option itself
enum Option<T> {
    Some(T), // (2) The first parent refers here
    None,
}

pub use Option::Some; // (1) `Some`'s def id refers to here

If this is the case, would this "fail" on something like the following?:

enum A<T> { V0(T) }
use A::V0 as V1;
use V1 as V2;
/* then, code with V2, such that you need parent's parent's parent */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not pointing to the use statement. It's pointing to a "constructor" definition which lives inside the "variant" definition.

So if we have

enum ExampleTuple<T> {
    ExampleTupleVariant(T),
}
use ExampleDifferentTupleVariantName as ExampleYetAnotherTupleVariantName;
use ExampleTuple as ExampleOtherTuple;
use ExampleTuple::ExampleTupleVariant as ExampleDifferentTupleVariantName;
use ExampleTuple::*;

impl<A> T1 for ExampleTuple<A> where A: T3 {}

then for all of

  • ExampleTuple::ExampleTupleVariant(q)
  • ExampleTupleVariant(q)
  • ExampleOtherTuple::ExampleTupleVariant(q)
  • ExampleDifferentTupleVariantName(q)
  • ExampleYetAnotherTupleVariantName(q)

by printing the relevant DefIds we see the same thing in each case:

expr_ctor_def_id :::                                   DefId(0:29 ~ blame_trait_error[b442]::ExampleTuple::ExampleTupleVariant::{constructor#0})
self.tcx.parent(expr_ctor_def_id) :::                  DefId(0:28 ~ blame_trait_error[b442]::ExampleTuple::ExampleTupleVariant)
self.tcx.parent(self.tcx.parent(expr_ctor_def_id)) ::: DefId(0:26 ~ blame_trait_error[b442]::ExampleTuple)

So going up once gets us to the variant and going up twice gets us to the type definition. I'm actually not sure how/why going up only once ever seemed to work before - this may have just been a miss since the first PR focused mostly on structs and tuples.

I've added a lot of new tests to cover this name resolving behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh, and for structures you get expr_ctor_def_id ::: DefId(...::Struct::{constructor#0}), so you only need to go one level up the parent chain. Makes sense, thanks for the explanation and adding a comment!

@WaffleLapkin
Copy link
Member

Thanks!
@bors r+ rollup

@bors
Copy link
Contributor

bors commented Mar 2, 2023

📌 Commit be15f17 has been approved by WaffleLapkin

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 2, 2023
compiler-errors added a commit to compiler-errors/rust that referenced this pull request Mar 2, 2023
…-span-fix-Some, r=WaffleLapkin

Point error span at Some constructor argument when trait resolution fails

This is a follow up to rust-lang#108254 and rust-lang#106477 which extends error span refinement to handle a case which I mistakenly believed was handled in rust-lang#106477. The goal is to refine the error span depicted below:

```rs
trait Fancy {}
impl <T> Fancy for Option<T> where T: Iterator {}

fn want_fancy<F>(f: F) where F: Fancy {}

fn example() {
    want_fancy(Some(5));
//  (BEFORE)   ^^^^^^^ `{integer}` is not an iterator
//  (AFTER)         ^  `{integer}` is not an iterator
}
```

I had used a (slightly more complex) example as an illustrative example in rust-lang#108254 , but hadn't actually turned it into a test, because I had (incorrectly) believed at the time it was covered by existing behavior. It turns out that `Some` is slightly "special" in that it resolves differently from the other `enum` constructors I had tried, and therefore this test was actually broken.

I've now updated the tests to include this example, and fixed the code to correctly resolve the `Some` constructor so that the span of the error is reduced.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 2, 2023
…-span-fix-Some, r=WaffleLapkin

Point error span at Some constructor argument when trait resolution fails

This is a follow up to rust-lang#108254 and rust-lang#106477 which extends error span refinement to handle a case which I mistakenly believed was handled in rust-lang#106477. The goal is to refine the error span depicted below:

```rs
trait Fancy {}
impl <T> Fancy for Option<T> where T: Iterator {}

fn want_fancy<F>(f: F) where F: Fancy {}

fn example() {
    want_fancy(Some(5));
//  (BEFORE)   ^^^^^^^ `{integer}` is not an iterator
//  (AFTER)         ^  `{integer}` is not an iterator
}
```

I had used a (slightly more complex) example as an illustrative example in rust-lang#108254 , but hadn't actually turned it into a test, because I had (incorrectly) believed at the time it was covered by existing behavior. It turns out that `Some` is slightly "special" in that it resolves differently from the other `enum` constructors I had tried, and therefore this test was actually broken.

I've now updated the tests to include this example, and fixed the code to correctly resolve the `Some` constructor so that the span of the error is reduced.
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 3, 2023
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#108022 (Support allocations with non-Box<[u8]> bytes)
 - rust-lang#108367 (Re-apply "switch to the macos-12-xl builder")
 - rust-lang#108557 (Point error span at Some constructor argument when trait resolution fails)
 - rust-lang#108573 (Explain compile-time vs run-time difference in env!() error message)
 - rust-lang#108584 (Put backtick content from rustdoc search errors into a `<code>` elements)
 - rust-lang#108624 (Make `ExprKind` the first field in `thir::Expr`)
 - rust-lang#108644 (Allow setting hashmap toml values in `./configure`)
 - rust-lang#108672 (Feed queries on impl side for RPITITs when using lower_impl_trait_in_trait_to_assoc_ty)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 564715a into rust-lang:master Mar 3, 2023
@rustbot rustbot added this to the 1.69.0 milestone Mar 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants