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

0 commit comments

Comments
 (0)