1 //! Regression test for https://github.com/rust-lang/rust/issues/62211
3 //! The old implementation of defaults did not check whether the provided
4 //! default actually fulfills all bounds on the assoc. type, leading to
5 //! unsoundness, demonstrated here as a use-after-free.
7 //! Note that the underlying cause of this is still not yet fixed.
8 //! See: https://github.com/rust-lang/rust/issues/33017
10 #![feature(associated_type_defaults)]
14 ops::{AddAssign, Deref},
17 trait UncheckedCopy: Sized {
18 // This Output is said to be Copy. Yet we default to Self
19 // and it's accepted, not knowing if Self ineed is Copy
20 type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
22 // We said the Output type was Copy, so we can Copy it freely!
23 fn unchecked_copy(other: &Self::Output) -> Self::Output {
27 fn make_origin(s: Self) -> Self::Output {
32 impl<T> UncheckedCopy for T {}
34 fn bug<T: UncheckedCopy>(origin: T) {
35 let origin = T::make_origin(origin);
36 let mut copy = T::unchecked_copy(&origin);
38 // assert we indeed have 2 strings pointing to the same buffer.
39 assert_eq!(origin.as_ptr(), copy.as_ptr());
41 // Drop the origin. Any use of `copy` is UB.
44 copy += "This is invalid!";
49 bug(String::from("hello!"));