Rollup merge of #49037 - estebank:coherence-tweaks, r=nikomatsakis

Coherence diagnostic tweaks
This commit is contained in:
kennytm 2018-03-16 05:38:11 +08:00
commit a199fb2319
No known key found for this signature in database
GPG Key ID: FEF6C8051D0E013C
10 changed files with 104 additions and 52 deletions

View File

@ -52,10 +52,10 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_def_id: DefId) {
let did = Some(trait_def_id);
let li = tcx.lang_items();
let span = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap());
// Disallow *all* explicit impls of `Sized` and `Unsize` for now.
if did == li.sized_trait() {
let span = tcx.span_of_impl(impl_def_id).unwrap();
struct_span_err!(tcx.sess,
span,
E0322,
@ -66,11 +66,12 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
}
if did == li.unsize_trait() {
let span = tcx.span_of_impl(impl_def_id).unwrap();
span_err!(tcx.sess,
span,
E0328,
"explicit impls for the `Unsize` trait are not permitted");
struct_span_err!(tcx.sess,
span,
E0328,
"explicit impls for the `Unsize` trait are not permitted")
.span_label(span, "impl of `Unsize` not allowed")
.emit();
return;
}
@ -88,14 +89,14 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
} else {
return; // everything OK
};
let mut err = struct_span_err!(tcx.sess,
tcx.span_of_impl(impl_def_id).unwrap(),
E0183,
"manual implementations of `{}` are experimental",
trait_name);
help!(&mut err,
"add `#![feature(unboxed_closures)]` to the crate attributes to enable");
err.emit();
struct_span_err!(tcx.sess,
span,
E0183,
"manual implementations of `{}` are experimental",
trait_name)
.span_label(span, format!("manual implementations of `{}` are experimental", trait_name))
.help("add `#![feature(unboxed_closures)]` to the crate attributes to enable")
.emit();
}
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
traits::supertrait_def_ids(tcx,
data.principal().unwrap().def_id());
if supertrait_def_ids.any(|d| d == trait_def_id) {
span_err!(tcx.sess,
tcx.span_of_impl(impl_def_id).unwrap(),
E0371,
"the object type `{}` automatically \
implements the trait `{}`",
trait_ref.self_ty(),
tcx.item_path_str(trait_def_id));
let sp = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap());
struct_span_err!(tcx.sess,
sp,
E0371,
"the object type `{}` automatically implements the trait `{}`",
trait_ref.self_ty(),
tcx.item_path_str(trait_def_id))
.span_label(sp, format!("`{}` automatically implements trait `{}`",
trait_ref.self_ty(),
tcx.item_path_str(trait_def_id)))
.emit();
}
}
}

View File

@ -40,29 +40,36 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
self.tcx.hir.node_to_string(item.id));
let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
let trait_def_id = trait_ref.def_id;
let cm = self.tcx.sess.codemap();
let sp = cm.def_span(item.span);
match traits::orphan_check(self.tcx, def_id) {
Ok(()) => {}
Err(traits::OrphanCheckErr::NoLocalInputType) => {
struct_span_err!(self.tcx.sess,
item.span,
sp,
E0117,
"only traits defined in the current crate can be \
implemented for arbitrary types")
.span_label(item.span, "impl doesn't use types inside crate")
.note(&format!("the impl does not reference any types defined in \
this crate"))
.span_label(sp, "impl doesn't use types inside crate")
.note("the impl does not reference any types defined in this crate")
.note("define and implement a trait or new type instead")
.emit();
return;
}
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
span_err!(self.tcx.sess,
item.span,
E0210,
"type parameter `{}` 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",
param_ty);
struct_span_err!(self.tcx.sess,
sp,
E0210,
"type parameter `{}` must be used as the type parameter \
for some local type (e.g. `MyStruct<{}>`)",
param_ty,
param_ty)
.span_label(sp,
format!("type parameter `{}` must be used as the type \
parameter for some local type", param_ty))
.note("only traits defined in the current crate can be implemented \
for a type parameter")
.emit();
return;
}
}
@ -121,22 +128,29 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
if self_def_id.is_local() {
None
} else {
Some(format!("cross-crate traits with a default impl, like `{}`, \
can only be implemented for a struct/enum type \
defined in the current crate",
self.tcx.item_path_str(trait_def_id)))
Some((
format!("cross-crate traits with a default impl, like `{}`, \
can only be implemented for a struct/enum type \
defined in the current crate",
self.tcx.item_path_str(trait_def_id)),
"can't implement cross-crate trait for type in another crate"
))
}
}
_ => {
Some(format!("cross-crate traits with a default impl, like `{}`, can \
only be implemented for a struct/enum type, not `{}`",
self.tcx.item_path_str(trait_def_id),
self_ty))
Some((format!("cross-crate traits with a default impl, like `{}`, can \
only be implemented for a struct/enum type, not `{}`",
self.tcx.item_path_str(trait_def_id),
self_ty),
"can't implement cross-crate trait with a default impl for \
non-struct/enum type"))
}
};
if let Some(msg) = msg {
span_err!(self.tcx.sess, item.span, E0321, "{}", msg);
if let Some((msg, label)) = msg {
struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
.span_label(sp, label)
.emit();
return;
}
}

View File

@ -2,7 +2,7 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`,
--> $DIR/empty_span.rs:17:5
|
LL | unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with a default impl
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
error: aborting due to previous error

View File

@ -32,7 +32,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
--> $DIR/coherence-impls-copy.rs:33:1
|
LL | impl Copy for (MyType, MyType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= 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
--> $DIR/coherence-impls-copy.rs:40:1
|
LL | impl Copy for [MyType] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
| ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= 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
--> $DIR/coherence-impls-copy.rs:44:1
|
LL | impl Copy for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= note: define and implement a trait or new type instead

View File

@ -8,11 +8,13 @@ LL | impl<R> External for (Q, R) {} //~ ERROR must be used
- 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>)
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;
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
error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<R>`)
--> $DIR/complex-impl.rs:19:1
|
LL | impl<R> External for (Q, R) {} //~ ERROR must be used
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -8,11 +8,13 @@ LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
- impl<'a, T> std::ops::Deref for &'a T
where T: ?Sized;
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
error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
--> $DIR/issue-28981.rs:15:1
|
LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `Foo` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

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

View File

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

View File

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

View File

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