diff --git a/tests/ui/borrowck/alias-liveness/gat-static.rs b/tests/ui/borrowck/alias-liveness/gat-static.rs index 1ab40fe828c36..92153124af932 100644 --- a/tests/ui/borrowck/alias-liveness/gat-static.rs +++ b/tests/ui/borrowck/alias-liveness/gat-static.rs @@ -8,7 +8,7 @@ trait Foo { fn assoc(&mut self) -> Self::Assoc<'_>; } -fn test(mut t: T) +fn overlapping_mut(mut t: T) where T: Foo, for<'a> T::Assoc<'a>: 'static, @@ -17,4 +17,13 @@ where let b = t.assoc(); } +fn live_past_borrow(mut t: T) +where + T: Foo, + for<'a> T::Assoc<'a>: 'static { + let x = t.assoc(); + drop(t); + drop(x); +} + fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.rs b/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.rs new file mode 100644 index 0000000000000..1f26c7babf210 --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.rs @@ -0,0 +1,16 @@ +// known-bug: #42940 + +trait Captures<'a> {} +impl Captures<'_> for T {} + +trait Outlives<'a>: 'a {} +impl<'a, T: 'a> Outlives<'a> for T {} + +// Test that we treat `for<'a> Opaque: 'a` as `Opaque: 'static` +fn test<'o>(v: &'o Vec) -> impl Captures<'o> + for<'a> Outlives<'a> {} + +fn statik() -> impl Sized { + test(&vec![]) +} + +fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr b/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr new file mode 100644 index 0000000000000..58a42d8afe4d7 --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr @@ -0,0 +1,16 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/higher-ranked-outlives-for-capture.rs:13:11 + | +LL | test(&vec![]) + | ------^^^^^^- + | | | + | | creates a temporary value which is freed while still in use + | argument requires that borrow lasts for `'static` +LL | } + | - temporary value is freed at the end of this statement + | + = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/borrowck/alias-liveness/higher-ranked.rs b/tests/ui/borrowck/alias-liveness/higher-ranked.rs new file mode 100644 index 0000000000000..afd0d3b31e3f3 --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/higher-ranked.rs @@ -0,0 +1,16 @@ +// check-pass + +trait Captures<'a> {} +impl Captures<'_> for T {} + +trait Outlives<'a>: 'a {} +impl<'a, T: 'a> Outlives<'a> for T {} + +// Test that we treat `for<'a> Opaque: 'a` as `Opaque: 'static` +fn test<'o>(v: &'o Vec) -> impl Captures<'o> + for<'a> Outlives<'a> {} + +fn opaque_doesnt_use_temporary() { + let a = test(&vec![]); +} + +fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/opaque-capture.rs b/tests/ui/borrowck/alias-liveness/opaque-capture.rs new file mode 100644 index 0000000000000..f4ca2728bdbed --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/opaque-capture.rs @@ -0,0 +1,17 @@ +// check-pass + +// Check that opaques capturing early and late-bound vars correctly mark +// regions required to be live using the item bounds. + +trait Captures<'a> {} +impl Captures<'_> for T {} + +fn captures_temp_late<'a>(x: &'a Vec) -> impl Sized + Captures<'a> + 'static {} +fn captures_temp_early<'a: 'a>(x: &'a Vec) -> impl Sized + Captures<'a> + 'static {} + +fn test() { + let x = captures_temp_early(&vec![]); + let y = captures_temp_late(&vec![]); +} + +fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/opaque-type-param.rs b/tests/ui/borrowck/alias-liveness/opaque-type-param.rs new file mode 100644 index 0000000000000..a292463b2ac45 --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/opaque-type-param.rs @@ -0,0 +1,14 @@ +// known-bug: #42940 + +trait Trait {} +impl Trait for () {} + +fn foo<'a>(s: &'a str) -> impl Trait + 'static { + bar(s) +} + +fn bar>(s: P) -> impl Trait + 'static { + () +} + +fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/opaque-type-param.stderr b/tests/ui/borrowck/alias-liveness/opaque-type-param.stderr new file mode 100644 index 0000000000000..e1fbbc14f44ee --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/opaque-type-param.stderr @@ -0,0 +1,13 @@ +error[E0700]: hidden type for `impl Trait + 'static` captures lifetime that does not appear in bounds + --> $DIR/opaque-type-param.rs:7:5 + | +LL | fn foo<'a>(s: &'a str) -> impl Trait + 'static { + | -- -------------------- opaque type defined here + | | + | hidden type `impl Trait + 'static` captures the lifetime `'a` as defined here +LL | bar(s) + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/borrowck/alias-liveness/rpit-static.rs b/tests/ui/borrowck/alias-liveness/rpit-static.rs index 8637d5fb720ea..45da3edb8780b 100644 --- a/tests/ui/borrowck/alias-liveness/rpit-static.rs +++ b/tests/ui/borrowck/alias-liveness/rpit-static.rs @@ -3,12 +3,20 @@ trait Captures<'a> {} impl Captures<'_> for T {} -fn foo(x: &i32) -> impl Sized + Captures<'_> + 'static {} +fn foo(x: &mut i32) -> impl Sized + Captures<'_> + 'static {} -fn main() { +fn overlapping_mut() { + let i = &mut 1; + let x = foo(i); + let y = foo(i); +} + +fn live_past_borrow() { let y; { - let x = 1; - y = foo(&x); + let x = &mut 1; + y = foo(x); } } + +fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/rpitit-static.rs b/tests/ui/borrowck/alias-liveness/rpitit-static.rs index ed7b496a42ba9..2cc68d2bf3d81 100644 --- a/tests/ui/borrowck/alias-liveness/rpitit-static.rs +++ b/tests/ui/borrowck/alias-liveness/rpitit-static.rs @@ -4,7 +4,13 @@ trait Foo { fn rpitit(&mut self) -> impl Sized + 'static; } -fn test(mut t: T) { +fn live_past_borrow(mut t: T) { + let x = t.rpitit(); + drop(t); + drop(x); +} + +fn overlapping_mut(mut t: T) { let a = t.rpitit(); let b = t.rpitit(); } diff --git a/tests/ui/borrowck/alias-liveness/rtn-static.rs b/tests/ui/borrowck/alias-liveness/rtn-static.rs index c850f0122e5a4..1f136b8b998b2 100644 --- a/tests/ui/borrowck/alias-liveness/rtn-static.rs +++ b/tests/ui/borrowck/alias-liveness/rtn-static.rs @@ -7,9 +7,15 @@ trait Foo { fn borrow(&mut self) -> impl Sized + '_; } +fn live_past_borrow>(mut t: T) { + let x = t.borrow(); + drop(t); + drop(x); +} + // Test that the `'_` item bound in `borrow` does not cause us to // overlook the `'static` RTN bound. -fn test>(mut t: T) { +fn overlapping_mut>(mut t: T) { let x = t.borrow(); let x = t.borrow(); } diff --git a/tests/ui/impl-trait/bivariant-lifetime-liveness.rs b/tests/ui/impl-trait/bivariant-lifetime-liveness.rs new file mode 100644 index 0000000000000..fe99fe3f34068 --- /dev/null +++ b/tests/ui/impl-trait/bivariant-lifetime-liveness.rs @@ -0,0 +1,15 @@ +// check-pass +// issue: 116794 + +// Uncaptured lifetimes should not be required to be live. + +struct Invariant(*mut T); + +fn opaque<'a: 'a>(_: &'a str) -> Invariant { + Invariant(&mut ()) +} + +fn main() { + let x = opaque(&String::new()); + drop(x); +}