Skip to content

dropck seems overconservative when dealing with matches at the end of a block #22252

Closed
@sfackler

Description

@sfackler
Member
#![feature(unsafe_destructor)]
struct A;

impl Drop for A {
    fn drop(&mut self) {}
}

struct B<'a> {
    a: &'a A,
}

#[unsafe_destructor]
impl<'a> Drop for B<'a> {
    fn drop(&mut self) {}
}

impl A {
    fn b(&self) -> B {
        B { a: self }
    }
}

fn main() {
    let a = A;
    match a.b() {
        _ => {}
    }
}
test.rs:25:11: 25:12 error: `a` does not live long enough
test.rs:25     match a.b() {
                     ^
test.rs:23:11: 28:2 note: reference must be valid for the destruction scope surrounding block at 23:10...
test.rs:23 fn main() {
test.rs:24     let a = A;
test.rs:25     match a.b() {
test.rs:26         _ => {}
test.rs:27     }
test.rs:28 }
test.rs:24:14: 28:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 24:13
test.rs:24     let a = A;
test.rs:25     match a.b() {
test.rs:26         _ => {}
test.rs:27     }
test.rs:28 }
error: aborting due to previous error

Adding anything after the match (like ; or ()) causes the error to go away.

cc @pnkfelix

Activity

sfackler

sfackler commented on Feb 13, 2015

@sfackler
MemberAuthor

This may be a dup of #21114

pnkfelix

pnkfelix commented on Feb 14, 2015

@pnkfelix
Member

I think this might be a consequence of our rules for r-value temporaries, where the temporaries in the expression at the end of a block are assigned a lifetime longer than that of the let-bindings within the block itself.

But then again, that answer is not very satisfying without an example of what kind of unsoundness this is supposedly preventing. (I do not have an example ready on hand, but you've given me a place to start.)

pnkfelix

pnkfelix commented on Feb 14, 2015

@pnkfelix
Member
pnkfelix

pnkfelix commented on Feb 14, 2015

@pnkfelix
Member

also, cc #12032 ;)

theemathas

theemathas commented on Feb 23, 2015

@theemathas
Contributor

The problem does not require a match

Simpler reproduction code:

#![feature(unsafe_destructor)]

struct Foo;
struct FooRef<'a>(&'a Foo);

impl<'a> FooRef<'a> {
    fn borrow(&self) {}
}

#[unsafe_destructor]
impl<'a> Drop for FooRef<'a> {
    fn drop(&mut self) {}
}

fn main() {
    let x = Foo;
    FooRef(&x).borrow()
}

playpen

The error:

<anon>:17:13: 17:14 error: `x` does not live long enough
<anon>:17     FooRef(&x).borrow()
                      ^
<anon>:15:11: 18:2 note: reference must be valid for the destruction scope surrounding block at 15:10...
<anon>:15 fn main() {
<anon>:16     let x = Foo;
<anon>:17     FooRef(&x).borrow()
<anon>:18 }
<anon>:16:16: 18:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 16:15
<anon>:16     let x = Foo;
<anon>:17     FooRef(&x).borrow()
<anon>:18 }

10 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-destructorsArea: Destructors (`Drop`, …)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mbrubeck@steveklabnik@pnkfelix@sfackler@arielb1

        Issue actions

          dropck seems overconservative when dealing with matches at the end of a block · Issue #22252 · rust-lang/rust