Skip to content

Commit 4ac1908

Browse files
Rollup merge of rust-lang#135304 - steffahn:tests_from_132289, r=compiler-errors
Add tests cases from review of rust-lang#132289 Adding my comments as test-cases as suggested by `@jackh726` in rust-lang#132289 (comment)
2 parents f85b79a + 5e50518 commit 4ac1908

6 files changed

+178
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
pub type A = &'static [usize; 1];
2+
pub type B = &'static [usize; 100];
3+
4+
pub trait Trait<P> {
5+
type Assoc;
6+
}
7+
8+
pub type Dyn<P> = dyn Trait<P, Assoc = A>;
9+
10+
pub trait LocallyUnimplemented<P> {}
11+
12+
impl<P, T: ?Sized> Trait<P> for T
13+
where
14+
T: LocallyUnimplemented<P>,
15+
{
16+
type Assoc = B;
17+
}
18+
19+
trait MakeArray<Arr> {
20+
fn make() -> &'static Arr;
21+
}
22+
impl<const N: usize> MakeArray<[usize; N]> for () {
23+
fn make() -> &'static [usize; N] {
24+
&[1337; N]
25+
}
26+
}
27+
28+
// it would be sound for this return type to be interpreted as being
29+
// either of A or B, if that's what a soundness fix for overlap of
30+
// dyn Trait's impls would entail
31+
32+
// In this test, we check at the call-site that the interpretation
33+
// is consistent across crates in this specific scenario.
34+
pub fn function<P>() -> (<Dyn<P> as Trait<P>>::Assoc, usize) {
35+
let val = <() as MakeArray<_>>::make();
36+
(val, val.len())
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::ops::Index;
2+
3+
pub trait Trait {
4+
fn f(&self)
5+
where
6+
dyn Index<(), Output = ()>: Index<()>;
7+
// rustc (correctly) determines ^^^^^^^^ this bound to be true
8+
}
9+
10+
pub fn call(x: &dyn Trait) {
11+
x.f(); // so we can call `f`
12+
}
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// This is a regression test for issues that came up during review of the (closed)
2+
// PR #132289; this single-crate test case is
3+
// the first example from @steffahn during review.
4+
// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564492153
5+
6+
//@ check-pass
7+
8+
type A = &'static [usize; 1];
9+
type B = &'static [usize; 100];
10+
11+
type DynSomething = dyn Something<Assoc = A>;
12+
13+
trait Super {
14+
type Assoc;
15+
}
16+
impl Super for Foo {
17+
type Assoc = A;
18+
}
19+
20+
trait IsDynSomething {}
21+
impl IsDynSomething for DynSomething {}
22+
23+
impl<T: ?Sized> Super for T
24+
where
25+
T: IsDynSomething,
26+
{
27+
type Assoc = B;
28+
}
29+
30+
trait Something: Super {
31+
fn method(&self) -> Self::Assoc;
32+
}
33+
34+
struct Foo;
35+
impl Something for Foo {
36+
fn method(&self) -> Self::Assoc {
37+
&[1337]
38+
}
39+
}
40+
41+
fn main() {
42+
let x = &Foo;
43+
let y: &DynSomething = x;
44+
45+
// no surprises here
46+
let _arr1: A = x.method();
47+
48+
// this (`_arr2`) can't ever become B either, soundly
49+
let _arr2: A = y.method();
50+
// there aren't any other arrays being defined anywhere in this
51+
// test case, besides the length-1 one containing [1337]
52+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// This is a regression test for issues that came up during review of the (closed)
2+
// PR #132289; this 2-crate test case is adapted from
3+
// the second example from @steffahn during review.
4+
// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564587796
5+
6+
//@ run-pass
7+
//@ aux-build: pr_review_132289_2_lib.rs
8+
9+
extern crate pr_review_132289_2_lib;
10+
11+
use pr_review_132289_2_lib::{function, Dyn, LocallyUnimplemented};
12+
13+
struct Param;
14+
15+
impl LocallyUnimplemented<Param> for Dyn<Param> {}
16+
17+
// it would be sound for `function::<Param>`'s return type to be
18+
// either of A or B, if that's what a soundness fix for overlap of
19+
// dyn Trait's impls would entail
20+
21+
// In this test, we check at this call-site that the interpretation
22+
// is consistent with the function definition's body.
23+
fn main() {
24+
let (arr, len) = function::<Param>();
25+
assert_eq!(arr.len(), len);
26+
}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// This is a regression test for issues that came up during review of the (closed)
2+
// PR #132289; this 3-ish-crate (including std) test case is adapted from
3+
// the third example from @steffahn during review.
4+
// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564599221
5+
6+
//@ run-pass
7+
//@ check-run-results
8+
//@ aux-build: pr_review_132289_3_lib.rs
9+
10+
extern crate pr_review_132289_3_lib;
11+
12+
use std::ops::Index;
13+
14+
use pr_review_132289_3_lib::{call, Trait};
15+
16+
trait SubIndex<I>: Index<I> {}
17+
18+
struct Param;
19+
20+
trait Project {
21+
type Ty: ?Sized;
22+
}
23+
impl Project for () {
24+
type Ty = dyn SubIndex<Param, Output = ()>;
25+
}
26+
27+
impl Index<Param> for <() as Project>::Ty {
28+
type Output = ();
29+
30+
fn index(&self, _: Param) -> &() {
31+
&()
32+
}
33+
}
34+
35+
struct Struct;
36+
37+
impl Trait for Struct {
38+
fn f(&self)
39+
where
40+
// higher-ranked to allow potentially-false bounds
41+
for<'a> dyn Index<(), Output = ()>: Index<()>,
42+
// after #132289 rustc used to believe this bound false
43+
{
44+
println!("hello!");
45+
}
46+
}
47+
48+
fn main() {
49+
call(&Struct); // <- would segfault if the method `f` wasn't part of the vtable
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello!

0 commit comments

Comments
 (0)