File: fixpoint-rerun-all-cycle-heads.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 893,176 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; lisp: 29; perl: 29; ruby: 19; sql: 11
file content (65 lines) | stat: -rw-r--r-- 1,986 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//@ compile-flags: -Znext-solver
#![feature(rustc_attrs)]

// Check that we correctly rerun the trait solver for heads of cycles,
// even if they are not the root.

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

#[rustc_coinductive]
trait Trait<'a, 'b> {}
trait NotImplemented {}

impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for A<T> where B<T>: Trait<'a, 'b> {}

// With this the root of `B<T>` is `A<T>`, even if the other impl does
// not have a cycle with `A<T>`. This candidate never applies because of
// the `A<T>: NotImplemented` bound.
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B<T>
where
    A<T>: Trait<'a, 'b>,
    A<T>: NotImplemented,
{
}

// HACK: This impls is necessary so that the impl above is well-formed.
//
// When checking that the impl above is well-formed we check `B<T>: Trait<'a, 'b>`
// with the where clauses `A<T>: Trait<'a, 'b>` and `A<T> NotImplemented`. Trying to
// use the impl itself to prove that adds region constraints as we uniquified the
// regions in the `A<T>: Trait<'a, 'b>` where-bound. As both the impl above
// and the impl below now apply with some constraints, we failed with ambiguity.
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B<T>
where
    A<T>: NotImplemented,
{}

// This impl directly requires 'b to be equal to 'static.
//
// Because of the coinductive cycle through `C<T>` it also requires
// 'a to be 'static.
impl<'a, T: ?Sized> Trait<'a, 'static> for B<T>
where
    C<T>: Trait<'a, 'a>,
{}

// In the first iteration of `B<T>: Trait<'a, 'b>` we don't add any
// constraints here, only after setting the provisional result to require
// `'b == 'static` do we also add that constraint for `'a`.
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for C<T>
where
    B<T>: Trait<'a, 'b>,
{}

fn impls_trait<'a, 'b, T: Trait<'a, 'b> + ?Sized>() {}

fn check<'a, T: ?Sized>() {
    impls_trait::<'a, 'static, A<T>>();
    //~^ ERROR lifetime may not live long enough
}

fn main() {
    check::<()>();
}