Skip to content

Casting a reference to a trait object reference loses lifetime information #12781

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
Aatch opened this issue Mar 9, 2014 · 4 comments
Closed
Labels
A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.

Comments

@Aatch
Copy link
Contributor

Aatch commented Mar 9, 2014

Best I can do, but it's self-contained:

trait FooTrait {
    fn do_thing(&self) -> ~str;
}
struct Container<'a> {
    things : ~[&'a FooTrait]
}

impl<'a> Container<'a> {
    fn new() -> Container {
        Container { things: ~[] }
    }
    fn add(&mut self, thing: &'a FooTrait) {
        self.things.push(thing);
    }
}

struct Foo;

impl FooTrait for Foo {
    fn do_thing(&self) -> ~str {
        ~"Test"
    }
}

fn make_foo() -> Foo {
    Foo
}

fn main() {
    let mut c = Container::new();

    for _ in range(0, 10) {
        let foo : Foo = make_foo();
        let foop : &Foo = &foo;
        let foo_obj = foop as &FooTrait;
        c.add(foo_obj);
    }

}

This compiles. It shouldn't, since foo doesn't live for long enough. If I don't do the cast (this also happens with coercion), it fails with the expected error message.

cc @nikomatsakis

@huonw
Copy link
Member

huonw commented Mar 9, 2014

Seems similar to #5723, #11374 or #11971 (particularly #11374).

@apoelstra
Copy link
Contributor

There are a lot of awfully-similar-looking lifetime bugs out there so I'm not sure where to put this, but I've got a short and sweet test case which (I believe) demonstrates this bug.

fn ret_old_memory() -> Box<Iterator<u8>> {
  box [0u8].iter().map(|n| *n) as Box<Iterator<u8>>
}

fn main() {
  println!("{:}", ret_old_memory().next());
}

Removing the .map(|n| *n) causes the compiler to correctly flag the return of a lost variable. As written this compiles (and actually works "correctly").

@alexcrichton
Copy link
Member

Fixed by #5723

@alexcrichton
Copy link
Member

Specifically #16453.

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2022
…lnicola

fix: Stack overflows and wrong type inference of associated type shorthands

This fixes `generic_predicates_for_param_query` comparing local IDs that belong to different definitions.

As the query is used in multiple places this fix affects various r-a features when an associated type shorthand and `impl Trait` involved. Notably inference, goto, completion, hover.

Fixes rust-lang#12484
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.
Projects
None yet
Development

No branches or pull requests

4 participants