Skip to content

Better guidance for projections #429

@flodiebold

Description

@flodiebold

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions