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

Confusing error if accidentially defining a type paramter with the same name as an existing type #52082

Closed
Kimundi opened this issue Jul 5, 2018 · 9 comments
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Kimundi
Copy link
Member

Kimundi commented Jul 5, 2018

An example from IRC just now:

https://play.rust-lang.org/?gist=ad253f7f1b851935890346136fe47912&version=stable&mode=debug&edition=2015

#[derive(Debug)]
struct Point
{
    x: i32,
    y: i32
}

impl Point
{
    fn add(a: &Point, b: &Point) -> Point
    {
        Point {x: a.x + b.x, y: a.y + b.y}
    }
}

trait Eq
{
    fn equals<T>(a: &T, b: &T) -> bool;
}

impl Eq for Point
{
    fn equals<Point>(a: &Point, b: &Point) -> bool
    {
        a.x == b.x && a.y == b.y
    }
}

fn main()
{
    let p1 = Point {x:  0, y: 10};
    let p2 = Point {x: 20, y: 42};
    println!("{:?}", Point::add(&p1, &p2));
    println!("p1: {:?}, p2: {:?}", p1, p2);
    println!("p1 == p2: {:?}", Eq::equals(&p1, &p2));
}
   Compiling playground v0.0.1 (file:///playground)
error[E0609]: no field `x` on type `&Point`
  --> src/main.rs:25:11
   |
25 |         a.x == b.x && a.y == b.y
   |           ^

error[E0609]: no field `x` on type `&Point`
  --> src/main.rs:25:18
   |
25 |         a.x == b.x && a.y == b.y
   |                  ^

error[E0609]: no field `y` on type `&Point`
  --> src/main.rs:25:25
   |
25 |         a.x == b.x && a.y == b.y
   |                         ^

error[E0609]: no field `y` on type `&Point`
  --> src/main.rs:25:32
   |
25 |         a.x == b.x && a.y == b.y
   |                                ^

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0609`.
error: Could not compile `playground`.

To learn more, run the command again with --verbose.

The mistake here is that Point is also used as a shadowing type parameter inside the Function.

Maybe have a warn lint that tries to detect cases like this? (With a type parameter that also exist as a concrete type in the surrounding scope)

This issue has been assigned to @Baranowski via this comment.

@oli-obk
Copy link
Contributor

oli-obk commented Jul 5, 2018

Clippy has such a lint, but it would trigger after the errors I think. We could mention that something is a type parameter whenever errors related to it occur. Or have a lint at resolve time

@estebank estebank added the A-diagnostics Area: Messages for errors, warnings, and lints label Jul 7, 2018
@estebank
Copy link
Contributor

E0609 should point at the type that doesn't have the field, in this case it would point at the type argument and not the struct, making it easier to figure out what's happening.

@estebank
Copy link
Contributor

The cases TyParam and TyRef need to be handled in

for the former by doing something like

let parent_id = self.tcx.hir().get_parent_item(expr.hir_id);
let parent = self.tcx.hir().get(parent_id);

and finding the appropriate param name and use its span to point to. For the TyRef case it's slightly harder because you need to dereference to find if it is an ADT or a Param, but the same rules apply.

@estebank estebank added E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. P-low Low priority labels Aug 15, 2019
@Baranowski
Copy link
Contributor

I would like to work on this as I'm currently learning Rust, if you don't mind.

@oli-obk
Copy link
Contributor

oli-obk commented Sep 20, 2019

Great! you can reserve this issue via @rustbot claim

@Baranowski
Copy link
Contributor

@rustbot claim

@rustbot rustbot self-assigned this Sep 20, 2019
@Baranowski
Copy link
Contributor

I would appreciate some hand-holding here.

From check_field, I have access to ty::ParamTy. It seems that if I also had ty::Generics available, I could map ty::ParamTy to ty::GenericParamDef, extract DefId from that, and get a step closer to span (which I suspect is stored somewhere in hir::). Perhaps I should add ty::Generics to rustc_typeck::check::FnCtxt?

@oli-obk
Copy link
Contributor

oli-obk commented Sep 25, 2019

The self object has a body_id field which should allow you to get at the DefId (I think tcx.hir().body_owner_def_id(self.body_id)) which you can then use with tcx.generics_of

Baranowski added a commit to Baranowski/rust that referenced this issue Sep 27, 2019
Centril added a commit to Centril/rust that referenced this issue Sep 28, 2019
bors added a commit that referenced this issue Sep 28, 2019
Rollup of 10 pull requests

Successful merges:

 - #64131 (data_structures: Add deterministic FxHashMap and FxHashSet wrappers)
 - #64387 (Fix redundant semicolon lint interaction with proc macro attributes)
 - #64678 (added more context for duplicate lang item errors (fixes #60561))
 - #64763 (Add E0734 and its long explanation)
 - #64793 (Fix format macro expansions spans to be macro-generated)
 - #64837 (Improve wording in documentation of MaybeUninit)
 - #64852 (Print ParamTy span when accessing a field (#52082))
 - #64875 (Upgrade async/await to "used" keywords.)
 - #64876 (Fix typo in intrinsics op safety)
 - #64880 (Slice docs: fix typo)

Failed merges:

r? @ghost
andjo403 pushed a commit to andjo403/rust that referenced this issue Oct 4, 2019
@Baranowski
Copy link
Contributor

I believe this issue can now be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants