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

E0221 needs more helpful information #35970

Closed
sophiajt opened this issue Aug 24, 2016 · 4 comments · Fixed by #37396
Closed

E0221 needs more helpful information #35970

sophiajt opened this issue Aug 24, 2016 · 4 comments · Fixed by #37396
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-low Low priority

Comments

@sophiajt
Copy link
Contributor

Currently, E0221 can give an error like:

error[E0221]: ambiguous associated type `A` in bounds of `Self`
  --> src/test/compile-fail/E0221.rs:21:16
   |
21 |         let _: Self::A;
   |                ^^^^^^^ ambiguous associated type `A`
   |
note: associated type `Self` could derive from `Foo`
  --> src/test/compile-fail/E0221.rs:21:16
   |
21 |         let _: Self::A;
   |                ^^^^^^^
note: associated type `Self` could derive from `Bar`
  --> src/test/compile-fail/E0221.rs:21:16
   |
21 |         let _: Self::A;
   |                ^^^^^^^

This isn't terribly helpful. Ideally, we'd like to show where these associated types that cause ambiguity are coming from:

error[E0221]: ambiguous associated type `A` in bounds of `Self`
  --> src/test/compile-fail/E0221.rs:21:16
   |
15 |    type A: T1;
   |    ---------- ambiguous `A` from `Foo`
...
19 |    type A: T2;
   |    ---------- ambiguous `A` from `Bar`
20 |    fn do_something() {
21 |         let _: Self::A;
   |                ^^^^^^^ ambiguous associated type `A`

cc @nikomatsakis

@nikomatsakis nikomatsakis added A-diagnostics Area: Messages for errors, warnings, and lints P-low Low priority E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. labels Aug 24, 2016
@nikomatsakis
Copy link
Contributor

I'd be up to mentor this. The message is reported by some code in src/librustc_typeck/astconv.rs, which has the job of converting the HIR representation of a type into the compiler's internal representation. The challenge here is that the HIR types have spans (because they are basically the things that the user wrote) whereas the internal representations do not. Right now, the routine in question, one_bound_for_associated_type, only has access to a list of the representations in internal form (bounds: Vec<ty::PolyTraitRef<'tcx>>. To give better spans, we have to trace those spans in (so e.g. we want bounds: Vec<(Span, ty::PolyTraitRef<'tcx>)>).

What this routine does is, given a type like A::Item, it selects what traits the associated type Item might have been defined in, and tries to pick one. The list bounds is the list of traits that A implements. So e.g. it might include something like A: Iterator, which would suggest that A::Item could be expanded to <A as Iterator>::Item. But if there was another bound, say A: Foo, that also defines an associated type Item, that'd be an amiguity.

If you look at the callers, there aren't that many (3, I think). Two of those are for trait objects, I think, where the bounds come from the supertraits of the trait object. Probably we could give those the spans of the trait type itself, though we may want to get the spans out of the trait definition where the supertraits come from (but that could be in another crate). That last part is a bit tricky because we'd have to extend the TraitDef. Let's assume we're not doing that for now, and we're willing to give a span referring to a trait X when in fact the item lies in a supertrait Y where X: Y.

The other is the more general case of a type parameter. I think the major piece of work then is to augment this routine get_type_parameter_bounds in the AstConv trait:

    fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
                                 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;

so that it returns a Vec<(Span, ty::PolyTraitRef<'tcx>)>, where we would thread through the spans whence each bound was derived.

Anyway, this is non-trivial, but seems to me to be achievable if anyone wants to dig in. If so, ping me (either on IRC, nmatsakis, or here) and I'll try to give more hints. :)

@mikhail-m1
Copy link
Contributor

@nikomatsakis I'll try, I need some time to look around

@mikhail-m1
Copy link
Contributor

@nikomatsakis get_type_parameter_bounds in caller_bounds contains vec of Predicate w/o spans. May be is it easy only for error case in one_bound_for_associated_type get spans from ast_map (hir::map) by DefId extracted from TypeTraitItems like trait_defines_associated_type_named do?

@mikhail-m1
Copy link
Contributor

I've updated it mikhail-m1@585f835.

But what do you think about trait from extern crate?

trait T3 {}

trait My : std::str::FromStr {
    type Err: T3;
    fn test() {
        let _: Self::Err;
    }
}
error[E0221]: ambiguous associated type `Err` in bounds of `Self`
  --> src/test/compile-fail/E0221.rs:32:16
   |
30 |     type Err: T3; //~ NOTE: ambiguous `Err` from `My`
   |     ------------- ambiguous `Err` from `My`
31 |     fn test() {
32 |         let _: Self::Err;
   |                ^^^^^^^^^ ambiguous associated type `Err`
   |
note: associated type `Self` could derive from `std::str::FromStr`
  --> src/test/compile-fail/E0221.rs:32:16
   |
32 |         let _: Self::Err;
   |                ^^^^^^^^^

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Oct 26, 2016
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-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-low Low priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants