Closed
Description
Please see the MessageReader::get_root
function below and the call to it in main()
. It seems that 'a
is not properly constrained.
This is related to #5121 and #12807.
// lifetimes.rs
// Like a slice.
pub struct StructReader<'a> {
buf : *u8,
len : uint,
marker : std::kinds::marker::ContravariantLifetime<'a>,
}
// Something that can be constructed from a StructReader<'a>,
// and will have the same lifetime 'a.
pub trait FromStructReader<'a> {
fn new(struct_reader : StructReader<'a>) -> Self;
}
pub struct MessageReader {
buf : ~[u8],
}
impl MessageReader {
// borrow `self` with lifetime `'a`, and construct a `T` that lives no longer than `'a`.
pub fn get_root<'a, T : FromStructReader<'a>>(&'a self) -> T {
FromStructReader::<'a>::new(
StructReader {buf : self.buf.as_ptr(),
len : self.buf.len(),
marker : std::kinds::marker::ContravariantLifetime::<'a>,
})
}
}
pub struct FooReader<'a> {
reader : StructReader<'a>
}
impl <'a> FromStructReader<'a> for FooReader<'a> {
fn new(struct_reader : StructReader<'a>) -> FooReader<'a> {
FooReader { reader : struct_reader}
}
}
impl <'a> FooReader<'a> {
pub fn get(&self, idx : uint) -> u8 {
assert!(idx < self.reader.len);
unsafe {
*self.reader.buf.offset(idx as int)
}
}
}
pub fn main () {
let bar = {
let message = MessageReader {buf : ~[1,2,3,4,5]};
let foo : FooReader = message.get_root();
foo
}; // this shouldn't typecheck, because `foo` cannot outlive `message`
let _x : ~[u8] = ~[9,9,9,9,9,9,9,9,9,9,9,9];
println!("bar.get(0) = {}", bar.get(0));
}
I expect this program not to typecheck, because it allows a FooReader
to live longer than the StructReader
it was constructed from.
However, we get:
$ rustc lifetimes.rs
$ ./lifetimes
bar.get(0) = 9