associated type not normalized when a where-clause is present
Affected Versions
At least 1.3, 1.4, rustc 1.5.0-nightly (11a612795 2015-10-04)
STR
trait Foo { type Bar; }
impl<T> Foo for T { type Bar = u64; }
fn foo<T>() -> <T as Foo>::Bar
where T: Foo // <- the code compiles if this is removed
{ 1 }
fn main() {}
Expected Result
the code should compile
Actual Result
<anon>:7:14: 7:15 error: mismatched types:
expected `<T as Foo>::Bar`,
found `_`
(expected associated type,
found integral variable) [E0308]
<anon>:7 x = Some(1);
^
cc @nikomatsakis
The root cause is that selection picks the where-clause candidate over any impl candidate, and this does not allow projection to make progress. This looks to be hard to fix.
Ariel Ben-Yehuda at 2015-10-07 22:03:10
Yes, this is to some extent a known limitation and the "expected result", but I would still classify it as a bug.
Niko Matsakis at 2015-10-08 18:47:47
(Note: Deleted and reposted since I screwed up the first version, and realized I could minimize it more)
I hit this case while trying to work around #68375 - I'm pretty sure it's the same bug
pub trait Data { type Elem; } pub struct ViewRepr<A>(A); impl<'a, A> Data for ViewRepr<&'a A> { type Elem = A; } type ArrayBase<S> = ArrayBaseInner<S, <S as Data>::Elem>; pub struct ArrayBaseInner<S: Data<Elem = Elem>, Elem> { ptr: *mut Elem, d: S, } fn std1d<'a>(_: ArrayBase<ViewRepr<&'a f64>>) {} fn map_axis<'a, F>(f: F) where F: FnMut(ArrayBase<ViewRepr<&'a f64>>) {} fn std() { map_axis(std1d); }error[E0631]: type mismatch in function arguments --> test.rs:25:14 | 17 | fn std1d<'a>(_: ArrayBase<ViewRepr<&'a f64>>) {} | --------------------------------------------- found signature of `for<'a> fn(ArrayBaseInner<ViewRepr<&'a f64>, <ViewRepr<&'a f64> as Data>::Elem>) -> _` 18 | 19 | fn map_axis<'a, F>(f: F) | -------- 20 | where 21 | F: FnMut(ArrayBase<ViewRepr<&'a f64>>) | ----------------------------------- required by this bound in `map_axis` ... 25 | map_axis(std1d); | ^^^^^ expected signature of `fn(ArrayBaseInner<ViewRepr<&f64>, f64>) -> _`Greg Morenz at 2020-01-20 14:53:49
Nope, you have a return value in
std1dbut not in the where clause formap_axisRustyYato at 2020-01-20 15:09:35
Oops, you're right, minification mistake. Fixed that above, it doesn't substantially change the error message.
Greg Morenz at 2020-01-20 15:26:27
@gmorenz this is because of the lifetime parameter. Because the associated type could depend on the choice of lifetime parameter, it doesn't get normalized.
That does seem related to this Issue.
RustyYato at 2020-01-20 16:41:12
Triage: no change
Maayan Hanin at 2022-10-17 19:30:59
Current output:
error[E0308]: mismatched types --> src/main.rs:7:3 5 | fn foo<T>() -> <T as Foo>::Bar | --------------- expected `<T as Foo>::Bar` because of return type 6 | where T: Foo // <- the code compiles if this is removed 7 | { 1 } | ^ expected associated type, found integer | = note: expected associated type `<T as Foo>::Bar` found type `{integer}` help: consider constraining the associated type `<T as Foo>::Bar` to `{integer}` |Dylan DPC at 2024-08-28 05:03:39