Don't check for alias bounds in liveness when aliases have escaping bound vars

This commit is contained in:
Michael Goulet 2023-10-31 21:43:19 +00:00
parent 46455dc650
commit 4d5d763e05
4 changed files with 64 additions and 1 deletions

View File

@ -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 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
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.

View File

@ -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() {}

View File

@ -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`.

View File

@ -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() {}