Open
Description
Code
#![feature(associated_type_defaults)]
use std::{
fmt::Display,
ops::{AddAssign, Deref},
};
trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
// This Output is said to be Copy. Yet we default to Self
// and it's accepted, not knowing if Self ineed is Copy
type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
//~^ ERROR the trait bound `Self: Copy` is not satisfied
//~| ERROR the trait bound `Self: Deref` is not satisfied
//~| ERROR cannot add-assign `&'static str` to `Self`
//~| ERROR `Self` doesn't implement `std::fmt::Display`
// We said the Output type was Copy, so we can Copy it freely!
fn unchecked_copy(other: &Self::Output) -> Self::Output {
(*other)
}
fn make_origin(s: Self) -> Self::Output {
s.into()
}
}
impl<T> UncheckedCopy for T {}
fn bug<T: UncheckedCopy>(origin: T) {
let origin = T::make_origin(origin);
let mut copy = T::unchecked_copy(&origin);
// assert we indeed have 2 strings pointing to the same buffer.
assert_eq!(origin.as_ptr(), copy.as_ptr());
// Drop the origin. Any use of `copy` is UB.
drop(origin);
copy += "This is invalid!";
println!("{}", copy);
}
fn main() {
bug(String::from("hello!"));
}
Current output
warning: unnecessary parentheses around block return value
--> src/lib.rs:19:9
|
19 | (*other)
| ^ ^
|
= note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
|
19 - (*other)
19 + *other
|
error[E0277]: the trait bound `T: Copy` is not satisfied
--> src/lib.rs:27:27
|
27 | impl<T> UncheckedCopy for T {}
| ^ the trait `Copy` is not implemented for `T`
|
note: required by a bound in `UncheckedCopy`
--> src/lib.rs:8:84
|
8 | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
| ^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
|
27 | impl<T: std::marker::Copy> UncheckedCopy for T {}
| +++++++++++++++++++
error[E0277]: the trait bound `T: Deref` is not satisfied
--> src/lib.rs:27:27
|
27 | impl<T> UncheckedCopy for T {}
| ^ the trait `Deref` is not implemented for `T`
|
note: required by a bound in `UncheckedCopy`
--> src/lib.rs:8:76
|
8 | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
| ^^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
|
27 | impl<T: std::ops::Deref> UncheckedCopy for T {}
| +++++++++++++++++
error[E0277]: cannot add-assign `&'static str` to `T`
--> src/lib.rs:27:27
|
27 | impl<T> UncheckedCopy for T {}
| ^ no implementation for `T += &'static str`
|
note: required by a bound in `UncheckedCopy`
--> src/lib.rs:8:50
|
8 | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
|
27 | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
| +++++++++++++++++++++++++++++++++++
error[E0277]: `T` doesn't implement `std::fmt::Display`
--> src/lib.rs:27:27
|
27 | impl<T> UncheckedCopy for T {}
| ^ `T` cannot be formatted with the default formatter
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy`
--> src/lib.rs:8:30
|
8 | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
| ^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
|
27 | impl<T: std::fmt::Display> UncheckedCopy for T {}
| +++++++++++++++++++
For more information about this error, try `rustc --explain E0277`.
Here we have several errors trying to add bounds to impl<T> UncheckedCopy for T {}
.
help: consider restricting type parameter `T`
|
27 | impl<T: std::marker::Copy> UncheckedCopy for T {}
This would work when adding only a single bound, but here we end up adding several bounds, separated by :
which causes syntax error, the "fully fixed" code ends up being
impl<T: std::marker::Copy: std::ops::Deref: std::ops::AddAssign<&'static str>: std::fmt::Display> UncheckedCopy for T {}
Can we make rust clever enough to separate these by +
?