Description
This code compiles on stable and it supposed to be safe:
use std::fmt::Display;
trait Printer {
fn print<P: Display>(&self, printable: P);
}
struct TestObj;
impl Printer for TestObj {
fn print<P: Display + 'static>(&self, printable: P) {}
}
fn main() {}
Rust Playground: https://play.rust-lang.org/?gist=4831916a69026aa1eb6ebca8719fddcd&version=stable&backtrace=2
But I expected to see an error like "P: 'static
appears on the impl method but not on the corresponding trait method".
Furthermore only bounds defined on the function in Trait definition are checked when I use methods on the TestObj
struct
so I can pass a non 'static
reference to the struct method print
and it assumed to be 'static
.
With that I can write something like this:
use std::fmt::Display;
trait Printer {
fn set_string<S: Display>(&mut self, S);
fn print(&self);
}
#[derive(Default)]
struct ConcretePrinter {
string: Option<Box<Display>>,
}
impl Printer for ConcretePrinter {
fn set_string<S: Display + 'static>(&mut self, string: S) {
self.string = Some(Box::new(string)); // save string for the later use
}
fn print(&self) {
self.string
.as_ref()
.map(|some_string| println!("{}", some_string));
}
}
fn main() {
let mut a = ConcretePrinter::default();
{
let heap_string = "hello".to_string();
let reference = &heap_string; // displayable but not static
a.set_string(reference); // only Printer bounds checked here
} // 'hello' string dropped
a.print(); // use after free
}
rustc 1.9.0 (e4e8b66 2016-05-18)
binary: rustc
commit-hash: e4e8b66
commit-date: 2016-05-18
host: x86_64-unknown-linux-gnu
release: 1.9.0
Rust Playground: https://play.rust-lang.org/?gist=e95ac4f83f16b062ee8b7c53ed52d5e2&version=stable&backtrace=0