Skip to content

Show span for trait that doesn't implement Copy #37493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct NodeCollector<'ast> {
/// If true, completely ignore nested items. We set this when loading
/// HIR from metadata, since in that case we only want the HIR for
/// one specific item (and not the ones nested inside of it).
pub ignore_nested_items: bool
pub ignore_nested_items: bool,
}

impl<'ast> NodeCollector<'ast> {
Expand All @@ -35,7 +35,7 @@ impl<'ast> NodeCollector<'ast> {
krate: krate,
map: vec![],
parent_node: CRATE_NODE_ID,
ignore_nested_items: false
ignore_nested_items: false,
};
collector.insert_entry(CRATE_NODE_ID, RootCrate);

Expand All @@ -51,7 +51,7 @@ impl<'ast> NodeCollector<'ast> {
krate: krate,
map: map,
parent_node: parent_node,
ignore_nested_items: true
ignore_nested_items: true,
};

collector.insert_entry(parent_node, RootInlinedParent(parent));
Expand Down
13 changes: 13 additions & 0 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use serialize::{Encodable, Decodable, Encoder, Decoder};
use std::fmt;
use std::fmt::Write;
use std::hash::{Hash, Hasher};
use syntax::ast;
Expand Down Expand Up @@ -220,6 +221,18 @@ impl DefPath {
}
}

impl fmt::Display for DefPath {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, component) in self.data.iter().enumerate() {
write!(f,
"{}{}",
if i == 0 { "" } else {"::"},
component.data.as_interned_str())?;
}
Ok(())
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum DefPathData {
// Root: these should only be used for the root nodes, because
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ impl IntTypeExt for attr::IntType {

#[derive(Copy, Clone)]
pub enum CopyImplementationError {
InfrigingField(Name),
InfrigingVariant(Name),
InfrigingField(DefId, Name),
InfrigingVariant(DefId, Name),
NotAnAdt,
HasDestructor
}
Expand Down Expand Up @@ -149,7 +149,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
let field_ty = field.ty(tcx, substs);
if infcx.type_moves_by_default(field_ty, span) {
return Err(CopyImplementationError::InfrigingField(
field.name))
field.did, field.name))
}
}
adt
Expand All @@ -160,7 +160,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
let field_ty = field.ty(tcx, substs);
if infcx.type_moves_by_default(field_ty, span) {
return Err(CopyImplementationError::InfrigingVariant(
variant.name))
variant.did, variant.name))
}
}
}
Expand Down
44 changes: 29 additions & 15 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,29 +253,43 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {

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::InfrigingField(did, name)) => {
let mut err = struct_span_err!(tcx.sess,
span,
E0204,
"the trait `Copy` may not be implemented for \
type `{}`",
self_type);
err.span_label(span,
&format!("field `{}` doesn't implement `Copy`",
name));
if let Some(def_span) = tcx.map.span_if_local(did) {
err.span_label(def_span, &"this field doesn't implement `Copy`");
}
err.emit()
}
Err(CopyImplementationError::InfrigingVariant(name)) => {
Err(CopyImplementationError::InfrigingVariant(did, _)) => {
let item = tcx.map.expect_item(impl_node_id);
let item_def_path = tcx.map.def_path(did);
let span = if let ItemImpl(.., Some(ref tr), _, _) = item.node {
tr.path.span
} else {
span
};

struct_span_err!(tcx.sess,
span,
E0205,
"the trait `Copy` may not be implemented for this type")
.span_label(span,
&format!("variant `{}` does not implement `Copy`", name))
.emit()
let mut err = struct_span_err!(tcx.sess,
span,
E0205,
"the trait `Copy` may not be implemented for \
type `{}`",
self_type);
err.span_label(span,
&format!("variant `{}` doesn't implement `Copy`",
item_def_path));
if let Some(def_span) = tcx.map.span_if_local(did) {
err.span_label(def_span, &"this variant doesn't implement `Copy`");
}
err.emit()
}
Err(CopyImplementationError::NotAnAdt) => {
let item = tcx.map.expect_item(impl_node_id);
Expand Down
6 changes: 4 additions & 2 deletions src/test/compile-fail/E0204.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@

struct Foo {
foo: Vec<u32>,
//~^ this field doesn't implement `Copy`
}

impl Copy for Foo { }
//~^ ERROR E0204
//~| NOTE field `foo` does not implement `Copy`
//~| NOTE field `foo` doesn't implement `Copy`

#[derive(Copy)]
//~^ ERROR E0204
//~| NOTE field `ty` does not implement `Copy`
//~| NOTE field `ty` doesn't implement `Copy`
//~| NOTE in this expansion of #[derive(Copy)]
struct Foo2<'a> {
ty: &'a mut bool,
//~^ this field doesn't implement `Copy`
}

fn main() {
Expand Down
10 changes: 6 additions & 4 deletions src/test/compile-fail/E0205.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@

enum Foo {
Bar(Vec<u32>),
//~^ NOTE this variant doesn't implement `Copy`
Baz,
}

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

#[derive(Copy)]
//~^ ERROR the trait `Copy` may not be implemented for this type
//~| NOTE variant `Bar` does not implement `Copy`
//~^ ERROR the trait `Copy` may not be implemented for type `Foo2<'a>`
//~| NOTE variant `Foo2::Bar` doesn't implement `Copy`
//~| NOTE in this expansion of #[derive(Copy)]
enum Foo2<'a> {
Bar(&'a mut bool),
//~^ NOTE this variant doesn't implement `Copy`
Baz,
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-27340.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

struct Foo;
#[derive(Copy, Clone)]
//~^ ERROR the trait `Copy` may not be implemented for this type
//~^ ERROR the trait `Copy` may not be implemented for type `Bar`
struct Bar(Foo);

fn main() {}
4 changes: 2 additions & 2 deletions src/test/compile-fail/opt-in-copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct IWantToCopyThis {
}

impl Copy for IWantToCopyThis {}
//~^ ERROR the trait `Copy` may not be implemented for this type
//~^ ERROR the trait `Copy` may not be implemented for type `IWantToCopyThis`

enum CantCopyThisEither {
A,
Expand All @@ -27,6 +27,6 @@ enum IWantToCopyThisToo {
}

impl Copy for IWantToCopyThisToo {}
//~^ ERROR the trait `Copy` may not be implemented for this type
//~^ ERROR the trait `Copy` may not be implemented for type `IWantToCopyThisToo`

fn main() {}
2 changes: 1 addition & 1 deletion src/test/compile-fail/union/union-copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ union W {
}

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

fn main() {}
19 changes: 19 additions & 0 deletions src/test/ui/span/issue-19950-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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.

struct NoCopy;

struct Bar {
item: NoCopy,
}

impl Copy for Bar {}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/span/issue-19950-1.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0204]: the trait `Copy` may not be implemented for type `Bar`
--> $DIR/issue-19950-1.rs:17:1
|
14 | item: NoCopy,
| ------------ this field doesn't implement `Copy`
...
17 | impl Copy for Bar {}
| ^^^^^^^^^^^^^^^^^^^^ field `item` doesn't implement `Copy`

error: aborting due to previous error

19 changes: 19 additions & 0 deletions src/test/ui/span/issue-19950-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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.

struct NoCopy;

enum Foo {
MyVariant(NoCopy)
}

impl Copy for Foo {}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/span/issue-19950-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0205]: the trait `Copy` may not be implemented for type `Foo`
--> $DIR/issue-19950-2.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: aborting due to previous error