Skip to content

Drop impl on type reverses order of field destruction #16492

Closed
@lilyball

Description

@lilyball

When a type has no Drop impl, it fields appear to be destructed in order of declaration. When a type does have a Drop impl, that order is apparently reversed. This is very surprising.

Example:

#![feature(unsafe_destructor)]
#![allow(non_camel_case_types)]

struct DropMe_NoImpl {
    _one: DropMsg,
    _two: DropMsg,
    _three: DropMsg
}

struct DropMe_Impl {
    _one: DropMsg,
    _two: DropMsg,
    _three: DropMsg
}

impl Drop for DropMe_Impl {
    fn drop(&mut self) {
        println!("[IMPL] DropMe_Impl.Drop");
    }
}

struct DropMsg(&'static str);

impl Drop for DropMsg {
    fn drop(&mut self) {
        let DropMsg(msg) = *self;
        println!("{}", msg);
    }
}

pub fn main() {
    let hasImpl = DropMe_Impl {
        _one: DropMsg("[ONE] DropMe.Drop"),
        _two: DropMsg("[TWO] DropMe.Drop"),
        _three: DropMsg("[THREE] DropMe.Drop")
    };

    println!("Dropping DropMe_Impl:");
    drop(hasImpl);

    let noImpl = DropMe_NoImpl {
        _one: DropMsg("[ONE] DropMe.Drop"),
        _two: DropMsg("[TWO] DropMe.Drop"),
        _three: DropMsg("[THREE] DropMe.Drop")
    };

    println!("\nDropping DropMe_NoImpl:");
    drop(noImpl);
}

Prints:

Dropping DropMe_Impl:
[IMPL] DropMe_Impl.Drop
[THREE] DropMe.Drop
[TWO] DropMe.Drop
[ONE] DropMe.Drop

Dropping DropMe_NoImpl:
[ONE] DropMe.Drop
[TWO] DropMe.Drop
[THREE] DropMe.Drop

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions