1
Fork 0

Add tests cases from review of #132289

This commit is contained in:
Frank Steffahn 2025-01-09 21:25:59 +01:00
parent 8247594932
commit 5e505189cd
6 changed files with 178 additions and 0 deletions

View file

@ -0,0 +1,37 @@
pub type A = &'static [usize; 1];
pub type B = &'static [usize; 100];
pub trait Trait<P> {
type Assoc;
}
pub type Dyn<P> = dyn Trait<P, Assoc = A>;
pub trait LocallyUnimplemented<P> {}
impl<P, T: ?Sized> Trait<P> for T
where
T: LocallyUnimplemented<P>,
{
type Assoc = B;
}
trait MakeArray<Arr> {
fn make() -> &'static Arr;
}
impl<const N: usize> MakeArray<[usize; N]> for () {
fn make() -> &'static [usize; N] {
&[1337; N]
}
}
// it would be sound for this return type to be interpreted as being
// either of A or B, if that's what a soundness fix for overlap of
// dyn Trait's impls would entail
// In this test, we check at the call-site that the interpretation
// is consistent across crates in this specific scenario.
pub fn function<P>() -> (<Dyn<P> as Trait<P>>::Assoc, usize) {
let val = <() as MakeArray<_>>::make();
(val, val.len())
}

View file

@ -0,0 +1,12 @@
use std::ops::Index;
pub trait Trait {
fn f(&self)
where
dyn Index<(), Output = ()>: Index<()>;
// rustc (correctly) determines ^^^^^^^^ this bound to be true
}
pub fn call(x: &dyn Trait) {
x.f(); // so we can call `f`
}

View file

@ -0,0 +1,52 @@
// This is a regression test for issues that came up during review of the (closed)
// PR #132289; this single-crate test case is
// the first example from @steffahn during review.
// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564492153
//@ check-pass
type A = &'static [usize; 1];
type B = &'static [usize; 100];
type DynSomething = dyn Something<Assoc = A>;
trait Super {
type Assoc;
}
impl Super for Foo {
type Assoc = A;
}
trait IsDynSomething {}
impl IsDynSomething for DynSomething {}
impl<T: ?Sized> Super for T
where
T: IsDynSomething,
{
type Assoc = B;
}
trait Something: Super {
fn method(&self) -> Self::Assoc;
}
struct Foo;
impl Something for Foo {
fn method(&self) -> Self::Assoc {
&[1337]
}
}
fn main() {
let x = &Foo;
let y: &DynSomething = x;
// no surprises here
let _arr1: A = x.method();
// this (`_arr2`) can't ever become B either, soundly
let _arr2: A = y.method();
// there aren't any other arrays being defined anywhere in this
// test case, besides the length-1 one containing [1337]
}

View file

@ -0,0 +1,26 @@
// This is a regression test for issues that came up during review of the (closed)
// PR #132289; this 2-crate test case is adapted from
// the second example from @steffahn during review.
// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564587796
//@ run-pass
//@ aux-build: pr_review_132289_2_lib.rs
extern crate pr_review_132289_2_lib;
use pr_review_132289_2_lib::{function, Dyn, LocallyUnimplemented};
struct Param;
impl LocallyUnimplemented<Param> for Dyn<Param> {}
// it would be sound for `function::<Param>`'s return type to be
// either of A or B, if that's what a soundness fix for overlap of
// dyn Trait's impls would entail
// In this test, we check at this call-site that the interpretation
// is consistent with the function definition's body.
fn main() {
let (arr, len) = function::<Param>();
assert_eq!(arr.len(), len);
}

View file

@ -0,0 +1,50 @@
// This is a regression test for issues that came up during review of the (closed)
// PR #132289; this 3-ish-crate (including std) test case is adapted from
// the third example from @steffahn during review.
// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564599221
//@ run-pass
//@ check-run-results
//@ aux-build: pr_review_132289_3_lib.rs
extern crate pr_review_132289_3_lib;
use std::ops::Index;
use pr_review_132289_3_lib::{call, Trait};
trait SubIndex<I>: Index<I> {}
struct Param;
trait Project {
type Ty: ?Sized;
}
impl Project for () {
type Ty = dyn SubIndex<Param, Output = ()>;
}
impl Index<Param> for <() as Project>::Ty {
type Output = ();
fn index(&self, _: Param) -> &() {
&()
}
}
struct Struct;
impl Trait for Struct {
fn f(&self)
where
// higher-ranked to allow potentially-false bounds
for<'a> dyn Index<(), Output = ()>: Index<()>,
// after #132289 rustc used to believe this bound false
{
println!("hello!");
}
}
fn main() {
call(&Struct); // <- would segfault if the method `f` wasn't part of the vtable
}

View file

@ -0,0 +1 @@
hello!