Skip to content

Commit 5fad51e

Browse files
committed
typeck::coherence::builtin - sort impls in the DefId order
this makes error messages consistent across architectures
1 parent 4cab293 commit 5fad51e

File tree

2 files changed

+56
-48
lines changed

2 files changed

+56
-48
lines changed

src/librustc_typeck/coherence/builtin.rs

+35-27
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,34 @@ use rustc::hir::map as hir_map;
2727
use rustc::hir::{self, ItemImpl};
2828

2929
pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
30-
if let Some(drop_trait) = tcx.lang_items.drop_trait() {
31-
tcx.lookup_trait_def(drop_trait)
32-
.for_each_impl(tcx, |impl_did| visit_implementation_of_drop(tcx, impl_did));
33-
}
34-
35-
if let Some(copy_trait) = tcx.lang_items.copy_trait() {
36-
tcx.lookup_trait_def(copy_trait)
37-
.for_each_impl(tcx, |impl_did| visit_implementation_of_copy(tcx, impl_did));
38-
}
39-
40-
if let Some(coerce_unsized_trait) = tcx.lang_items.coerce_unsized_trait() {
41-
let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) {
42-
Ok(id) => id,
43-
Err(err) => {
44-
tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
45-
}
46-
};
30+
check_trait(tcx, tcx.lang_items.drop_trait(), visit_implementation_of_drop);
31+
check_trait(tcx, tcx.lang_items.copy_trait(), visit_implementation_of_copy);
32+
check_trait(
33+
tcx,
34+
tcx.lang_items.coerce_unsized_trait(),
35+
visit_implementation_of_coerce_unsized);
36+
}
4737

48-
tcx.lookup_trait_def(coerce_unsized_trait).for_each_impl(tcx, |impl_did| {
49-
visit_implementation_of_coerce_unsized(tcx,
50-
impl_did,
51-
unsize_trait,
52-
coerce_unsized_trait)
38+
fn check_trait<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
39+
trait_def_id: Option<DefId>,
40+
mut f: F)
41+
where F: FnMut(TyCtxt<'a, 'tcx, 'tcx>, DefId, DefId)
42+
{
43+
if let Some(trait_def_id) = trait_def_id {
44+
let mut impls = vec![];
45+
tcx.lookup_trait_def(trait_def_id).for_each_impl(tcx, |did| {
46+
impls.push(did);
5347
});
48+
impls.sort();
49+
for impl_def_id in impls {
50+
f(tcx, trait_def_id, impl_def_id);
51+
}
5452
}
5553
}
5654

57-
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
55+
fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
56+
_drop_did: DefId,
57+
impl_did: DefId) {
5858
let items = tcx.associated_item_def_ids(impl_did);
5959
if items.is_empty() {
6060
// 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:
9696
}
9797
}
9898

99-
fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
99+
fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
100+
_copy_did: DefId,
101+
impl_did: DefId) {
100102
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
101103

102104
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:
166168
}
167169

168170
fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
169-
impl_did: DefId,
170-
unsize_trait: DefId,
171-
coerce_unsized_trait: DefId) {
171+
coerce_unsized_trait: DefId,
172+
impl_did: DefId) {
172173
debug!("visit_implementation_of_coerce_unsized: impl_did={:?}",
173174
impl_did);
174175

176+
let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) {
177+
Ok(id) => id,
178+
Err(err) => {
179+
tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
180+
}
181+
};
182+
175183
let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
176184
n
177185
} else {

src/test/ui/span/E0204.stderr

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/E0204.rs:29:10
3-
|
4-
29 | #[derive(Copy)]
5-
| ^^^^
6-
30 | enum EFoo2<'a> {
7-
31 | Bar(&'a mut bool),
8-
| ------------- this field does not implement `Copy`
9-
10-
error[E0204]: the trait `Copy` may not be implemented for this type
11-
--> $DIR/E0204.rs:17:10
2+
--> $DIR/E0204.rs:15:6
123
|
13-
17 | #[derive(Copy)]
14-
| ^^^^
15-
18 | struct Foo2<'a> {
16-
19 | ty: &'a mut bool,
17-
| ---------------- this field does not implement `Copy`
4+
12 | foo: Vec<u32>,
5+
| ------------- this field does not implement `Copy`
6+
...
7+
15 | impl Copy for Foo { }
8+
| ^^^^
189

1910
error[E0204]: the trait `Copy` may not be implemented for this type
2011
--> $DIR/E0204.rs:27:6
@@ -26,13 +17,22 @@ error[E0204]: the trait `Copy` may not be implemented for this type
2617
| ^^^^
2718

2819
error[E0204]: the trait `Copy` may not be implemented for this type
29-
--> $DIR/E0204.rs:15:6
20+
--> $DIR/E0204.rs:17:10
3021
|
31-
12 | foo: Vec<u32>,
32-
| ------------- this field does not implement `Copy`
33-
...
34-
15 | impl Copy for Foo { }
35-
| ^^^^
22+
17 | #[derive(Copy)]
23+
| ^^^^
24+
18 | struct Foo2<'a> {
25+
19 | ty: &'a mut bool,
26+
| ---------------- this field does not implement `Copy`
27+
28+
error[E0204]: the trait `Copy` may not be implemented for this type
29+
--> $DIR/E0204.rs:29:10
30+
|
31+
29 | #[derive(Copy)]
32+
| ^^^^
33+
30 | enum EFoo2<'a> {
34+
31 | Bar(&'a mut bool),
35+
| ------------- this field does not implement `Copy`
3636

3737
error: aborting due to 4 previous errors
3838

0 commit comments

Comments
 (0)