Skip to content

Commit 9b4f811

Browse files
committed
Use more targeted spans for orphan rule errors
1 parent adfe9a4 commit 9b4f811

File tree

63 files changed

+312
-199
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+312
-199
lines changed

src/librustc/traits/coherence.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
237237
}
238238

239239
pub enum OrphanCheckErr<'tcx> {
240-
NonLocalInputType(Vec<Ty<'tcx>>),
240+
NonLocalInputType(Vec<(Ty<'tcx>, usize)>),
241241
UncoveredTy(Ty<'tcx>),
242242
}
243243

@@ -391,8 +391,10 @@ fn orphan_check_trait_ref<'tcx>(
391391
}
392392

393393
let mut non_local_spans = vec![];
394-
for input_ty in
395-
trait_ref.input_types().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
394+
for (i, input_ty) in trait_ref
395+
.input_types()
396+
.flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
397+
.enumerate()
396398
{
397399
debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
398400
if ty_is_local(tcx, input_ty, in_crate) {
@@ -402,7 +404,7 @@ fn orphan_check_trait_ref<'tcx>(
402404
debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
403405
return Err(OrphanCheckErr::UncoveredTy(input_ty))
404406
}
405-
non_local_spans.push(input_ty);
407+
non_local_spans.push((input_ty, i));
406408
}
407409
// If we exit above loop, never found a local type.
408410
debug!("orphan_check_trait_ref: no local type");
@@ -413,7 +415,7 @@ fn orphan_check_trait_ref<'tcx>(
413415
// parameters to the trait, with the self type appearing
414416
// first. Find the first input type that either references a
415417
// type parameter OR some local type.
416-
for input_ty in trait_ref.input_types() {
418+
for (i, input_ty) in trait_ref.input_types().enumerate() {
417419
if ty_is_local(tcx, input_ty, in_crate) {
418420
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
419421

@@ -442,7 +444,7 @@ fn orphan_check_trait_ref<'tcx>(
442444
return Err(OrphanCheckErr::UncoveredTy(param));
443445
}
444446

445-
non_local_spans.push(input_ty);
447+
non_local_spans.push((input_ty, i));
446448
}
447449
// If we exit above loop, never found a local type.
448450
debug!("orphan_check_trait_ref: no local type");

src/librustc_typeck/coherence/orphan.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
2424
fn visit_item(&mut self, item: &hir::Item) {
2525
let def_id = self.tcx.hir().local_def_id(item.hir_id);
2626
// "Trait" impl
27-
if let hir::ItemKind::Impl(.., Some(_), _, _) = item.kind {
27+
if let hir::ItemKind::Impl(.., generics, Some(_), impl_ty, _) = &item.kind {
2828
debug!("coherence2::orphan check: trait impl {}",
2929
self.tcx.hir().node_to_string(item.hir_id));
3030
let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
@@ -41,28 +41,43 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
4141
"only traits defined in the current crate can be implemented for \
4242
arbitrary types"
4343
);
44-
err.span_label(sp, "impl doesn't use types inside crate");
45-
for ty in &tys {
46-
err.note(&format!("`{}` is not defined in the current create", ty));
44+
err.span_label(sp, "impl doesn't use only types from inside the current crate");
45+
for (ty, i) in &tys {
46+
let msg = format!("`{}` is not defined in the current crate", ty);
47+
if *i == 0 {
48+
err.span_label(impl_ty.span, &msg);
49+
} else {
50+
err.note(&msg);
51+
}
4752
}
4853
err.note("define and implement a trait or new type instead");
4954
err.emit();
5055
return;
5156
}
5257
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
53-
struct_span_err!(self.tcx.sess,
54-
sp,
55-
E0210,
56-
"type parameter `{}` must be used as the type parameter \
57-
for some local type (e.g., `MyStruct<{}>`)",
58-
param_ty,
59-
param_ty)
60-
.span_label(sp,
61-
format!("type parameter `{}` must be used as the type \
62-
parameter for some local type", param_ty))
63-
.note("only traits defined in the current crate can be implemented \
64-
for a type parameter")
65-
.emit();
58+
let mut sp = sp;
59+
for param in &generics.params {
60+
if param.name.ident().to_string() == param_ty.to_string() {
61+
sp = param.span;
62+
}
63+
}
64+
let mut err = struct_span_err!(
65+
self.tcx.sess,
66+
sp,
67+
E0210,
68+
"type parameter `{}` must be used as the type parameter for some local \
69+
type (e.g., `MyStruct<{}>`)",
70+
param_ty,
71+
param_ty
72+
);
73+
err.span_label(sp, format!(
74+
"type parameter `{}` must be used as the type parameter for some local \
75+
type",
76+
param_ty,
77+
));
78+
err.note("only traits defined in the current crate can be implemented for a \
79+
type parameter");
80+
err.emit();
6681
return;
6782
}
6883
}

src/test/ui/coherence/coherence-all-remote.old.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-all-remote.rs:9:1
2+
--> $DIR/coherence-all-remote.rs:9:6
33
|
44
LL | impl<T> Remote1<T> for isize { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-all-remote.re.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-all-remote.rs:9:1
2+
--> $DIR/coherence-all-remote.rs:9:6
33
|
44
LL | impl<T> Remote1<T> for isize { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-bigint-param.old.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-bigint-param.rs:11:1
2+
--> $DIR/coherence-bigint-param.rs:11:6
33
|
44
LL | impl<T> Remote1<BigInt> for T { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-bigint-param.re.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-bigint-param.rs:11:1
2+
--> $DIR/coherence-bigint-param.rs:11:6
33
|
44
LL | impl<T> Remote1<BigInt> for T { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-cow.a.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-cow.rs:18:1
2+
--> $DIR/coherence-cow.rs:18:6
33
|
44
LL | impl<T> Remote for Pair<T,Cover<T>> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-cow.b.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-cow.rs:23:1
2+
--> $DIR/coherence-cow.rs:23:6
33
|
44
LL | impl<T> Remote for Pair<Cover<T>,T> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-cow.c.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
2-
--> $DIR/coherence-cow.rs:28:1
2+
--> $DIR/coherence-cow.rs:28:6
33
|
44
LL | impl<T,U> Remote for Pair<Cover<T>,U> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
77
= note: only traits defined in the current crate can be implemented for a type parameter
88

src/test/ui/coherence/coherence-cow.re_a.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
22
--> $DIR/coherence-cow.rs:18:1
33
|
44
LL | impl<T> Remote for Pair<T,Cover<T>> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
5+
| ^^^^^^^^^^^^^^^^^^^----------------
6+
| | |
7+
| | `lib::Pair<T, Cover<T>>` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
69
|
7-
= note: `lib::Pair<T, Cover<T>>` is not defined in the current create
810
= note: define and implement a trait or new type instead
911

1012
error: aborting due to previous error

src/test/ui/coherence/coherence-cow.re_b.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
22
--> $DIR/coherence-cow.rs:23:1
33
|
44
LL | impl<T> Remote for Pair<Cover<T>,T> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
5+
| ^^^^^^^^^^^^^^^^^^^----------------
6+
| | |
7+
| | `lib::Pair<Cover<T>, T>` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
69
|
7-
= note: `lib::Pair<Cover<T>, T>` is not defined in the current create
810
= note: define and implement a trait or new type instead
911

1012
error: aborting due to previous error

src/test/ui/coherence/coherence-cow.re_c.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
22
--> $DIR/coherence-cow.rs:28:1
33
|
44
LL | impl<T,U> Remote for Pair<Cover<T>,U> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
5+
| ^^^^^^^^^^^^^^^^^^^^^----------------
6+
| | |
7+
| | `lib::Pair<Cover<T>, U>` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
69
|
7-
= note: `lib::Pair<Cover<T>, U>` is not defined in the current create
810
= note: define and implement a trait or new type instead
911

1012
error: aborting due to previous error

src/test/ui/coherence/coherence-cross-crate-conflict.old.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | impl<A> Foo for A {
88
- impl trait_impl_conflict::Foo for isize;
99

1010
error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
11-
--> $DIR/coherence-cross-crate-conflict.rs:12:1
11+
--> $DIR/coherence-cross-crate-conflict.rs:12:6
1212
|
1313
LL | impl<A> Foo for A {
14-
| ^^^^^^^^^^^^^^^^^ type parameter `A` must be used as the type parameter for some local type
14+
| ^ type parameter `A` must be used as the type parameter for some local type
1515
|
1616
= note: only traits defined in the current crate can be implemented for a type parameter
1717

src/test/ui/coherence/coherence-cross-crate-conflict.re.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | impl<A> Foo for A {
88
- impl trait_impl_conflict::Foo for isize;
99

1010
error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
11-
--> $DIR/coherence-cross-crate-conflict.rs:12:1
11+
--> $DIR/coherence-cross-crate-conflict.rs:12:6
1212
|
1313
LL | impl<A> Foo for A {
14-
| ^^^^^^^^^^^^^^^^^ type parameter `A` must be used as the type parameter for some local type
14+
| ^ type parameter `A` must be used as the type parameter for some local type
1515
|
1616
= note: only traits defined in the current crate can be implemented for a type parameter
1717

src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
22
--> $DIR/coherence-fundamental-trait-objects.rs:15:1
33
|
44
LL | impl Misc for dyn Fundamental<Local> {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
5+
| ^^^^^^^^^^^^^^----------------------
6+
| | |
7+
| | `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
69
|
7-
= note: `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current create
810
= note: define and implement a trait or new type instead
911

1012
error: aborting due to previous error

src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
22
--> $DIR/coherence-fundamental-trait-objects.rs:15:1
33
|
44
LL | impl Misc for dyn Fundamental<Local> {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
5+
| ^^^^^^^^^^^^^^----------------------
6+
| | |
7+
| | `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
69
|
7-
= note: `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current create
810
= note: define and implement a trait or new type instead
911

1012
error: aborting due to previous error

src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1414
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:22:1
1515
|
1616
LL | impl !Send for dyn Marker2 {}
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
17+
| ^^^^^^^^^^^^^^^-----------
18+
| | |
19+
| | `(dyn Marker2 + 'static)` is not defined in the current crate
20+
| impl doesn't use only types from inside the current crate
1821
|
19-
= note: `(dyn Marker2 + 'static)` is not defined in the current create
2022
= note: define and implement a trait or new type instead
2123

2224
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`

src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1414
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:22:1
1515
|
1616
LL | unsafe impl Send for dyn Marker2 {}
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
17+
| ^^^^^^^^^^^^^^^^^^^^^-----------
18+
| | |
19+
| | `(dyn Marker2 + 'static)` is not defined in the current crate
20+
| impl doesn't use only types from inside the current crate
1821
|
19-
= note: `(dyn Marker2 + 'static)` is not defined in the current create
2022
= note: define and implement a trait or new type instead
2123

2224
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`

src/test/ui/coherence/coherence-impls-copy.old.stderr

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,36 +49,44 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
4949
--> $DIR/coherence-impls-copy.rs:8:1
5050
|
5151
LL | impl Copy for i32 {}
52-
| ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
52+
| ^^^^^^^^^^^^^^---
53+
| | |
54+
| | `i32` is not defined in the current crate
55+
| impl doesn't use only types from inside the current crate
5356
|
54-
= note: `i32` is not defined in the current create
5557
= note: define and implement a trait or new type instead
5658

5759
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
5860
--> $DIR/coherence-impls-copy.rs:32:1
5961
|
6062
LL | impl Copy for (MyType, MyType) {}
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
63+
| ^^^^^^^^^^^^^^----------------
64+
| | |
65+
| | `(MyType, MyType)` is not defined in the current crate
66+
| impl doesn't use only types from inside the current crate
6267
|
63-
= note: `(MyType, MyType)` is not defined in the current create
6468
= note: define and implement a trait or new type instead
6569

6670
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
6771
--> $DIR/coherence-impls-copy.rs:40:1
6872
|
6973
LL | impl Copy for [MyType] {}
70-
| ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
74+
| ^^^^^^^^^^^^^^--------
75+
| | |
76+
| | `[MyType]` is not defined in the current crate
77+
| impl doesn't use only types from inside the current crate
7178
|
72-
= note: `[MyType]` is not defined in the current create
7379
= note: define and implement a trait or new type instead
7480

7581
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
7682
--> $DIR/coherence-impls-copy.rs:45:1
7783
|
7884
LL | impl Copy for &'static [NotSync] {}
79-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
85+
| ^^^^^^^^^^^^^^------------------
86+
| | |
87+
| | `&'static [NotSync]` is not defined in the current crate
88+
| impl doesn't use only types from inside the current crate
8089
|
81-
= note: `&'static [NotSync]` is not defined in the current create
8290
= note: define and implement a trait or new type instead
8391

8492
error: aborting due to 10 previous errors

0 commit comments

Comments
 (0)