From 5fad51e7f42fc61d6e507dc3a17787534b4acbcc Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 4 Jan 2017 11:54:57 +0200 Subject: [PATCH] typeck::coherence::builtin - sort impls in the DefId order this makes error messages consistent across architectures --- src/librustc_typeck/coherence/builtin.rs | 62 +++++++++++++----------- src/test/ui/span/E0204.stderr | 42 ++++++++-------- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index d067cb99aa0..ba95a179891 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -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, + 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 { diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr index ae543ed1a5d..81a60a9dd30 100644 --- a/src/test/ui/span/E0204.stderr +++ b/src/test/ui/span/E0204.stderr @@ -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), - | ------------- 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` +12 | foo: Vec, + | ------------- this field does not implement `Copy` +... +15 | impl Copy for Foo { } + | ^^^^ 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, - | ------------- 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