]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/defaults-unsound-62211-2.rs
Rollup merge of #76468 - SNCPlay42:lifetime-names, r=Mark-Simulacrum
[rust.git] / src / test / ui / associated-types / defaults-unsound-62211-2.rs
1 //! Regression test for https://github.com/rust-lang/rust/issues/62211
2 //!
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 and ICEs, the latter being demonstrated here.
6 //!
7 //! Note that the underlying cause of this is still not yet fixed.
8 //! See: https://github.com/rust-lang/rust/issues/33017
9
10 #![feature(associated_type_defaults)]
11
12 use std::{
13     fmt::Display,
14     ops::{AddAssign, Deref},
15 };
16
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;
21     //~^ ERROR the trait bound `Self: Copy` is not satisfied
22     //~| ERROR the trait bound `Self: Deref` is not satisfied
23     //~| ERROR cannot add-assign `&'static str` to `Self`
24     //~| ERROR `Self` doesn't implement `std::fmt::Display`
25
26     // We said the Output type was Copy, so we can Copy it freely!
27     fn unchecked_copy(other: &Self::Output) -> Self::Output {
28         (*other)
29     }
30
31     fn make_origin(s: Self) -> Self::Output {
32         s.into()
33     }
34 }
35
36 impl<T> UncheckedCopy for T {}
37
38 fn bug<T: UncheckedCopy>(origin: T) {
39     let origin = T::make_origin(origin);
40     let mut copy = T::unchecked_copy(&origin);
41
42     // assert we indeed have 2 strings pointing to the same buffer.
43     assert_eq!(origin.as_ptr(), copy.as_ptr());
44
45     // Drop the origin. Any use of `copy` is UB.
46     drop(origin);
47
48     copy += "This is invalid!";
49     println!("{}", copy);
50 }
51
52 fn main() {
53     bug(());
54 }