1
Fork 0

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}; use rustc::hir::{self, ItemImpl};
pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
if let Some(drop_trait) = tcx.lang_items.drop_trait() { check_trait(tcx, tcx.lang_items.drop_trait(), visit_implementation_of_drop);
tcx.lookup_trait_def(drop_trait) check_trait(tcx, tcx.lang_items.copy_trait(), visit_implementation_of_copy);
.for_each_impl(tcx, |impl_did| visit_implementation_of_drop(tcx, impl_did)); check_trait(
} tcx,
tcx.lang_items.coerce_unsized_trait(),
visit_implementation_of_coerce_unsized);
}
if let Some(copy_trait) = tcx.lang_items.copy_trait() { fn check_trait<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
tcx.lookup_trait_def(copy_trait) trait_def_id: Option<DefId>,
.for_each_impl(tcx, |impl_did| visit_implementation_of_copy(tcx, impl_did)); mut f: F)
} where F: FnMut(TyCtxt<'a, 'tcx, 'tcx>, DefId, DefId)
{
if let Some(coerce_unsized_trait) = tcx.lang_items.coerce_unsized_trait() { if let Some(trait_def_id) = trait_def_id {
let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) { let mut impls = vec![];
Ok(id) => id, tcx.lookup_trait_def(trait_def_id).for_each_impl(tcx, |did| {
Err(err) => { impls.push(did);
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)
}); });
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); let items = tcx.associated_item_def_ids(impl_did);
if items.is_empty() { if items.is_empty() {
// We'll error out later. For now, just don't ICE. // 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); 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) { 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>, fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_did: DefId, coerce_unsized_trait: DefId,
unsize_trait: DefId, impl_did: DefId) {
coerce_unsized_trait: DefId) {
debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", debug!("visit_implementation_of_coerce_unsized: impl_did={:?}",
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) { let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
n n
} else { } else {

View file

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