]> git.lizzy.rs Git - rust.git/blob - tests/ui/span/dropck-object-cycle.rs
Optimize `TyKind::eq`.
[rust.git] / tests / ui / span / dropck-object-cycle.rs
1 // This test used to be part of a run-pass test, but revised outlives
2 // rule means that it no longer compiles.
3
4 #![allow(unused_variables)]
5
6 trait Trait<'a> {
7     fn long(&'a self) -> isize;
8     fn short<'b>(&'b self) -> isize;
9 }
10
11 fn object_invoke1<'d>(x: &'d dyn Trait<'d>) -> (isize, isize) { loop { } }
12
13 trait MakerTrait {
14     fn mk() -> Self;
15 }
16
17 fn make_val<T:MakerTrait>() -> T {
18     MakerTrait::mk()
19 }
20
21 impl<'t> MakerTrait for Box<dyn Trait<'t>+'static> {
22     fn mk() -> Box<dyn Trait<'t>+'static> { loop { } }
23 }
24
25 pub fn main() {
26     let m : Box<dyn Trait+'static> = make_val();
27     assert_eq!(object_invoke1(&*m), (4,5));
28     //~^ ERROR `*m` does not live long enough
29
30     // the problem here is that the full type of `m` is
31     //
32     //   Box<Trait<'m>+'static>
33     //
34     // Here `'m` must be exactly the lifetime of the variable `m`.
35     // This is because of two requirements:
36     // 1. First, the basic type rules require that the
37     //    type of `m`'s value outlives the lifetime of `m`. This puts a lower
38     //    bound `'m`.
39     //
40     // 2. Meanwhile, the signature of `object_invoke1` requires that
41     //    we create a reference of type `&'d Trait<'d>` for some `'d`.
42     //    `'d` cannot outlive `'m`, so that forces the lifetime to be `'m`.
43     //
44     // This then conflicts with the dropck rules, which require that
45     // the type of `m` *strictly outlives* `'m`. Hence we get an
46     // error.
47 }