Skip to content

Weird interaction with projections in trait bounds #43049

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sgrif opened this issue Jul 4, 2017 · 4 comments
Open

Weird interaction with projections in trait bounds #43049

sgrif opened this issue Jul 4, 2017 · 4 comments
Labels
A-type-system Area: Type system C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@sgrif
Copy link
Contributor

sgrif commented Jul 4, 2017

Reproduction case here: https://is.gd/KJTI1j.

This code should compile fine, as it's simply stating a constraint and then something attempting to use it. Regardless of whether the projection is unified with the real type or not, this code should be able to compile. Replacing the projection on line 22 with a concrete type will cause the issue to go away.

@scalexm
Copy link
Member

scalexm commented Jul 5, 2017

It seems like in the requirement T: AsExpression<<Self as Expression>::SqlType>, rustc is confused with the impl impl<T: Expression> AsExpression<T::SqlType> for T . It becomes more apparent when you replace the impl with:

impl<T> DoStuff<T> for Foo where
    T: AsExpression<<Self as Expression>::SqlType>,
    T::Expression: Expression,
    T: Expression
{}

(just added T: Expression), the compiler yields the error
type mismatch resolving `<T as Expression>::SqlType == Foo`.

However, the impl:

impl<T> DoStuff<T> for Foo where
    T: AsExpression<<T as Expression>::SqlType>,
    T::Expression: Expression,
    T: Expression
{}

compiles fine.

Coming back to your code, the main problem is that rustc tries to evaluate T as Expression (whereas it should not) which explains the error and the proposed fix ("consider adding a where T: Expression bound").

I'm investigating.

@scalexm
Copy link
Member

scalexm commented Jul 5, 2017

So I removed the impl impl<T: Expression> AsExpression<T::SqlType> for T in order to have a bit less confusion. The error is also more informative:

the trait `AsExpression<Foo>` is not implemented for `T`

So basically, the error comes from opt_normalize_projection_type not being able to project <T as AsExpression<Foo>>::Expression, and thus adding an obligation T as AsExpression<Foo> which it is unable to prove.

This seems related to the caching mechanism...

@scalexm
Copy link
Member

scalexm commented Jul 6, 2017

Ok the real culprit probably is select::match_poly_trait_ref, or rather select::match_where_clause_trait_ref which is calling the former, the call:

match_poly_trait_ref: obligation=Obligation(predicate=Binder(TraitPredicate(<T as AsExpression<Foo>>)),depth=0) poly_trait_ref=Binder(<T as AsExpression<<Foo as Expression>::SqlType>>)

fails, probably because poly_trait_ref is not normalized.

@Mark-Simulacrum Mark-Simulacrum added the A-type-system Area: Type system label Jul 19, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 28, 2017
@Spoonbender
Copy link

Triage: no change

@Noratrieb Noratrieb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 5, 2023
@fmease fmease added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Dec 21, 2024
@fmease fmease added the fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. label Feb 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants