Skip to content

Commit

Permalink
Auto merge of #117466 - compiler-errors:alias-bound, r=aliemjay
Browse files Browse the repository at this point in the history
Don't check for alias bounds in liveness when aliases have escaping bound vars

I actually have no idea how we *should* be treating aliases with escaping bound vars here... but the simplest behavior is just doing what we used to do before.

r? aliemjay

Fixes #117455
  • Loading branch information
bors committed Nov 2, 2023
2 parents 62270fb + 4d5d763 commit b800c30
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
10 changes: 9 additions & 1 deletion compiler/rustc_infer/src/infer/outlives/for_liveness.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions tests/ui/borrowck/alias-liveness/escaping-bounds-2.rs
Original file line number Diff line number Diff line change
@@ -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() {}
19 changes: 19 additions & 0 deletions tests/ui/borrowck/alias-liveness/escaping-bounds-2.stderr
Original file line number Diff line number Diff line change
@@ -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`.
22 changes: 22 additions & 0 deletions tests/ui/borrowck/alias-liveness/escaping-bounds.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit b800c30

Please sign in to comment.