Skip to content

Copy: Clone has made dropck implementation unsound! #24895

Closed
@pnkfelix

Description

@pnkfelix

Sample code (playpen):

#![allow(unused_variables, unused_assignments)]

struct D<T:Copy>(T, &'static str);

#[derive(Copy)]
struct S<'a>(&'a D<i32>, &'static str);
impl<'a> Clone for S<'a> {
    fn clone(&self) -> S<'a> {
        println!("cloning `S(_, {})` and thus accessing: {}", self.1, (self.0).0);
        S(self.0, self.1)
    }
}

impl<T:Copy> Drop for D<T> {
    fn drop(&mut self) {
        println!("calling Drop for {}", self.1);
        let _call = self.0.clone();
    }
}

fn main() {
    let (d2, d1);
    d1 = D(34, "d1");
    d2 = D(S(&d1, "inner"), "d2");
}

The Drop Check rule, as specified in RFC 769, requires that no methods be attached to the trait in question. The trait Copy used to qualify under that criteria, but with the addition of the Copy: Clone bound, it no longer does.

The original dropck implementation took a short-cut to enforcing the criteria (by only accepting the known builtin bounds, under the assumption that none had user-defined methods), and so now it is unsound.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-highHigh priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions