Unify region variables when projecting associated types

This is required to avoid cycles when evaluating auto trait
predicates.
This commit is contained in:
matthewjasper 2020-06-16 18:27:40 +01:00 committed by Matthew Jasper
parent 435f97cec1
commit ba2ef58ae6
29 changed files with 133 additions and 35 deletions

View file

@ -1,8 +1,8 @@
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/project-fn-ret-invariant.rs:48:8
--> $DIR/project-fn-ret-invariant.rs:48:4
|
LL | bar(foo, x)
| ^^^
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8...
--> $DIR/project-fn-ret-invariant.rs:44:8

View file

@ -0,0 +1,34 @@
// Checking the `Send` bound in `main` requires:
//
// checking <C<'static> as Y>::P: Send
// which normalizes to Box<X<C<'?1>>>: Send
// which needs X<C<'?1>>: Send
// which needs <C<'?1> as Y>::P: Send
//
// At this point we used to normalize the predicate to `Box<X<C<'?2>>>: Send`
// and continue in a loop where we created new region variables to the
// recursion limit. To avoid this we now "canonicalize" region variables to
// lowest unified region vid. This means we instead have to prove
// `Box<X<C<'?1>>>: Send`, which we can because auto traits are coinductive.
// check-pass
// Avoid a really long error message if this regresses.
#![recursion_limit="20"]
trait Y {
type P;
}
impl<'a> Y for C<'a> {
type P = Box<X<C<'a>>>;
}
struct C<'a>(&'a ());
struct X<T: Y>(T::P);
fn is_send<S: Send>() {}
fn main() {
is_send::<X<C<'static>>>();
}

View file

@ -0,0 +1,30 @@
// Test that we don't hit the recursion limit for short cycles involving lifetimes.
// Shouldn't hit this, we should realize that we're in a cycle sooner.
#![recursion_limit="20"]
trait NotAuto {}
trait Y {
type P;
}
impl<'a> Y for C<'a> {
type P = Box<X<C<'a>>>;
}
struct C<'a>(&'a ());
struct X<T: Y>(T::P);
impl<T: NotAuto> NotAuto for Box<T> {}
impl<T: Y> NotAuto for X<T> where T::P: NotAuto {}
impl<'a> NotAuto for C<'a> {}
fn is_send<S: NotAuto>() {}
//~^ NOTE: required
fn main() {
// Should only be a few notes.
is_send::<X<C<'static>>>();
//~^ ERROR overflow evaluating
//~| NOTE: required
}

View file

@ -0,0 +1,14 @@
error[E0275]: overflow evaluating the requirement `std::boxed::Box<X<C<'_>>>: NotAuto`
--> $DIR/traits-inductive-overflow-lifetime.rs:27:5
|
LL | fn is_send<S: NotAuto>() {}
| ------- required by this bound in `is_send`
...
LL | is_send::<X<C<'static>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `NotAuto` for `X<C<'static>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0275`.