]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/defaults-unsound-62211-1.rs
Auto merge of #76110 - FedericoPonzi:convert-openoptions-cint, r=JoshTriplett
[rust.git] / src / test / ui / associated-types / defaults-unsound-62211-1.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, demonstrated here as a use-after-free.
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
18 trait UncheckedCopy: Sized {
19     // This Output is said to be Copy. Yet we default to Self
20     // and it's accepted, not knowing if Self ineed is Copy
21     type Output: Copy
22     //~^ ERROR the trait bound `Self: Copy` is not satisfied
23     + Deref<Target = str>
24     //~^ ERROR the trait bound `Self: Deref` is not satisfied
25     + AddAssign<&'static str>
26     //~^ ERROR cannot add-assign `&'static str` to `Self`
27     + From<Self>
28     + Display = Self;
29     //~^ ERROR `Self` doesn't implement `std::fmt::Display`
30
31     // We said the Output type was Copy, so we can Copy it freely!
32     fn unchecked_copy(other: &Self::Output) -> Self::Output {
33         (*other)
34     }
35
36     fn make_origin(s: Self) -> Self::Output {
37         s.into()
38     }
39 }
40
41 impl<T> UncheckedCopy for T {}
42 //~^ ERROR `T` doesn't implement `std::fmt::Display`
43 //~| ERROR the trait bound `T: Deref` is not satisfied
44 //~| ERROR cannot add-assign `&'static str` to `T`
45 //~| ERROR the trait bound `T: Copy` is not satisfied
46
47 fn bug<T: UncheckedCopy>(origin: T) {
48     let origin = T::make_origin(origin);
49     let mut copy = T::unchecked_copy(&origin);
50
51     // assert we indeed have 2 strings pointing to the same buffer.
52     assert_eq!(origin.as_ptr(), copy.as_ptr());
53
54     // Drop the origin. Any use of `copy` is UB.
55     drop(origin);
56
57     copy += "This is invalid!";
58     println!("{}", copy);
59 }
60
61 fn main() {
62     bug(String::from("hello!"));
63 }