Rustdoc: Show if a type has drop glue

I don't think rustdoc currently documents whether a type has drop glue. I'm wondering if this might be a useful addition, given that the addition of drop glue to a type (either by impl Drop or adding a field with drop glue) can be a breaking change for clients. Thoughts?

9 Likes

It's useful to know about drop behaviour at the type level (e.g. because you want to make a union where one of the fields is generic), so I'm expecting Rust to eventually get a "drop is equivalent to forget" trait (TrivialDrop is a commonly suggested name). If it does, then the presence or absence of a nontrivial drop would most reasonably be shown in documentation by listing the trait in question as an autotrait.

There should also maybe be a PhantomDrop type in order to allow types to opt out of being observable as having nontrivial drop (so that they can add a Drop implementation later without breaking the downstream).

2 Likes

This seems desirable, but tricky to implement well:

On the semantic side, it's not enough to say if a type does or doesn't have drop glue. For generic types, that will depend on their argments:

/// Has drop glue iff T has drop glue.
pub struct Foo<T>(T);

/// Has drop glue iff `<T as SomeTrait>::SomeAssocType` has drop glue.
pub struct Bar<T: SomeTrait>(T::SomeAssocType);

/// Has drop glue iff `<<T as SomeTrait>::SomeAssocType as SomeTrait>::SomeAssocType>`
pub struct Baz<T: SomeTrait>(Bar<Bar<T>>);

On the UI side, it's unclear how to present this to the user. Normally rustdoc mirrors rust's syntax, but that doesn't work for derived information like this. You could put in in the "Layout" section in the bottom of the page, but that has it's own problems.

1 Like

NLL complicates this more than I realised, I see now that my original framing of the question missed the mark - it's not just whether the type ends up with drop glue, it's which generic parameters may dangle when the type is dropped:

#![allow(unused)]

struct InnerA<'a>(&'a u8);
struct InnerB<'b>(&'b u8);

// Uncommenting causes error at `x += 1`
//impl Drop for InnerA<'_> { fn drop(&mut self) {} }

// Uncommenting causes error at `y += 1`
//impl Drop for InnerB<'_> { fn drop(&mut self) {} }

pub struct Outer<'a, 'b> {
    a: InnerA<'a>,
    b: InnerB<'b>,
}

fn main() {
    let mut x = 0;
    let mut y = 0;
    let outer = Outer {
        a: InnerA(&x),
        b: InnerB(&y),
    };
    x += 1;
    y += 1;
}
2 Likes