diff options
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/ui/specialization/issue-33017.rs | 45 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-33017.stderr | 17 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-51892.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-51892.stderr | 10 |
4 files changed, 91 insertions, 0 deletions
diff --git a/src/test/ui/specialization/issue-33017.rs b/src/test/ui/specialization/issue-33017.rs new file mode 100644 index 00000000000..4d19230df6b --- /dev/null +++ b/src/test/ui/specialization/issue-33017.rs @@ -0,0 +1,45 @@ +// Test to ensure that trait bounds are propertly +// checked on specializable associated types + +#![allow(incomplete_features)] +#![feature(specialization)] + +trait UncheckedCopy: Sized { + type Output: From<Self> + Copy + Into<Self>; +} + +impl<T> UncheckedCopy for T { + default type Output = Self; + //~^ ERROR: the trait bound `T: Copy` is not satisfied +} + +fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T { + (*other).into() +} + +fn bug(origin: String) { + // Turn the String into it's Output type... + // Which we can just do by `.into()`, the assoc type states `From<Self>`. + let origin_output = origin.into(); + + // Make a copy of String::Output, which is a String... + let mut copy: String = unchecked_copy::<String>(&origin_output); + + // Turn the Output type into a String again, + // Which we can just do by `.into()`, the assoc type states `Into<Self>`. + let mut origin: String = origin_output.into(); + + // assert both Strings use the same buffer. + assert_eq!(copy.as_ptr(), origin.as_ptr()); + + // Any use of the copy we made becomes invalid, + drop(origin); + + // OH NO! UB UB UB UB! + copy.push_str(" world!"); + println!("{}", copy); +} + +fn main() { + bug(String::from("hello")); +} diff --git a/src/test/ui/specialization/issue-33017.stderr b/src/test/ui/specialization/issue-33017.stderr new file mode 100644 index 00000000000..bff4618d0be --- /dev/null +++ b/src/test/ui/specialization/issue-33017.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/issue-33017.rs:12:5 + | +LL | type Output: From<Self> + Copy + Into<Self>; + | ---- required by this bound in `UncheckedCopy::Output` +... +LL | default type Output = Self; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | impl<T: std::marker::Copy> UncheckedCopy for T { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/specialization/issue-51892.rs b/src/test/ui/specialization/issue-51892.rs new file mode 100644 index 00000000000..3cd0711ae42 --- /dev/null +++ b/src/test/ui/specialization/issue-51892.rs @@ -0,0 +1,19 @@ +#![allow(incomplete_features)] +#![feature(const_generics)] +#![feature(const_evaluatable_checked)] +#![feature(specialization)] + +pub trait Trait { + type Type; +} + +impl<T: ?Sized> Trait for T { + default type Type = [u8; 1]; +} + +impl<T: Trait> Trait for *const T { + type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()]; + //~^ ERROR: unconstrained generic constant +} + +fn main() {} diff --git a/src/test/ui/specialization/issue-51892.stderr b/src/test/ui/specialization/issue-51892.stderr new file mode 100644 index 00000000000..2d30164380a --- /dev/null +++ b/src/test/ui/specialization/issue-51892.stderr @@ -0,0 +1,10 @@ +error: unconstrained generic constant + --> $DIR/issue-51892.rs:15:5 + | +LL | type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<<T as Trait>::Type>()]:` + +error: aborting due to previous error + |
