diff options
| author | Michael Goulet <michael@errs.io> | 2023-10-31 21:43:19 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-11-02 10:25:57 +0000 |
| commit | 4d5d763e051fcbaf7b68d2b2c445d1cce21c35b4 (patch) | |
| tree | d78a6c8bb771c4e7ced8534012af7e0772770b68 | |
| parent | 46455dc65069387f2dc46612f13fd45452ab301a (diff) | |
| download | rust-4d5d763e051fcbaf7b68d2b2c445d1cce21c35b4.tar.gz rust-4d5d763e051fcbaf7b68d2b2c445d1cce21c35b4.zip | |
Don't check for alias bounds in liveness when aliases have escaping bound vars
4 files changed, 64 insertions, 1 deletions
diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index ebc51b98be5..398ac94ee36 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -1,4 +1,6 @@ -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use std::ops::ControlFlow; @@ -49,6 +51,12 @@ where return ControlFlow::Continue(()); } + // FIXME: Don't consider alias bounds on types that have escaping bound + // vars. See #117455. + if ty.has_escaping_bound_vars() { + return ty.super_visit_with(self); + } + match ty.kind() { // We can prove that an alias is live two ways: // 1. All the components are live. diff --git a/tests/ui/borrowck/alias-liveness/escaping-bounds-2.rs b/tests/ui/borrowck/alias-liveness/escaping-bounds-2.rs new file mode 100644 index 00000000000..05884f6741c --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/escaping-bounds-2.rs @@ -0,0 +1,14 @@ +trait Trait { + type Gat<'a: 'b, 'b: 'c, 'c>: 'c; +} + +fn get_func<'a, T: Trait>(_: &'a str) -> fn(T::Gat<'a, '_, 'static>) { + loop {} +} + +fn test<T: Trait>() { + let func = get_func::<T>(&String::new()); //~ ERROR temporary value dropped + drop(func); +} + +fn main() {} diff --git a/tests/ui/borrowck/alias-liveness/escaping-bounds-2.stderr b/tests/ui/borrowck/alias-liveness/escaping-bounds-2.stderr new file mode 100644 index 00000000000..7fd0cb9bb02 --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/escaping-bounds-2.stderr @@ -0,0 +1,19 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/escaping-bounds-2.rs:10:31 + | +LL | let func = get_func::<T>(&String::new()); + | ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | | + | creates a temporary value which is freed while still in use +LL | drop(func); + | ---- borrow later used here + | +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = String::new(); +LL ~ let func = get_func::<T>(&binding); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/borrowck/alias-liveness/escaping-bounds.rs b/tests/ui/borrowck/alias-liveness/escaping-bounds.rs new file mode 100644 index 00000000000..3ccdc78e60a --- /dev/null +++ b/tests/ui/borrowck/alias-liveness/escaping-bounds.rs @@ -0,0 +1,22 @@ +// check-pass + +// Ensure that we don't ICE when an alias that has escaping bound vars is +// required to be live. This is because the code that allows us to deduce an +// appropriate outlives bound for a given alias type (in this test, a +// projection) does not handle aliases with escaping bound vars. +// See <https://github.com/rust-lang/rust/issues/117455>. + +trait Foo { + type Assoc<'a, 'b>: 'static; +} + +struct MentionsLifetimeAndType<'a, T>(&'a (), T); + +fn foo<'a, 'b, T: Foo>(_: <T as Foo>::Assoc<'a, 'b>) {} + +fn test<'b, T: Foo>() { + let y: MentionsLifetimeAndType<'_, for<'a> fn(<T as Foo>::Assoc<'a, 'b>)> = + MentionsLifetimeAndType(&(), foo); +} + +fn main() {} |
