Skip to content

Commit 4cab293

Browse files
committed
simplify Copy implementation error reporting
Span the affected fields instead of reporting the field/variant name.
1 parent e41920a commit 4cab293

File tree

7 files changed

+68
-73
lines changed

7 files changed

+68
-73
lines changed

src/libcore/marker.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,10 @@ pub trait Unsize<T: ?Sized> {
234234
/// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's
235235
/// managing some resource besides its own [`size_of::<T>()`] bytes.
236236
///
237-
/// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get a
238-
/// compile-time error. Specifically, with structs you'll get [E0204] and with enums you'll get
239-
/// [E0205].
237+
/// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get
238+
/// the error [E0204].
240239
///
241240
/// [E0204]: ../../error-index.html#E0204
242-
/// [E0205]: ../../error-index.html#E0205
243241
///
244242
/// ## When *should* my type be `Copy`?
245243
///

src/librustc/ty/util.rs

+8-22
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use hir::map::DefPathData;
1515
use infer::InferCtxt;
1616
use hir::map as ast_map;
1717
use traits::{self, Reveal};
18-
use ty::{self, Ty, AdtKind, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
18+
use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
1919
use ty::{Disr, ParameterEnvironment};
2020
use ty::fold::TypeVisitor;
2121
use ty::layout::{Layout, LayoutError};
@@ -120,9 +120,8 @@ impl IntTypeExt for attr::IntType {
120120

121121

122122
#[derive(Copy, Clone)]
123-
pub enum CopyImplementationError {
124-
InfrigingField(Name),
125-
InfrigingVariant(Name),
123+
pub enum CopyImplementationError<'tcx> {
124+
InfrigingField(&'tcx ty::FieldDef),
126125
NotAnAdt,
127126
HasDestructor
128127
}
@@ -145,7 +144,7 @@ pub enum Representability {
145144
impl<'tcx> ParameterEnvironment<'tcx> {
146145
pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
147146
self_type: Ty<'tcx>, span: Span)
148-
-> Result<(),CopyImplementationError> {
147+
-> Result<(), CopyImplementationError> {
149148
// FIXME: (@jroesch) float this code up
150149
tcx.infer_ctxt(None, Some(self.clone()), Reveal::NotSpecializable).enter(|infcx| {
151150
let (adt, substs) = match self_type.sty {
@@ -161,23 +160,10 @@ impl<'tcx> ParameterEnvironment<'tcx> {
161160
}
162161
};
163162

164-
match adt.adt_kind() {
165-
AdtKind::Struct | AdtKind::Union => {
166-
for field in adt.all_fields() {
167-
if !field_implements_copy(field) {
168-
return Err(CopyImplementationError::InfrigingField(
169-
field.name))
170-
}
171-
}
172-
}
173-
AdtKind::Enum => {
174-
for variant in &adt.variants {
175-
for field in &variant.fields {
176-
if !field_implements_copy(field) {
177-
return Err(CopyImplementationError::InfrigingVariant(
178-
variant.name))
179-
}
180-
}
163+
for variant in &adt.variants {
164+
for field in &variant.fields {
165+
if !field_implements_copy(field) {
166+
return Err(CopyImplementationError::InfrigingField(field));
181167
}
182168
}
183169
}

src/librustc_typeck/coherence/builtin.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
121121

122122
match param_env.can_type_implement_copy(tcx, self_type, span) {
123123
Ok(()) => {}
124-
Err(CopyImplementationError::InfrigingField(name)) => {
125-
struct_span_err!(tcx.sess,
126-
span,
127-
E0204,
128-
"the trait `Copy` may not be implemented for this type")
129-
.span_label(span, &format!("field `{}` does not implement `Copy`", name))
130-
.emit()
131-
}
132-
Err(CopyImplementationError::InfrigingVariant(name)) => {
124+
Err(CopyImplementationError::InfrigingField(field)) => {
133125
let item = tcx.map.expect_item(impl_node_id);
134126
let span = if let ItemImpl(.., Some(ref tr), _, _) = item.node {
135127
tr.path.span
@@ -139,10 +131,11 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
139131

140132
struct_span_err!(tcx.sess,
141133
span,
142-
E0205,
134+
E0204,
143135
"the trait `Copy` may not be implemented for this type")
144-
.span_label(span,
145-
&format!("variant `{}` does not implement `Copy`", name))
136+
.span_label(
137+
tcx.def_span(field.did),
138+
&"this field does not implement `Copy`")
146139
.emit()
147140
}
148141
Err(CopyImplementationError::NotAnAdt) => {

src/librustc_typeck/diagnostics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2300,6 +2300,7 @@ This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this
23002300
differs from the behavior for `&T`, which is always `Copy`).
23012301
"##,
23022302

2303+
/*
23032304
E0205: r##"
23042305
An attempt to implement the `Copy` trait for an enum failed because one of the
23052306
variants does not implement `Copy`. To fix this, you must implement `Copy` for
@@ -2329,6 +2330,7 @@ enum Foo<'a> {
23292330
This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this
23302331
differs from the behavior for `&T`, which is always `Copy`).
23312332
"##,
2333+
*/
23322334

23332335
E0206: r##"
23342336
You can only implement `Copy` for a struct or enum. Both of the following

src/test/compile-fail/E0205.rs

-30
This file was deleted.

src/test/compile-fail/E0204.rs src/test/ui/span/E0204.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@ struct Foo {
1313
}
1414

1515
impl Copy for Foo { }
16-
//~^ ERROR E0204
17-
//~| NOTE field `foo` does not implement `Copy`
1816

1917
#[derive(Copy)]
20-
//~^ ERROR E0204
21-
//~| NOTE field `ty` does not implement `Copy`
22-
//~| NOTE in this expansion of #[derive(Copy)]
2318
struct Foo2<'a> {
2419
ty: &'a mut bool,
2520
}
2621

22+
enum EFoo {
23+
Bar { x: Vec<u32> },
24+
Baz,
25+
}
26+
27+
impl Copy for EFoo { }
28+
29+
#[derive(Copy)]
30+
enum EFoo2<'a> {
31+
Bar(&'a mut bool),
32+
Baz,
33+
}
34+
2735
fn main() {
2836
}

src/test/ui/span/E0204.stderr

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
error[E0204]: the trait `Copy` may not be implemented for this type
2+
--> $DIR/E0204.rs:29:10
3+
|
4+
29 | #[derive(Copy)]
5+
| ^^^^
6+
30 | enum EFoo2<'a> {
7+
31 | Bar(&'a mut bool),
8+
| ------------- this field does not implement `Copy`
9+
10+
error[E0204]: the trait `Copy` may not be implemented for this type
11+
--> $DIR/E0204.rs:17:10
12+
|
13+
17 | #[derive(Copy)]
14+
| ^^^^
15+
18 | struct Foo2<'a> {
16+
19 | ty: &'a mut bool,
17+
| ---------------- this field does not implement `Copy`
18+
19+
error[E0204]: the trait `Copy` may not be implemented for this type
20+
--> $DIR/E0204.rs:27:6
21+
|
22+
23 | Bar { x: Vec<u32> },
23+
| ----------- this field does not implement `Copy`
24+
...
25+
27 | impl Copy for EFoo { }
26+
| ^^^^
27+
28+
error[E0204]: the trait `Copy` may not be implemented for this type
29+
--> $DIR/E0204.rs:15:6
30+
|
31+
12 | foo: Vec<u32>,
32+
| ------------- this field does not implement `Copy`
33+
...
34+
15 | impl Copy for Foo { }
35+
| ^^^^
36+
37+
error: aborting due to 4 previous errors
38+

0 commit comments

Comments
 (0)