Description
#![feature(type_alias_impl_trait)]
type Foo<'a> = impl Fn() -> Foo<'a>;
fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
x
}
fn main() {}
this causes rustc to freeze. This is similar to
rust/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
Lines 1 to 10 in c50c62d
The only reason that this test does not hang is the following hack in fulfillment
rust/compiler/rustc_trait_selection/src/traits/fulfill.rs
Lines 711 to 733 in c50c62d
because of this hack we only try to prove <Foo as FnOnce<()>>::Output == Foo
using evaluate_obligation
which uses DefiningAnchor::Bubble
instead of the DefiningAnchor::Bind
used by typeck and fulfill directly.
The reason this breaks when using DefiningAnchor::Bind
is the following:
we call project_and_unify_type
for <Foo as FnOnce<()>>::Output == Foo
which normalizes <Foo as FnOnce<()>>::Output
to Foo
.
The issue is that we then replace Foo
with a new inference variable (if we use DefiningAnchor::Bind
) ?n
and add the item bounds of Foo
as obligations on that new inference variable:
rust/compiler/rustc_trait_selection/src/traits/project.rs
Lines 280 to 286 in c50c62d
This adds a new obligation <?n as FnOnce<()>>::Output == Foo
to the fulfillment context, even though ?n
was already constrained to Foo
again. The easiest fix is to resolve inference variables in obligations before adding them to the fulfillment context.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status