]>
Commit | Line | Data |
---|---|---|
74b04a01 XL |
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 | ||
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 | |
1b1a35ee | 22 | //~^ ERROR the trait bound `Self: Copy` is not satisfied |
74b04a01 | 23 | + Deref<Target = str> |
1b1a35ee | 24 | //~^ ERROR the trait bound `Self: Deref` is not satisfied |
74b04a01 XL |
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` | |
1b1a35ee | 43 | //~| ERROR the trait bound `T: Deref` is not satisfied |
74b04a01 | 44 | //~| ERROR cannot add-assign `&'static str` to `T` |
1b1a35ee | 45 | //~| ERROR the trait bound `T: Copy` is not satisfied |
74b04a01 XL |
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(()); | |
63 | } |