Closed
Description
Due to associated defaults not being type checked whether they indeed implement all traits specified by the associated type, you can create a program in safe Rust that will segfault:
#![feature(associated_type_defaults)]
use std::{
fmt::Display,
ops::{AddAssign, Deref}
};
trait UncheckedCopy: Sized {
// 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;
// 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 mut 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!"));
}
Playground link: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=395dbcdd4da0d0b66de9fcda6e1deb13
Metadata
Metadata
Assignees
Labels
Area: Associated items (types, constants & functions)Category: This is a bug.`#![feature(associated_type_defaults)]`Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the language teamThis issue requires a nightly compiler in some way.