diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 09ab98745bd6a..a252ff4cd2252 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -387,21 +387,23 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { Some(id) => id, None => { return } }; - let impl_items = tcx.impl_items.borrow(); let trait_impls = match tcx.trait_impls.borrow().get(&drop_trait).cloned() { None => return, // No types with (new-style) dtors present. Some(found_impls) => found_impls }; for &impl_did in trait_impls.borrow().iter() { - let items = &(*impl_items)[impl_did]; - if items.len() < 1 { - // We'll error out later. For now, just don't ICE. - continue; - } - let method_def_id = items[0]; + let method_def_id = { + let items = &tcx.impl_items.borrow()[impl_did]; + if items.len() < 1 { + // We'll error out later. For now, just don't ICE. + continue; + } + items[0] + }; let self_type = self.get_self_type_for_implementation(impl_did); + match self_type.ty.sty { ty::ty_enum(type_def_id, _) | ty::ty_struct(type_def_id, _) | @@ -434,6 +436,16 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } } } + + if impl_did.krate == ast::LOCAL_CRATE { + let span = tcx.map.span(impl_did.node); + let param_env = ParameterEnvironment::for_item(tcx, impl_did.node); + if !ty::type_moves_by_default(¶m_env, span, self_type.ty) { + span_err!(tcx.sess, span, E0184, + "the `Drop` trait may not be implemented on \ + a type that implements `Copy`") + } + } } } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 9657bf82a8b81..c9e15b93ad4c5 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -157,5 +157,6 @@ register_diagnostics! { E0180, E0181, E0182, - E0183 + E0183, + E0184 } diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs new file mode 100644 index 0000000000000..3d1626041bb31 --- /dev/null +++ b/src/test/compile-fail/exclusive-drop-and-copy.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// issue #20126 + +#[derive(Copy)] +struct Foo; + +impl Drop for Foo { + //~^ ERROR the `Drop` trait may not be implemented on a type that implements `Copy` + fn drop(&mut self) {} +} + +fn main() {}