Skip to content

Commit 77b578f

Browse files
authored
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 #116040 (comment) and #59402 (comment) so that we make sure not to regress them the next time that we relax the opaque capture rules :^)
2 parents 456139f + 3a0799d commit 77b578f

6 files changed

+134
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This test should never pass!
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
trait Captures<'a> {}
6+
impl<T> Captures<'_> for T {}
7+
8+
struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
9+
unsafe impl Send for MyTy<'_, 'static> {}
10+
11+
fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a {
12+
MyTy::<'a, 'b>(None)
13+
}
14+
15+
fn step2<'a, 'b: 'a>() -> impl Sized + 'a {
16+
step1::<'a, 'b>()
17+
//~^ ERROR hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds
18+
}
19+
20+
fn step3<'a, 'b: 'a>() -> impl Send + 'a {
21+
step2::<'a, 'b>()
22+
// This should not be Send unless `'b: 'static`
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0700]: hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds
2+
--> $DIR/rpit-hidden-erased-unsoundness.rs:16:5
3+
|
4+
LL | fn step2<'a, 'b: 'a>() -> impl Sized + 'a {
5+
| -- --------------- opaque type defined here
6+
| |
7+
| hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here
8+
LL | step1::<'a, 'b>()
9+
| ^^^^^^^^^^^^^^^^^
10+
|
11+
help: to declare that `impl Sized + 'a` captures `'b`, you can add an explicit `'b` lifetime bound
12+
|
13+
LL | fn step2<'a, 'b: 'a>() -> impl Sized + 'a + 'b {
14+
| ++++
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0700`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This test should never pass!
2+
3+
use std::cell::RefCell;
4+
use std::rc::Rc;
5+
6+
trait Swap: Sized {
7+
fn swap(self, other: Self);
8+
}
9+
10+
impl<T> Swap for Rc<RefCell<T>> {
11+
fn swap(self, other: Self) {
12+
<RefCell<T>>::swap(&self, &other);
13+
}
14+
}
15+
16+
fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
17+
x
18+
//~^ ERROR hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds
19+
}
20+
21+
fn dangle() -> &'static [i32; 3] {
22+
let long = Rc::new(RefCell::new(&[4, 5, 6]));
23+
let x = [1, 2, 3];
24+
let short = Rc::new(RefCell::new(&x));
25+
hide(long.clone()).swap(hide(short));
26+
let res: &'static [i32; 3] = *long.borrow();
27+
res
28+
}
29+
30+
fn main() {
31+
println!("{:?}", dangle());
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0700]: hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds
2+
--> $DIR/rpit-hide-lifetime-for-swap.rs:17:5
3+
|
4+
LL | fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
5+
| -- -------------- opaque type defined here
6+
| |
7+
| hidden type `Rc<RefCell<&'b T>>` captures the lifetime `'b` as defined here
8+
LL | x
9+
| ^
10+
|
11+
help: to declare that `impl Swap + 'a` captures `'b`, you can add an explicit `'b` lifetime bound
12+
|
13+
LL | fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a + 'b {
14+
| ++++
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0700`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// This test should never pass!
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
trait Captures<'a> {}
6+
impl<T> Captures<'_> for T {}
7+
8+
struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
9+
unsafe impl Send for MyTy<'_, 'static> {}
10+
11+
fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a {
12+
MyTy::<'a, 'b>(None)
13+
}
14+
15+
mod tait {
16+
type Tait<'a> = impl Sized + 'a;
17+
pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> {
18+
super::step1::<'a, 'b>()
19+
//~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
20+
}
21+
}
22+
23+
fn step3<'a, 'b: 'a>() -> impl Send + 'a {
24+
tait::step2::<'a, 'b>()
25+
// This should not be Send unless `'b: 'static`
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0700]: hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
2+
--> $DIR/tait-hidden-erased-unsoundness.rs:18:9
3+
|
4+
LL | type Tait<'a> = impl Sized + 'a;
5+
| --------------- opaque type defined here
6+
LL | pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> {
7+
| -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here
8+
LL | super::step1::<'a, 'b>()
9+
| ^^^^^^^^^^^^^^^^^^^^^^^^
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0700`.

0 commit comments

Comments
 (0)