Skip to content

Commit

Permalink
Require that types cannot implement both Drop and Copy.
Browse files Browse the repository at this point in the history
Opt-in built-in traits allowed one to explicitly implement both `Drop`
and `Copy` for a type. This can theoretically make some sense, but the
current implementation means it is codegened totally incorrectly which
can lead to memory unsafety, so this feature is disabled for now.

Fixes #20126.
  • Loading branch information
huonw committed Jan 7, 2015
1 parent c7dd3c4 commit 3c1ca17
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 3 deletions.
9 changes: 8 additions & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6891,6 +6891,7 @@ pub enum CopyImplementationError {
FieldDoesNotImplementCopy(ast::Name),
VariantDoesNotImplementCopy(ast::Name),
TypeIsStructural,
TypeHasDestructor,
}

pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
Expand All @@ -6900,14 +6901,15 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
{
let tcx = param_env.tcx;

match self_type.sty {
let did = match self_type.sty {
ty::ty_struct(struct_did, substs) => {
let fields = ty::struct_fields(tcx, struct_did, substs);
for field in fields.iter() {
if type_moves_by_default(param_env, span, field.mt.ty) {
return Err(FieldDoesNotImplementCopy(field.name))
}
}
struct_did
}
ty::ty_enum(enum_did, substs) => {
let enum_variants = ty::enum_variants(tcx, enum_did);
Expand All @@ -6920,8 +6922,13 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
}
}
}
enum_did
}
_ => return Err(TypeIsStructural),
};

if ty::has_dtor(tcx, did) {
return Err(TypeHasDestructor)
}

Ok(())
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,11 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
for this type; type is not a structure or \
enumeration")
}
Err(ty::TypeHasDestructor) => {
span_err!(tcx.sess, span, E0184,
"the trait `Copy` may not be implemented for this type; \
the type has a destructor");
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,6 @@ register_diagnostics! {
E0180,
E0181,
E0182,
E0183
E0183,
E0184
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/drop-on-non-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

impl Drop for int {
impl<'a> Drop for &'a mut int {
//~^ ERROR the Drop trait may only be implemented on structures
//~^^ ERROR cannot provide an extension implementation
fn drop(&mut self) {
Expand Down
30 changes: 30 additions & 0 deletions src/test/compile-fail/exclusive-drop-and-copy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unsafe_destructor)]

// issue #20126

#[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
struct Foo;

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

#[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
struct Bar<T>;

#[unsafe_destructor]
impl<T> Drop for Bar<T> {
fn drop(&mut self) {}
}

fn main() {}

5 comments on commit 3c1ca17

@bors
Copy link
Contributor

@bors bors commented on 3c1ca17 Jan 8, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at huonw@3c1ca17

@bors
Copy link
Contributor

@bors bors commented on 3c1ca17 Jan 8, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging huonw/rust/no-drop-and-copy = 3c1ca17 into auto

@bors
Copy link
Contributor

@bors bors commented on 3c1ca17 Jan 8, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

status: {"merge_sha": "0cccb46aadec55ebb7b10411b22c1f51485e2702"}

@bors
Copy link
Contributor

@bors bors commented on 3c1ca17 Jan 8, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huonw/rust/no-drop-and-copy = 3c1ca17 merged ok, testing candidate = 0cccb46

Please sign in to comment.