Skip to content

Commit

Permalink
Rollup merge of rust-lang#103876 - oli-obk:tait_implications, r=lcnr
Browse files Browse the repository at this point in the history
type alias impl trait: add tests showing that hidden type only outlives lifetimes that occur in bounds

fixes rust-lang#103642

rust-lang#102417 only made sure that hidden types cannot outlive lifetimes other than the ones mentioned on bounds, but didn't allow us to actually infer anything from that.

cc `@aliemjay`
  • Loading branch information
matthiaskrgr authored Nov 29, 2022
2 parents e0098a5 + ca57832 commit 3617adf
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 6 deletions.
12 changes: 6 additions & 6 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1705,29 +1705,29 @@ impl<'tcx> RegionInferenceContext<'tcx> {
});
}

#[instrument(level = "debug", skip(self, infcx, errors_buffer))]
fn check_member_constraints(
&self,
infcx: &InferCtxt<'tcx>,
errors_buffer: &mut RegionErrors<'tcx>,
) {
let member_constraints = self.member_constraints.clone();
for m_c_i in member_constraints.all_indices() {
debug!("check_member_constraint(m_c_i={:?})", m_c_i);
debug!(?m_c_i);
let m_c = &member_constraints[m_c_i];
let member_region_vid = m_c.member_region_vid;
debug!(
"check_member_constraint: member_region_vid={:?} with value {}",
member_region_vid,
self.region_value_str(member_region_vid),
?member_region_vid,
value = ?self.region_value_str(member_region_vid),
);
let choice_regions = member_constraints.choice_regions(m_c_i);
debug!("check_member_constraint: choice_regions={:?}", choice_regions);
debug!(?choice_regions);

// Did the member region wind up equal to any of the option regions?
if let Some(o) =
choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid))
{
debug!("check_member_constraint: evaluated as equal to {:?}", o);
debug!("evaluated as equal to {:?}", o);
continue;
}

Expand Down
25 changes: 25 additions & 0 deletions src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// check-pass

#![feature(type_alias_impl_trait)]

trait Callable {
type Output;
fn call() -> Self::Output;
}

impl<'a> Callable for &'a () {
type Output = impl Sized;
fn call() -> Self::Output {}
}

fn test<'a>() -> impl Sized {
<&'a () as Callable>::call()
}

fn want_static<T: 'static>(_: T) {}

fn test2<'a>() {
want_static(<&'a () as Callable>::call());
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#![feature(type_alias_impl_trait)]

trait Callable {
type Output;
fn call(x: Self) -> Self::Output;
}

trait PlusOne {
fn plus_one(&mut self);
}

impl<'a> PlusOne for &'a mut i32 {
fn plus_one(&mut self) {
**self += 1;
}
}

impl<T: PlusOne> Callable for T {
type Output = impl PlusOne;
fn call(t: T) -> Self::Output { t }
}

fn test<'a>(y: &'a mut i32) -> impl PlusOne {
<&'a mut i32 as Callable>::call(y)
//~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
}

fn main() {
let mut z = 42;
let mut thing = test(&mut z);
let mut thing2 = test(&mut z);
thing.plus_one();
assert_eq!(z, 43);
thing2.plus_one();
assert_eq!(z, 44);
thing.plus_one();
assert_eq!(z, 45);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
--> $DIR/imply_bounds_from_bounds_param.rs:24:5
|
LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne {
| -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here
LL | <&'a mut i32 as Callable>::call(y)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound
|
LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a {
| ++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0700`.
38 changes: 38 additions & 0 deletions src/test/ui/type-alias-impl-trait/self_implication.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// check-pass

#![feature(type_alias_impl_trait)]
fn foo() {
struct Foo<'a> {
x: &'a mut u8,
}
impl<'a> Foo<'a> {
fn foo(&self) -> impl Sized {}
}
// use site
let mut x = 5;
let y = Foo { x: &mut x };
let z = y.foo();
let _a = &x; // invalidate the `&'a mut`in `y`
let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
}

fn bar() {
struct Foo<'a> {
x: &'a mut u8,
}

// desugared
type FooX<'a> = impl Sized;
impl<'a> Foo<'a> {
fn foo(&self) -> FooX<'a> {}
}

// use site
let mut x = 5;
let y = Foo { x: &mut x };
let z = y.foo();
let _a = &x; // invalidate the `&'a mut`in `y`
let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
}

fn main() {}

0 comments on commit 3617adf

Please sign in to comment.