typeck::coherence::builtin - sort impls in the DefId order

this makes error messages consistent across architectures
This commit is contained in:
Ariel Ben-Yehuda 2017-01-04 11:54:57 +02:00
parent 4cab2931c8
commit 5fad51e7f4
2 changed files with 56 additions and 48 deletions

View File

@ -27,34 +27,34 @@ use rustc::hir::map as hir_map;
use rustc::hir::{self, ItemImpl};
pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
if let Some(drop_trait) = tcx.lang_items.drop_trait() {
tcx.lookup_trait_def(drop_trait)
.for_each_impl(tcx, |impl_did| visit_implementation_of_drop(tcx, impl_did));
check_trait(tcx, tcx.lang_items.drop_trait(), visit_implementation_of_drop);
check_trait(tcx, tcx.lang_items.copy_trait(), visit_implementation_of_copy);
check_trait(
tcx,
tcx.lang_items.coerce_unsized_trait(),
visit_implementation_of_coerce_unsized);
}
if let Some(copy_trait) = tcx.lang_items.copy_trait() {
tcx.lookup_trait_def(copy_trait)
.for_each_impl(tcx, |impl_did| visit_implementation_of_copy(tcx, impl_did));
}
if let Some(coerce_unsized_trait) = tcx.lang_items.coerce_unsized_trait() {
let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) {
Ok(id) => id,
Err(err) => {
tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
}
};
tcx.lookup_trait_def(coerce_unsized_trait).for_each_impl(tcx, |impl_did| {
visit_implementation_of_coerce_unsized(tcx,
impl_did,
unsize_trait,
coerce_unsized_trait)
fn check_trait<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_def_id: Option<DefId>,
mut f: F)
where F: FnMut(TyCtxt<'a, 'tcx, 'tcx>, DefId, DefId)
{
if let Some(trait_def_id) = trait_def_id {
let mut impls = vec![];
tcx.lookup_trait_def(trait_def_id).for_each_impl(tcx, |did| {
impls.push(did);
});
impls.sort();
for impl_def_id in impls {
f(tcx, trait_def_id, impl_def_id);
}
}
}
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_drop_did: DefId,
impl_did: DefId) {
let items = tcx.associated_item_def_ids(impl_did);
if items.is_empty() {
// We'll error out later. For now, just don't ICE.
@ -96,7 +96,9 @@ fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
}
}
fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_copy_did: DefId,
impl_did: DefId) {
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
@ -166,12 +168,18 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
}
fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_did: DefId,
unsize_trait: DefId,
coerce_unsized_trait: DefId) {
coerce_unsized_trait: DefId,
impl_did: DefId) {
debug!("visit_implementation_of_coerce_unsized: impl_did={:?}",
impl_did);
let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) {
Ok(id) => id,
Err(err) => {
tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
}
};
let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
n
} else {

View File

@ -1,20 +1,11 @@
error[E0204]: the trait `Copy` may not be implemented for this type
--> $DIR/E0204.rs:29:10
--> $DIR/E0204.rs:15:6
|
29 | #[derive(Copy)]
| ^^^^
30 | enum EFoo2<'a> {
31 | Bar(&'a mut bool),
12 | foo: Vec<u32>,
| ------------- 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)]
...
15 | impl Copy for Foo { }
| ^^^^
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
@ -26,13 +17,22 @@ error[E0204]: the trait `Copy` may not be implemented for this type
| ^^^^
error[E0204]: the trait `Copy` may not be implemented for this type
--> $DIR/E0204.rs:15:6
--> $DIR/E0204.rs:17:10
|
12 | foo: Vec<u32>,
| ------------- this field does not implement `Copy`
...
15 | impl Copy for Foo { }
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:29:10
|
29 | #[derive(Copy)]
| ^^^^
30 | enum EFoo2<'a> {
31 | Bar(&'a mut bool),
| ------------- this field does not implement `Copy`
error: aborting due to 4 previous errors