Unable to call trait method as function when implemented on bound
I tried this code:
#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
pub trait Bar {}
pub trait Foo {
type Ty;
fn foo(self) -> Self::Ty;
}
impl<B: Bar> Foo for B {
type Ty = u32;
fn foo(self) -> Self::Ty {
14
}
}
struct Qux;
impl Bar for Qux {}
fn main() {
let a = Qux;
a.foo();
let b = Qux;
Foo::foo(b);
}
I expected to see this happen: no error. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=41805c77628c84f5e2ccb80c4be2bfe6
Instead, this happened:
trait_call.rs:17:30: error: mismatched types, expected ‘<placeholder:>’ but got ‘<integer>’ [E0308]
17 | fn foo(self) -> Self::Ty {
| ~~ ~~~~ ^
crab1: error: bounds not satisfied for dyn [Foo<Self>] ‘Sized, Bar’ is not satisfied [E0277]
trait_call.rs:31:14: error: mismatched types, expected ‘dyn [Foo<Self>]’ but got ‘Qux’ [E0308]
17 | fn foo(self) -> Self::Ty {
| ~~~~
......
31 | Foo::foo(b);
| ^
I'm guessing we're missing something simple? This shows up in the for-loop testcase when trying to call IntoIterator::into_iter(1..3) vs (1..3).into_iter(), since IntoIterator is implemented like so:
impl<I: Iterator> IntoIterator for I {
type Item = I::Item;
type IntoIter = I;
fn into_iter(self) -> I {
self
}
}
Can i take on this with a bit of help?
I guess this might be happening in gcc/rust/typecheck/rust-tyty.cc with BaseType::bounds_compatible() and BaseType::satisfies_bound()? I noticed there is a // FIX ME this is missing locus and Idk if its related to anything in this bug?
hm, the "missing locus" part is about missing location info for error emitting, but it does not affect type resolution or anything.
I'm not super familiar with this part of the code so I wouldn't be much help I think - this is @philberty's domain if he has some time