Rollup merge of #116730 - compiler-errors:unsoundness-tests-rpit, r=aliemjay
Add some unsoundness tests for opaques capturing hidden regions not in substs Commit tests from https://github.com/rust-lang/rust/pull/116040#issuecomment-1751610237 and https://github.com/rust-lang/rust/pull/59402#issuecomment-476003242 so that we make sure not to regress them the next time that we relax the opaque capture rules :^)
This commit is contained in:
commit
77b578f72b
@ -0,0 +1,25 @@
|
|||||||
|
// This test should never pass!
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
trait Captures<'a> {}
|
||||||
|
impl<T> Captures<'_> for T {}
|
||||||
|
|
||||||
|
struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
|
||||||
|
unsafe impl Send for MyTy<'_, 'static> {}
|
||||||
|
|
||||||
|
fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a {
|
||||||
|
MyTy::<'a, 'b>(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step2<'a, 'b: 'a>() -> impl Sized + 'a {
|
||||||
|
step1::<'a, 'b>()
|
||||||
|
//~^ ERROR hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step3<'a, 'b: 'a>() -> impl Send + 'a {
|
||||||
|
step2::<'a, 'b>()
|
||||||
|
// This should not be Send unless `'b: 'static`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,18 @@
|
|||||||
|
error[E0700]: hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds
|
||||||
|
--> $DIR/rpit-hidden-erased-unsoundness.rs:16:5
|
||||||
|
|
|
||||||
|
LL | fn step2<'a, 'b: 'a>() -> impl Sized + 'a {
|
||||||
|
| -- --------------- opaque type defined here
|
||||||
|
| |
|
||||||
|
| hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here
|
||||||
|
LL | step1::<'a, 'b>()
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: to declare that `impl Sized + 'a` captures `'b`, you can add an explicit `'b` lifetime bound
|
||||||
|
|
|
||||||
|
LL | fn step2<'a, 'b: 'a>() -> impl Sized + 'a + 'b {
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0700`.
|
@ -0,0 +1,32 @@
|
|||||||
|
// This test should never pass!
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
trait Swap: Sized {
|
||||||
|
fn swap(self, other: Self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Swap for Rc<RefCell<T>> {
|
||||||
|
fn swap(self, other: Self) {
|
||||||
|
<RefCell<T>>::swap(&self, &other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
|
||||||
|
x
|
||||||
|
//~^ ERROR hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dangle() -> &'static [i32; 3] {
|
||||||
|
let long = Rc::new(RefCell::new(&[4, 5, 6]));
|
||||||
|
let x = [1, 2, 3];
|
||||||
|
let short = Rc::new(RefCell::new(&x));
|
||||||
|
hide(long.clone()).swap(hide(short));
|
||||||
|
let res: &'static [i32; 3] = *long.borrow();
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{:?}", dangle());
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
error[E0700]: hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds
|
||||||
|
--> $DIR/rpit-hide-lifetime-for-swap.rs:17:5
|
||||||
|
|
|
||||||
|
LL | fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
|
||||||
|
| -- -------------- opaque type defined here
|
||||||
|
| |
|
||||||
|
| hidden type `Rc<RefCell<&'b T>>` captures the lifetime `'b` as defined here
|
||||||
|
LL | x
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
help: to declare that `impl Swap + 'a` captures `'b`, you can add an explicit `'b` lifetime bound
|
||||||
|
|
|
||||||
|
LL | fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a + 'b {
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0700`.
|
@ -0,0 +1,28 @@
|
|||||||
|
// This test should never pass!
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
trait Captures<'a> {}
|
||||||
|
impl<T> Captures<'_> for T {}
|
||||||
|
|
||||||
|
struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
|
||||||
|
unsafe impl Send for MyTy<'_, 'static> {}
|
||||||
|
|
||||||
|
fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a {
|
||||||
|
MyTy::<'a, 'b>(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
mod tait {
|
||||||
|
type Tait<'a> = impl Sized + 'a;
|
||||||
|
pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> {
|
||||||
|
super::step1::<'a, 'b>()
|
||||||
|
//~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step3<'a, 'b: 'a>() -> impl Send + 'a {
|
||||||
|
tait::step2::<'a, 'b>()
|
||||||
|
// This should not be Send unless `'b: 'static`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,13 @@
|
|||||||
|
error[E0700]: hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
|
||||||
|
--> $DIR/tait-hidden-erased-unsoundness.rs:18:9
|
||||||
|
|
|
||||||
|
LL | type Tait<'a> = impl Sized + 'a;
|
||||||
|
| --------------- opaque type defined here
|
||||||
|
LL | pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> {
|
||||||
|
| -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here
|
||||||
|
LL | super::step1::<'a, 'b>()
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0700`.
|
Loading…
Reference in New Issue
Block a user