Skip to content

Commit 4d5cd21

Browse files
committed
Coherence diagnostic tweaks
1 parent 883e746 commit 4d5cd21

File tree

10 files changed

+104
-52
lines changed

10 files changed

+104
-52
lines changed

src/librustc_typeck/coherence/mod.rs

+26-21
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
5252
fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_def_id: DefId) {
5353
let did = Some(trait_def_id);
5454
let li = tcx.lang_items();
55+
let span = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap());
5556

5657
// Disallow *all* explicit impls of `Sized` and `Unsize` for now.
5758
if did == li.sized_trait() {
58-
let span = tcx.span_of_impl(impl_def_id).unwrap();
5959
struct_span_err!(tcx.sess,
6060
span,
6161
E0322,
@@ -66,11 +66,12 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
6666
}
6767

6868
if did == li.unsize_trait() {
69-
let span = tcx.span_of_impl(impl_def_id).unwrap();
70-
span_err!(tcx.sess,
71-
span,
72-
E0328,
73-
"explicit impls for the `Unsize` trait are not permitted");
69+
struct_span_err!(tcx.sess,
70+
span,
71+
E0328,
72+
"explicit impls for the `Unsize` trait are not permitted")
73+
.span_label(span, "impl of `Unsize` not allowed")
74+
.emit();
7475
return;
7576
}
7677

@@ -88,14 +89,14 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
8889
} else {
8990
return; // everything OK
9091
};
91-
let mut err = struct_span_err!(tcx.sess,
92-
tcx.span_of_impl(impl_def_id).unwrap(),
93-
E0183,
94-
"manual implementations of `{}` are experimental",
95-
trait_name);
96-
help!(&mut err,
97-
"add `#![feature(unboxed_closures)]` to the crate attributes to enable");
98-
err.emit();
92+
struct_span_err!(tcx.sess,
93+
span,
94+
E0183,
95+
"manual implementations of `{}` are experimental",
96+
trait_name)
97+
.span_label(span, format!("manual implementations of `{}` are experimental", trait_name))
98+
.help("add `#![feature(unboxed_closures)]` to the crate attributes to enable")
99+
.emit();
99100
}
100101

101102
pub fn provide(providers: &mut Providers) {
@@ -168,13 +169,17 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
168169
traits::supertrait_def_ids(tcx,
169170
data.principal().unwrap().def_id());
170171
if supertrait_def_ids.any(|d| d == trait_def_id) {
171-
span_err!(tcx.sess,
172-
tcx.span_of_impl(impl_def_id).unwrap(),
173-
E0371,
174-
"the object type `{}` automatically \
175-
implements the trait `{}`",
176-
trait_ref.self_ty(),
177-
tcx.item_path_str(trait_def_id));
172+
let sp = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap());
173+
struct_span_err!(tcx.sess,
174+
sp,
175+
E0371,
176+
"the object type `{}` automatically implements the trait `{}`",
177+
trait_ref.self_ty(),
178+
tcx.item_path_str(trait_def_id))
179+
.span_label(sp, format!("`{}` automatically implements trait `{}`",
180+
trait_ref.self_ty(),
181+
tcx.item_path_str(trait_def_id)))
182+
.emit();
178183
}
179184
}
180185
}

src/librustc_typeck/coherence/orphan.rs

+35-21
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,36 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
4040
self.tcx.hir.node_to_string(item.id));
4141
let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
4242
let trait_def_id = trait_ref.def_id;
43+
let cm = self.tcx.sess.codemap();
44+
let sp = cm.def_span(item.span);
4345
match traits::orphan_check(self.tcx, def_id) {
4446
Ok(()) => {}
4547
Err(traits::OrphanCheckErr::NoLocalInputType) => {
4648
struct_span_err!(self.tcx.sess,
47-
item.span,
49+
sp,
4850
E0117,
4951
"only traits defined in the current crate can be \
5052
implemented for arbitrary types")
51-
.span_label(item.span, "impl doesn't use types inside crate")
52-
.note(&format!("the impl does not reference any types defined in \
53-
this crate"))
53+
.span_label(sp, "impl doesn't use types inside crate")
54+
.note("the impl does not reference any types defined in this crate")
5455
.note("define and implement a trait or new type instead")
5556
.emit();
5657
return;
5758
}
5859
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
59-
span_err!(self.tcx.sess,
60-
item.span,
61-
E0210,
62-
"type parameter `{}` must be used as the type parameter for \
63-
some local type (e.g. `MyStruct<T>`); only traits defined in \
64-
the current crate can be implemented for a type parameter",
65-
param_ty);
60+
struct_span_err!(self.tcx.sess,
61+
sp,
62+
E0210,
63+
"type parameter `{}` must be used as the type parameter \
64+
for some local type (e.g. `MyStruct<{}>`)",
65+
param_ty,
66+
param_ty)
67+
.span_label(sp,
68+
format!("type parameter `{}` must be used as the type \
69+
parameter for some local type", param_ty))
70+
.note("only traits defined in the current crate can be implemented \
71+
for a type parameter")
72+
.emit();
6673
return;
6774
}
6875
}
@@ -121,22 +128,29 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
121128
if self_def_id.is_local() {
122129
None
123130
} else {
124-
Some(format!("cross-crate traits with a default impl, like `{}`, \
125-
can only be implemented for a struct/enum type \
126-
defined in the current crate",
127-
self.tcx.item_path_str(trait_def_id)))
131+
Some((
132+
format!("cross-crate traits with a default impl, like `{}`, \
133+
can only be implemented for a struct/enum type \
134+
defined in the current crate",
135+
self.tcx.item_path_str(trait_def_id)),
136+
"can't implement cross-crate trait for type in another crate"
137+
))
128138
}
129139
}
130140
_ => {
131-
Some(format!("cross-crate traits with a default impl, like `{}`, can \
132-
only be implemented for a struct/enum type, not `{}`",
133-
self.tcx.item_path_str(trait_def_id),
134-
self_ty))
141+
Some((format!("cross-crate traits with a default impl, like `{}`, can \
142+
only be implemented for a struct/enum type, not `{}`",
143+
self.tcx.item_path_str(trait_def_id),
144+
self_ty),
145+
"can't implement cross-crate trait with a default impl for \
146+
non-struct/enum type"))
135147
}
136148
};
137149

138-
if let Some(msg) = msg {
139-
span_err!(self.tcx.sess, item.span, E0321, "{}", msg);
150+
if let Some((msg, label)) = msg {
151+
struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
152+
.span_label(sp, label)
153+
.emit();
140154
return;
141155
}
142156
}

src/test/ui/codemap_tests/empty_span.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`,
22
--> $DIR/empty_span.rs:17:5
33
|
44
LL | unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with a default impl
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
66

77
error: aborting due to previous error
88

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
3232
--> $DIR/coherence-impls-copy.rs:33:1
3333
|
3434
LL | impl Copy for (MyType, MyType) {}
35-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
3636
|
3737
= note: the impl does not reference any types defined in this crate
3838
= note: define and implement a trait or new type instead
@@ -41,7 +41,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
4141
--> $DIR/coherence-impls-copy.rs:40:1
4242
|
4343
LL | impl Copy for [MyType] {}
44-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
44+
| ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
4545
|
4646
= note: the impl does not reference any types defined in this crate
4747
= note: define and implement a trait or new type instead
@@ -50,7 +50,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
5050
--> $DIR/coherence-impls-copy.rs:44:1
5151
|
5252
LL | impl Copy for &'static [NotSync] {}
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
5454
|
5555
= note: the impl does not reference any types defined in this crate
5656
= note: define and implement a trait or new type instead

src/test/ui/e0119/complex-impl.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ LL | impl<R> External for (Q, R) {} //~ ERROR must be used
88
- impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box<U>, V, W>)
99
where <U as std::ops::FnOnce<(T,)>>::Output == V, <V as std::iter::Iterator>::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, <W as std::ops::Add>::Output: std::marker::Copy;
1010

11-
error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
11+
error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<R>`)
1212
--> $DIR/complex-impl.rs:19:1
1313
|
1414
LL | impl<R> External for (Q, R) {} //~ ERROR must be used
15-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` must be used as the type parameter for some local type
16+
|
17+
= note: only traits defined in the current crate can be implemented for a type parameter
1618

1719
error: aborting due to 2 previous errors
1820

src/test/ui/e0119/issue-28981.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
88
- impl<'a, T> std::ops::Deref for &'a T
99
where T: ?Sized;
1010

11-
error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
11+
error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
1212
--> $DIR/issue-28981.rs:15:1
1313
|
1414
LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
15-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
| ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `Foo` must be used as the type parameter for some local type
16+
|
17+
= note: only traits defined in the current crate can be implemented for a type parameter
1618

1719
error: aborting due to 2 previous errors
1820

src/test/ui/error-codes/E0117.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
88
--> $DIR/E0117.rs:11:1
99
|
1010
LL | impl Drop for u32 {} //~ ERROR E0117
11-
| ^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
11+
| ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
1212
|
1313
= note: the impl does not reference any types defined in this crate
1414
= note: define and implement a trait or new type instead

src/test/ui/error-codes/E0206.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1414
--> $DIR/E0206.rs:13:1
1515
|
1616
LL | impl Copy for Foo { }
17-
| ^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
17+
| ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
1818
|
1919
= note: the impl does not reference any types defined in this crate
2020
= note: define and implement a trait or new type instead

src/test/ui/error-codes/E0328.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(unsize)]
12+
13+
use std::marker::Unsize;
14+
15+
pub struct MyType;
16+
17+
impl<T> Unsize<T> for MyType {}
18+
//~^ ERROR explicit impls for the `Unsize` trait are not permitted [E0328]
19+
20+
fn main() {}

src/test/ui/error-codes/E0328.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0328]: explicit impls for the `Unsize` trait are not permitted
2+
--> $DIR/E0328.rs:17:1
3+
|
4+
LL | impl<T> Unsize<T> for MyType {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Unsize` not allowed
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0328`.

0 commit comments

Comments
 (0)