Skip to content

Can implement coerce by packing a borrowed pointer inside a @Trait #7247

Closed
@bblum

Description

@bblum

The gist is that the kind-checker permits putting borrowed pointers into traits, which will cause the compiler to forget about the lifetime. The following program uses this to return a borrowed pointer outside of its stack frame, and then collides another stack frame into it to implement type coercion.

This will be fixed by #3569.

trait Foo<T> {
    fn get(@self) -> T;
}

struct Bar<'self, T> {
    x: &'self Option<T>,
}

impl <'self, T: Copy> Foo<T> for Bar<'self, T> {
    #[inline(always)] // Needed to avoid clobbering too early!
    fn get(@self) -> T {
        copy *self.x.get_ref()
    }
}

fn foo<T: 'static + Copy>(val: Option<T>) -> @Foo<T> {
    let x = val;
    let bar = Bar { x: &x };
    return @bar as @Foo<T>; // this is the line that should be illegal
}

fn coerce<A: 'static + Copy, B: 'static + Copy>(val: A) -> B {
    // Contains a borrowed pointer past the end of the stack.
    let x = foo(None::<B>);
    // The value passed in collides with the stack location pointed to inside x.
    // Need to call it "_z", not "_", because the latter will immediately get freed.
    let _z = foo(Some(val));
    x.get()
}
fn main() {
    let y: ~str = coerce(~[0x31u8, 0x33, 0x33, 0x37, 0]);
    println(fmt!("%?", y));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemA-type-systemArea: Type systemI-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions