1 // Test to ensure that trait bounds are properly
2 // checked on specializable associated types
4 #![allow(incomplete_features)]
5 #![feature(specialization)]
7 trait UncheckedCopy: Sized {
8 type Output: From<Self> + Copy + Into<Self>;
11 impl<T> UncheckedCopy for T {
12 default type Output = Self;
13 //~^ ERROR: the trait bound `T: Copy` is not satisfied
16 fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T {
20 fn bug(origin: String) {
21 // Turn the String into it's Output type...
22 // Which we can just do by `.into()`, the assoc type states `From<Self>`.
23 let origin_output = origin.into();
25 // Make a copy of String::Output, which is a String...
26 let mut copy: String = unchecked_copy::<String>(&origin_output);
28 // Turn the Output type into a String again,
29 // Which we can just do by `.into()`, the assoc type states `Into<Self>`.
30 let mut origin: String = origin_output.into();
32 // assert both Strings use the same buffer.
33 assert_eq!(copy.as_ptr(), origin.as_ptr());
35 // Any use of the copy we made becomes invalid,
38 // OH NO! UB UB UB UB!
39 copy.push_str(" world!");
44 bug(String::from("hello"));