Skip to content
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

old trait solver provisional cache does not handle changes in the cycle kind #119

Open
lcnr opened this issue Jul 9, 2024 · 0 comments
Open

Comments

@lcnr
Copy link
Contributor

lcnr commented Jul 9, 2024

struct A<T: ?Sized>(*const T);
struct B<T: ?Sized>(*const T);
struct C<T: ?Sized>(*const T);

impl<T: ?Sized> Unpin for A<T>
where
    B<T>: Unpin,
    B<T>: Inductive,
{}

impl<T: ?Sized> Unpin for B<T>
where
    A<T>: Unpin,
{}

trait Inductive {}
impl<T: ?Sized + Unpin> Inductive for T {}

fn is_unpin<T: Unpin>() {}

fn main() {
    is_unpin::<A<()>>();
}

This test should fail as A: Unpin -> B: Inductive -> B: Unpin -> A: Unpin is an inductive cycle. However, the old solver reuses the provisional cache entry of the coinductive A: Unpin -> B: Unpin -> A: Unpin cycle for B: Unpin. Changing the order of where clauses on the A<T>: Unpin impl causes this test to correctly The only place we remove provisional entries is fn on_failure or when completely done with this cycle. Idk if and how you'd get an unsoundness from that, but this explains why the old solver is fast when handling complex auto trait cycles.

It does hang during coherence when computing intercrate ambiguity causes. It recursively evaluates nested goals, but still returns Ok(None), clearing the provisional cache.

@lcnr lcnr changed the title old trait solver provisional cache does not changes in the cycle kind old trait solver provisional cache does not handle changes in the cycle kind Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant