diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 9af10966eda..ed01b93f133 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -234,12 +234,10 @@ pub trait Unsize { /// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's /// managing some resource besides its own [`size_of::()`] bytes. /// -/// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get a -/// compile-time error. Specifically, with structs you'll get [E0204] and with enums you'll get -/// [E0205]. +/// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get +/// the error [E0204]. /// /// [E0204]: ../../error-index.html#E0204 -/// [E0205]: ../../error-index.html#E0205 /// /// ## When *should* my type be `Copy`? /// diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 34c07d442e3..0b1030f74b0 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -15,7 +15,7 @@ use hir::map::DefPathData; use infer::InferCtxt; use hir::map as ast_map; use traits::{self, Reveal}; -use ty::{self, Ty, AdtKind, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; +use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; use ty::{Disr, ParameterEnvironment}; use ty::fold::TypeVisitor; use ty::layout::{Layout, LayoutError}; @@ -120,9 +120,8 @@ impl IntTypeExt for attr::IntType { #[derive(Copy, Clone)] -pub enum CopyImplementationError { - InfrigingField(Name), - InfrigingVariant(Name), +pub enum CopyImplementationError<'tcx> { + InfrigingField(&'tcx ty::FieldDef), NotAnAdt, HasDestructor } @@ -145,7 +144,7 @@ pub enum Representability { impl<'tcx> ParameterEnvironment<'tcx> { pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, self_type: Ty<'tcx>, span: Span) - -> Result<(),CopyImplementationError> { + -> Result<(), CopyImplementationError> { // FIXME: (@jroesch) float this code up tcx.infer_ctxt(None, Some(self.clone()), Reveal::NotSpecializable).enter(|infcx| { let (adt, substs) = match self_type.sty { @@ -161,23 +160,10 @@ impl<'tcx> ParameterEnvironment<'tcx> { } }; - match adt.adt_kind() { - AdtKind::Struct | AdtKind::Union => { - for field in adt.all_fields() { - if !field_implements_copy(field) { - return Err(CopyImplementationError::InfrigingField( - field.name)) - } - } - } - AdtKind::Enum => { - for variant in &adt.variants { - for field in &variant.fields { - if !field_implements_copy(field) { - return Err(CopyImplementationError::InfrigingVariant( - variant.name)) - } - } + for variant in &adt.variants { + for field in &variant.fields { + if !field_implements_copy(field) { + return Err(CopyImplementationError::InfrigingField(field)); } } } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index d6eb7d4b183..d067cb99aa0 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -121,15 +121,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: match param_env.can_type_implement_copy(tcx, self_type, span) { Ok(()) => {} - Err(CopyImplementationError::InfrigingField(name)) => { - struct_span_err!(tcx.sess, - span, - E0204, - "the trait `Copy` may not be implemented for this type") - .span_label(span, &format!("field `{}` does not implement `Copy`", name)) - .emit() - } - Err(CopyImplementationError::InfrigingVariant(name)) => { + Err(CopyImplementationError::InfrigingField(field)) => { let item = tcx.map.expect_item(impl_node_id); let span = if let ItemImpl(.., Some(ref tr), _, _) = item.node { tr.path.span @@ -139,10 +131,11 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: struct_span_err!(tcx.sess, span, - E0205, + E0204, "the trait `Copy` may not be implemented for this type") - .span_label(span, - &format!("variant `{}` does not implement `Copy`", name)) + .span_label( + tcx.def_span(field.did), + &"this field does not implement `Copy`") .emit() } Err(CopyImplementationError::NotAnAdt) => { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index d3b671f2a4d..1a971be64d8 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -2300,6 +2300,7 @@ This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this differs from the behavior for `&T`, which is always `Copy`). "##, +/* E0205: r##" An attempt to implement the `Copy` trait for an enum failed because one of the variants does not implement `Copy`. To fix this, you must implement `Copy` for @@ -2329,6 +2330,7 @@ enum Foo<'a> { This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this differs from the behavior for `&T`, which is always `Copy`). "##, +*/ E0206: r##" You can only implement `Copy` for a struct or enum. Both of the following diff --git a/src/test/compile-fail/E0205.rs b/src/test/compile-fail/E0205.rs deleted file mode 100644 index c73e7534301..00000000000 --- a/src/test/compile-fail/E0205.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 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. - -enum Foo { - Bar(Vec), - Baz, -} - -impl Copy for Foo { } -//~^ ERROR the trait `Copy` may not be implemented for this type -//~| NOTE variant `Bar` does not implement `Copy` - -#[derive(Copy)] -//~^ ERROR the trait `Copy` may not be implemented for this type -//~| NOTE variant `Bar` does not implement `Copy` -//~| NOTE in this expansion of #[derive(Copy)] -enum Foo2<'a> { - Bar(&'a mut bool), - Baz, -} - -fn main() { -} diff --git a/src/test/compile-fail/E0204.rs b/src/test/ui/span/E0204.rs similarity index 77% rename from src/test/compile-fail/E0204.rs rename to src/test/ui/span/E0204.rs index 0f108a17c95..9fb37607c7d 100644 --- a/src/test/compile-fail/E0204.rs +++ b/src/test/ui/span/E0204.rs @@ -13,16 +13,24 @@ struct Foo { } impl Copy for Foo { } -//~^ ERROR E0204 -//~| NOTE field `foo` does not implement `Copy` #[derive(Copy)] -//~^ ERROR E0204 -//~| NOTE field `ty` does not implement `Copy` -//~| NOTE in this expansion of #[derive(Copy)] struct Foo2<'a> { ty: &'a mut bool, } +enum EFoo { + Bar { x: Vec }, + Baz, +} + +impl Copy for EFoo { } + +#[derive(Copy)] +enum EFoo2<'a> { + Bar(&'a mut bool), + Baz, +} + fn main() { } diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr new file mode 100644 index 00000000000..ae543ed1a5d --- /dev/null +++ b/src/test/ui/span/E0204.stderr @@ -0,0 +1,38 @@ +error[E0204]: the trait `Copy` may not be implemented for this type + --> $DIR/E0204.rs:29:10 + | +29 | #[derive(Copy)] + | ^^^^ +30 | enum EFoo2<'a> { +31 | Bar(&'a mut bool), + | ------------- this field does not implement `Copy` + +error[E0204]: the trait `Copy` may not be implemented for this type + --> $DIR/E0204.rs:17:10 + | +17 | #[derive(Copy)] + | ^^^^ +18 | struct Foo2<'a> { +19 | ty: &'a mut bool, + | ---------------- this field does not implement `Copy` + +error[E0204]: the trait `Copy` may not be implemented for this type + --> $DIR/E0204.rs:27:6 + | +23 | Bar { x: Vec }, + | ----------- this field does not implement `Copy` +... +27 | impl Copy for EFoo { } + | ^^^^ + +error[E0204]: the trait `Copy` may not be implemented for this type + --> $DIR/E0204.rs:15:6 + | +12 | foo: Vec, + | ------------- this field does not implement `Copy` +... +15 | impl Copy for Foo { } + | ^^^^ + +error: aborting due to 4 previous errors +