about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-01-03 23:54:12 +0200
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-01-04 00:03:34 +0200
commit4cab2931c89fe09dfa295445ad491c2ece7e7df1 (patch)
tree2cda1054aa58a957a67486f4cd510ad8731735d6
parente41920a1c304487e64506adf27100a224c6ef6e6 (diff)
downloadrust-4cab2931c89fe09dfa295445ad491c2ece7e7df1.tar.gz
rust-4cab2931c89fe09dfa295445ad491c2ece7e7df1.zip
simplify Copy implementation error reporting
Span the affected fields instead of reporting the field/variant name.
-rw-r--r--src/libcore/marker.rs6
-rw-r--r--src/librustc/ty/util.rs30
-rw-r--r--src/librustc_typeck/coherence/builtin.rs17
-rw-r--r--src/librustc_typeck/diagnostics.rs2
-rw-r--r--src/test/compile-fail/E0205.rs30
-rw-r--r--src/test/ui/span/E0204.rs (renamed from src/test/compile-fail/E0204.rs)18
-rw-r--r--src/test/ui/span/E0204.stderr38
7 files changed, 68 insertions, 73 deletions
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<T: ?Sized> {
 /// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's
 /// managing some resource besides its own [`size_of::<T>()`] 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 <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.
-
-enum Foo {
-    Bar(Vec<u32>),
-    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
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<u32> },
+    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<u32> },
+   |           ----------- 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<u32>,
+   |     ------------- this field does not implement `Copy`
+...
+15 | impl Copy for Foo { }
+   |      ^^^^
+
+error: aborting due to 4 previous errors
+