[ ] Refine name resolution cache functionality and merge path analysis pass with def analysis, this probably should be done before implementing #988
[x] Integrate method selection into type inference context properly. For example, s.foo should be resolved to Trait<u32>::method without any ambiguity. (Resolved in #1007)
trait Trait<T> {
fn method(self) -> T
}
struct S {}
impl Trait for S {
fn method(self) -> i32 {
1
}
}
impl Trait for S {
fn method(self) -> u32 {
1
}
}
fn foo() -> u32 {
let s = S {};
s.method()
}
This could be achieved by maintaining the mapping between a canonical type and a given receiver type in a call site.
Also, the method selector needs to return a `TraitInst` that relates to the receiver type. In the above example, it will be `Canonical<Trait<S, ?0>>`. The below one is a more complex case,
```rust
trait Default {
fn default() -> Self
}
trait Foo<T, U> {
fn foo(self) -> (T, U)
}
struct S<T> {
t: T,
}
impl<T> S<T> {
fn new() -> Self
where
T: Default,
{
Self { t: T::default() }
}
}
impl<T> Foo<i32, T> for S<T> {
fn foo(self) -> (i32, T) {
(1, self.t)
}
}
impl<T> Foo<u32, T> for S<T> {
fn foo(self) -> (u32, T) {
(1, self.t)
}
}
fn bar() -> (u32, i32) {
let s = S::new()
s.foo()
}
In this case, assuming the type of s is S<?10> in the inference context and its canonical form is Canonical<S<?0>>, then the method selector needs to return Canonical<Trait<S<?0>, ?1, ?0>> as a candidate for s.foo. Then, it should be decanonicalized to Trait<S<?10>, ?fresh, ?10> in the inference context, where ?fresh is a new type variable.
[ ] Improve error message when function call doesn't satisfy constraints.
Currently, the error message is not so good when function argument/return type doesn't satisfy the constraints.
e.g.,
To address this issue generally, we need to maintain how the generic parameter relates to the argument/return type given by the call site in the type inference phase.
[ ] Refine name resolution cache functionality and merge path analysis pass with def analysis, this probably should be done before implementing #988
[x] Integrate method selection into type inference context properly. For example,
s.foo
should be resolved toTrait<u32>::method
without any ambiguity. (Resolved in #1007)struct S {}
impl Trait for S {
fn method(self) -> i32 {
1
}
}
impl Trait for S {
fn method(self) -> u32 {
1
}
}
fn foo() -> u32 { let s = S {}; s.method() }
In this case, assuming the type of
s
isS<?10>
in the inference context and its canonical form isCanonical<S<?0>>
, then the method selector needs to returnCanonical<Trait<S<?0>, ?1, ?0>>
as a candidate fors.foo
. Then, it should be decanonicalized toTrait<S<?10>, ?fresh, ?10>
in the inference context, where?fresh
is a new type variable.fn bar() { let opt = Some("FOO") foo(t: opt, u: "FOO") }
error[6-0003]: trait bound is not satisfied ┌─ foo.fe:12:5 │ 12 │ foo(t: opt, u: "FOO") │ ^^^
String<3>
doesn't implementCopy