Skip to content

dropck can be bypassed via associated types #26657

Closed
@arielb1

Description

@arielb1

STR

// Using this instead of Fn etc. to take HRTB out of the equation.
trait Trigger<B> { fn fire(&self, b: &mut B); }
impl<B: Button> Trigger<B> for () {
    fn fire(&self, b: &mut B) {
        b.push();
    }
}

// Still unsound Zook
trait Button { fn push(&self); }
struct Zook<B: Button> { button: B }

impl<B: Button> Drop for Zook<B> {
    fn drop(&mut self) {
        self.button.push();
    }
}


trait Associator {
    type As;
}

impl<B: Button> Associator for B {
    type As = Zook<B>;
}
struct Wrap<A: Associator>(<A as Associator>::As);

// AND
struct Bomb { usable: bool }
impl Drop for Bomb { fn drop(&mut self) { self.usable = false; } }
impl Bomb { fn activate(&self) { assert!(self.usable) } }

enum B<'a> { HarmlessButton, BigRedButton(&'a Bomb) }
impl<'a> Button for B<'a> {
    fn push(&self) {
        if let B::BigRedButton(borrowed) = *self {
            borrowed.activate();
        }
    }
}

fn main() {
    let (mut w, ticking): (Wrap<B>, _);
    w = Wrap(Zook { button: B::HarmlessButton });
    ticking = Bomb { usable: true };
    w.0.button = B::BigRedButton(&ticking);
}

Notes

This seems like just an implementation bug to me - we should check that projections are also drop-valid. cc @pnkfelix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-destructorsArea: Destructors (`Drop`, …)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions