Skip to content

Commit d9d75b5

Browse files
committed
Show span for trait that doesn't implement Copy
Change error message to ```nocode error[E0205]: the trait `Copy` may not be implemented for type `Foo` --> $DIR/issue-19950.rs:17:6 | 14 | MyVariant(NoCopy) | ----------------- this variant doesn't implement `Copy` ... 17 | impl Copy for Foo {} | ^^^^ variant `Foo::MyVariant` doesn't implement `Copy` error[E0204]: the trait `Copy` may not be implemented for type `Bar` --> $DIR/issue-19950.rs:23:1 | 20 | item: NoCopy, | ------------ this field doesn't implement `Copy` ... 23 | impl Copy for Bar {} | ^^^^^^^^^^^^^^^^^^^^ field `item` in struct `Bar` doesn't implement `Copy` ```
1 parent 4ecc85b commit d9d75b5

File tree

13 files changed

+123
-32
lines changed

13 files changed

+123
-32
lines changed

src/librustc/hir/map/collector.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct NodeCollector<'ast> {
2626
/// If true, completely ignore nested items. We set this when loading
2727
/// HIR from metadata, since in that case we only want the HIR for
2828
/// one specific item (and not the ones nested inside of it).
29-
pub ignore_nested_items: bool
29+
pub ignore_nested_items: bool,
3030
}
3131

3232
impl<'ast> NodeCollector<'ast> {
@@ -35,7 +35,7 @@ impl<'ast> NodeCollector<'ast> {
3535
krate: krate,
3636
map: vec![],
3737
parent_node: CRATE_NODE_ID,
38-
ignore_nested_items: false
38+
ignore_nested_items: false,
3939
};
4040
collector.insert_entry(CRATE_NODE_ID, RootCrate);
4141

@@ -51,7 +51,7 @@ impl<'ast> NodeCollector<'ast> {
5151
krate: krate,
5252
map: map,
5353
parent_node: parent_node,
54-
ignore_nested_items: true
54+
ignore_nested_items: true,
5555
};
5656

5757
collector.insert_entry(parent_node, RootInlinedParent(parent));

src/librustc/hir/map/definitions.rs

+13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
1818
use rustc_data_structures::fx::FxHashMap;
1919
use rustc_data_structures::stable_hasher::StableHasher;
2020
use serialize::{Encodable, Decodable, Encoder, Decoder};
21+
use std::fmt;
2122
use std::fmt::Write;
2223
use std::hash::{Hash, Hasher};
2324
use syntax::ast;
@@ -220,6 +221,18 @@ impl DefPath {
220221
}
221222
}
222223

224+
impl fmt::Display for DefPath {
225+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226+
for (i, component) in self.data.iter().enumerate() {
227+
write!(f,
228+
"{}{}",
229+
if i == 0 { "" } else {"::"},
230+
component.data.as_interned_str())?;
231+
}
232+
Ok(())
233+
}
234+
}
235+
223236
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
224237
pub enum DefPathData {
225238
// Root: these should only be used for the root nodes, because

src/librustc/ty/util.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ impl IntTypeExt for attr::IntType {
115115

116116
#[derive(Copy, Clone)]
117117
pub enum CopyImplementationError {
118-
InfrigingField(Name),
119-
InfrigingVariant(Name),
118+
InfrigingField(DefId, Name),
119+
InfrigingVariant(DefId, Name),
120120
NotAnAdt,
121121
HasDestructor
122122
}
@@ -149,7 +149,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
149149
let field_ty = field.ty(tcx, substs);
150150
if infcx.type_moves_by_default(field_ty, span) {
151151
return Err(CopyImplementationError::InfrigingField(
152-
field.name))
152+
field.did, field.name))
153153
}
154154
}
155155
adt
@@ -160,7 +160,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
160160
let field_ty = field.ty(tcx, substs);
161161
if infcx.type_moves_by_default(field_ty, span) {
162162
return Err(CopyImplementationError::InfrigingVariant(
163-
variant.name))
163+
variant.did, variant.name))
164164
}
165165
}
166166
}

src/librustc_typeck/coherence/mod.rs

+29-15
Original file line numberDiff line numberDiff line change
@@ -253,29 +253,43 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
253253

254254
match param_env.can_type_implement_copy(tcx, self_type, span) {
255255
Ok(()) => {}
256-
Err(CopyImplementationError::InfrigingField(name)) => {
257-
struct_span_err!(tcx.sess,
258-
span,
259-
E0204,
260-
"the trait `Copy` may not be implemented for this type")
261-
.span_label(span, &format!("field `{}` does not implement `Copy`", name))
262-
.emit()
256+
Err(CopyImplementationError::InfrigingField(did, name)) => {
257+
let mut err = struct_span_err!(tcx.sess,
258+
span,
259+
E0204,
260+
"the trait `Copy` may not be implemented for \
261+
type `{}`",
262+
self_type);
263+
err.span_label(span,
264+
&format!("field `{}` doesn't implement `Copy`",
265+
name));
266+
if let Some(def_span) = tcx.map.span_if_local(did) {
267+
err.span_label(def_span, &"this field doesn't implement `Copy`");
268+
}
269+
err.emit()
263270
}
264-
Err(CopyImplementationError::InfrigingVariant(name)) => {
271+
Err(CopyImplementationError::InfrigingVariant(did, _)) => {
265272
let item = tcx.map.expect_item(impl_node_id);
273+
let item_def_path = tcx.map.def_path(did);
266274
let span = if let ItemImpl(.., Some(ref tr), _, _) = item.node {
267275
tr.path.span
268276
} else {
269277
span
270278
};
271279

272-
struct_span_err!(tcx.sess,
273-
span,
274-
E0205,
275-
"the trait `Copy` may not be implemented for this type")
276-
.span_label(span,
277-
&format!("variant `{}` does not implement `Copy`", name))
278-
.emit()
280+
let mut err = struct_span_err!(tcx.sess,
281+
span,
282+
E0205,
283+
"the trait `Copy` may not be implemented for \
284+
type `{}`",
285+
self_type);
286+
err.span_label(span,
287+
&format!("variant `{}` doesn't implement `Copy`",
288+
item_def_path));
289+
if let Some(def_span) = tcx.map.span_if_local(did) {
290+
err.span_label(def_span, &"this variant doesn't implement `Copy`");
291+
}
292+
err.emit()
279293
}
280294
Err(CopyImplementationError::NotAnAdt) => {
281295
let item = tcx.map.expect_item(impl_node_id);

src/test/compile-fail/E0204.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@
1010

1111
struct Foo {
1212
foo: Vec<u32>,
13+
//~^ this field doesn't implement `Copy`
1314
}
1415

1516
impl Copy for Foo { }
1617
//~^ ERROR E0204
17-
//~| NOTE field `foo` does not implement `Copy`
18+
//~| NOTE field `foo` doesn't implement `Copy`
1819

1920
#[derive(Copy)]
2021
//~^ ERROR E0204
21-
//~| NOTE field `ty` does not implement `Copy`
22+
//~| NOTE field `ty` doesn't implement `Copy`
2223
//~| NOTE in this expansion of #[derive(Copy)]
2324
struct Foo2<'a> {
2425
ty: &'a mut bool,
26+
//~^ this field doesn't implement `Copy`
2527
}
2628

2729
fn main() {

src/test/compile-fail/E0205.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@
1010

1111
enum Foo {
1212
Bar(Vec<u32>),
13+
//~^ NOTE this variant doesn't implement `Copy`
1314
Baz,
1415
}
1516

1617
impl Copy for Foo { }
17-
//~^ ERROR the trait `Copy` may not be implemented for this type
18-
//~| NOTE variant `Bar` does not implement `Copy`
18+
//~^ ERROR the trait `Copy` may not be implemented for type `Foo`
19+
//~| NOTE variant `Foo::Bar` doesn't implement `Copy`
1920

2021
#[derive(Copy)]
21-
//~^ ERROR the trait `Copy` may not be implemented for this type
22-
//~| NOTE variant `Bar` does not implement `Copy`
22+
//~^ ERROR the trait `Copy` may not be implemented for type `Foo2<'a>`
23+
//~| NOTE variant `Foo2::Bar` doesn't implement `Copy`
2324
//~| NOTE in this expansion of #[derive(Copy)]
2425
enum Foo2<'a> {
2526
Bar(&'a mut bool),
27+
//~^ NOTE this variant doesn't implement `Copy`
2628
Baz,
2729
}
2830

src/test/compile-fail/issue-27340.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
struct Foo;
1212
#[derive(Copy, Clone)]
13-
//~^ ERROR the trait `Copy` may not be implemented for this type
13+
//~^ ERROR the trait `Copy` may not be implemented for type `Bar`
1414
struct Bar(Foo);
1515

1616
fn main() {}

src/test/compile-fail/opt-in-copy.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct IWantToCopyThis {
1515
}
1616

1717
impl Copy for IWantToCopyThis {}
18-
//~^ ERROR the trait `Copy` may not be implemented for this type
18+
//~^ ERROR the trait `Copy` may not be implemented for type `IWantToCopyThis`
1919

2020
enum CantCopyThisEither {
2121
A,
@@ -27,6 +27,6 @@ enum IWantToCopyThisToo {
2727
}
2828

2929
impl Copy for IWantToCopyThisToo {}
30-
//~^ ERROR the trait `Copy` may not be implemented for this type
30+
//~^ ERROR the trait `Copy` may not be implemented for type `IWantToCopyThisToo`
3131

3232
fn main() {}

src/test/compile-fail/union/union-copy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ union W {
2121
}
2222

2323
impl Copy for U {} // OK
24-
impl Copy for W {} //~ ERROR the trait `Copy` may not be implemented for this type
24+
impl Copy for W {} //~ ERROR the trait `Copy` may not be implemented for type `W`
2525

2626
fn main() {}

src/test/ui/span/issue-19950-1.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct NoCopy;
12+
13+
struct Bar {
14+
item: NoCopy,
15+
}
16+
17+
impl Copy for Bar {}
18+
19+
fn main() {}

src/test/ui/span/issue-19950-1.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0204]: the trait `Copy` may not be implemented for type `Bar`
2+
--> $DIR/issue-19950-1.rs:17:1
3+
|
4+
14 | item: NoCopy,
5+
| ------------ this field doesn't implement `Copy`
6+
...
7+
17 | impl Copy for Bar {}
8+
| ^^^^^^^^^^^^^^^^^^^^ field `item` doesn't implement `Copy`
9+
10+
error: aborting due to previous error
11+

src/test/ui/span/issue-19950-2.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct NoCopy;
12+
13+
enum Foo {
14+
MyVariant(NoCopy)
15+
}
16+
17+
impl Copy for Foo {}
18+
19+
fn main() {}

src/test/ui/span/issue-19950-2.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0205]: the trait `Copy` may not be implemented for type `Foo`
2+
--> $DIR/issue-19950-2.rs:17:6
3+
|
4+
14 | MyVariant(NoCopy)
5+
| ----------------- this variant doesn't implement `Copy`
6+
...
7+
17 | impl Copy for Foo {}
8+
| ^^^^ variant `Foo::MyVariant` doesn't implement `Copy`
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)