Rollup merge of #49037 - estebank:coherence-tweaks, r=nikomatsakis
Coherence diagnostic tweaks
This commit is contained in:
commit
a199fb2319
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
20
src/test/ui/error-codes/E0328.rs
Normal file
20
src/test/ui/error-codes/E0328.rs
Normal 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() {}
|
9
src/test/ui/error-codes/E0328.stderr
Normal file
9
src/test/ui/error-codes/E0328.stderr
Normal 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`.
|
Loading…
x
Reference in New Issue
Block a user