Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

Closed
Aatch opened this issue Mar 9, 2014 · 4 comments
Closed
Labels
A-lifetimes Area: Lifetimes / regions A-traits 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions A-traits 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