Skip to content

Commit bdb20f4

Browse files
committed
Add a test for a tait unsoundess
1 parent 0130c3a commit bdb20f4

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// known-bug: #113278
2+
// run-fail
3+
4+
#![feature(trivial_bounds, type_alias_impl_trait)]
5+
#![allow(trivial_bounds)]
6+
7+
mod sus {
8+
use super::*;
9+
pub type Sep = impl Sized + std::fmt::Display;
10+
pub fn mk_sep() -> Sep {
11+
String::from("hello")
12+
}
13+
14+
pub trait Proj {
15+
type Assoc;
16+
}
17+
impl Proj for () {
18+
type Assoc = sus::Sep;
19+
}
20+
21+
pub struct Bar<T: Proj> {
22+
pub inner: <T as Proj>::Assoc,
23+
pub _marker: T,
24+
}
25+
impl<T: Proj> Clone for Bar<T> {
26+
fn clone(&self) -> Self {
27+
todo!()
28+
}
29+
}
30+
impl<T: Proj<Assoc = i32> + Copy> Copy for Bar<T> {}
31+
pub type Tait = impl Copy + From<Bar<()>> + Into<Bar<()>>;
32+
pub fn define_tait() -> Tait
33+
where
34+
// This bound does not exist on `type Tait`, but will
35+
// constrain `Sep` to `i32`, and then forget about it.
36+
// On the other hand `mk_sep` constrains it to `String`.
37+
// Since `Tait: Copy`, we can now copy `String`s.
38+
(): Proj<Assoc = i32>,
39+
{
40+
Bar { inner: 1i32, _marker: () }
41+
}
42+
}
43+
44+
fn copy_tait(x: sus::Tait) -> (sus::Tait, sus::Tait) {
45+
(x, x)
46+
}
47+
48+
fn main() {
49+
let bar = sus::Bar { inner: sus::mk_sep(), _marker: () };
50+
let (y, z) = copy_tait(bar.into()); // copy a string
51+
drop(y.into()); // drop one instance
52+
println!("{}", z.into().inner); // print the other
53+
}

0 commit comments

Comments
 (0)