diff options
| author | marmeladema <xademax@gmail.com> | 2021-04-23 23:09:26 +0100 |
|---|---|---|
| committer | marmeladema <xademax@gmail.com> | 2021-04-23 23:09:26 +0100 |
| commit | a657e17a7f4348bf95cbda8475cd2cc2507aea8e (patch) | |
| tree | b900d20ac82586b8b8edf74adf2ad8a674b5812f /src/test | |
| parent | 9a352326112e4fd993e339cbd4eabae06d4979b9 (diff) | |
| download | rust-a657e17a7f4348bf95cbda8475cd2cc2507aea8e.tar.gz rust-a657e17a7f4348bf95cbda8475cd2cc2507aea8e.zip | |
Add test for issue #33017
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 |
2 files changed, 62 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`. |
