-
Notifications
You must be signed in to change notification settings - Fork 184
Description
I think the following test, or something similar, should pass:
#[test]
fn projection_guidance() {
test! {
program {
trait Iterator { type Item; }
#[non_enumerable]
trait Step {}
struct Range<T> {}
impl<T> Iterator for Range<T> where T: Step {
type Item = T;
}
}
goal {
exists<T> {
exists<U> {
<Range<T> as Iterator>::Item = U
}
}
} yields[SolverChoice::recursive()] {
"Ambiguous; definite substitution { [?0 := ?0.0, ?1 = ?0.0] }"
}
}
}
I.e. the recursive solver should be able to tell that there is only one impl that could possibly apply, so we know the Item
type. This is derived from the following real-world case (from rust-lang/rust-analyzer#4072:
enum Option<T> {}
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
trait Step { }
impl Step for i32 {}
impl Step for u32 {}
struct Range<T>(T, T);
impl<A: Step> Iterator for Range<A> {
type Item = A;
}
fn main() {
let x = Range(0, 10).next();
}
which rustc manages to figure out. (This isn't related to integer type variables / fallback, it's just an easy way to get a type variable.)
The SLG solver gives Ambiguous; definite substitution for<?U0> { [?0 := ^0.0, ?1 := (Iterator::Item)<Range<^0.0>>] }
, which is also not very helpful, but that's related to other problems, I think.
I haven't really looked into why this doesn't work in the recursive solver or how to fix it; I think it may be that the solver just gives up too early when one subgoal flounders (in this case the ?0: Step
goal). It could be a good first issue for getting into the recursive solver. It may be more complicated though.
This issue has been assigned to @Mcat12 via this comment.