Remove wfcheck for auto traits, remove dead error codes
The WF checks are now done as an AST validation.
This commit is contained in:
parent
02b5fee732
commit
edd52b1975
@ -247,16 +247,16 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
if is_auto == IsAuto::Yes {
|
||||
// Auto traits cannot have generics, super traits nor contain items.
|
||||
if generics.is_parameterized() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"auto traits cannot have generics");
|
||||
struct_span_err!(self.session, item.span, E0567,
|
||||
"Auto traits cannot have generic parameters").emit();
|
||||
}
|
||||
if !bounds.is_empty() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"auto traits cannot have super traits");
|
||||
struct_span_err!(self.session, item.span, E0568,
|
||||
"Auto traits cannot have predicates").emit();
|
||||
}
|
||||
if !trait_items.is_empty() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"auto traits cannot contain items");
|
||||
struct_span_err!(self.session, item.span, E0380,
|
||||
"Auto traits cannot have methods or associated items").emit();
|
||||
}
|
||||
}
|
||||
self.no_questions_in_bounds(bounds, "supertraits", true);
|
||||
|
@ -150,6 +150,13 @@ fn some_func() {
|
||||
[RFC 911]: https://github.com/rust-lang/rfcs/pull/911
|
||||
"##,
|
||||
|
||||
E0380: r##"
|
||||
Auto traits cannot have methods or associated items.
|
||||
For more information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
||||
"##,
|
||||
|
||||
E0449: r##"
|
||||
A visibility qualifier was used when it was unnecessary. Erroneous code
|
||||
examples:
|
||||
@ -264,5 +271,7 @@ fn foo() {}
|
||||
E0226, // only a single explicit lifetime bound is permitted
|
||||
E0472, // asm! is unsupported on this target
|
||||
E0561, // patterns aren't allowed in function pointer types
|
||||
E0567, // auto traits can not have type parameters
|
||||
E0568, // auto traits can not have predicates
|
||||
E0642, // patterns aren't allowed in methods without bodies
|
||||
}
|
||||
|
@ -275,74 +275,8 @@ fn check_type_defn<F>(&mut self, item: &hir::Item, all_sized: bool, mut lookup_f
|
||||
});
|
||||
}
|
||||
|
||||
fn check_auto_trait(&mut self, trait_def_id: DefId, span: Span) {
|
||||
// We want to ensure:
|
||||
//
|
||||
// 1) that there are no items contained within
|
||||
// the trait definition
|
||||
//
|
||||
// 2) that the definition doesn't violate the no-super trait rule
|
||||
// for auto traits.
|
||||
//
|
||||
// 3) that the trait definition does not have any type parameters
|
||||
|
||||
let predicates = self.tcx.predicates_of(trait_def_id);
|
||||
|
||||
// We must exclude the Self : Trait predicate contained by all
|
||||
// traits.
|
||||
let has_predicates =
|
||||
predicates.predicates.iter().any(|predicate| {
|
||||
match predicate {
|
||||
&ty::Predicate::Trait(ref poly_trait_ref) => {
|
||||
let self_ty = poly_trait_ref.0.self_ty();
|
||||
!(self_ty.is_self() && poly_trait_ref.def_id() == trait_def_id)
|
||||
},
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
|
||||
let has_ty_params = self.tcx.generics_of(trait_def_id).types.len() > 1;
|
||||
|
||||
// We use an if-else here, since the generics will also trigger
|
||||
// an extraneous error message when we find predicates like
|
||||
// `T : Sized` for a trait like: `trait Magic<T>`.
|
||||
//
|
||||
// We also put the check on the number of items here,
|
||||
// as it seems confusing to report an error about
|
||||
// extraneous predicates created by things like
|
||||
// an associated type inside the trait.
|
||||
let mut err = None;
|
||||
if !self.tcx.associated_item_def_ids(trait_def_id).is_empty() {
|
||||
error_380(self.tcx, span);
|
||||
} else if has_ty_params {
|
||||
err = Some(struct_span_err!(self.tcx.sess, span, E0567,
|
||||
"traits with auto impls (`e.g. impl \
|
||||
Trait for ..`) can not have type parameters"));
|
||||
} else if has_predicates {
|
||||
err = Some(struct_span_err!(self.tcx.sess, span, E0568,
|
||||
"traits with auto impls (`e.g. impl \
|
||||
Trait for ..`) cannot have predicates"));
|
||||
}
|
||||
|
||||
// Finally if either of the above conditions apply we should add a note
|
||||
// indicating that this error is the result of a recent soundness fix.
|
||||
match err {
|
||||
None => {},
|
||||
Some(mut e) => {
|
||||
e.note("the new auto trait rules are the result of a \
|
||||
recent soundness fix; see #29859 for more details");
|
||||
e.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait(&mut self, item: &hir::Item) {
|
||||
let trait_def_id = self.tcx.hir.local_def_id(item.id);
|
||||
|
||||
if self.tcx.trait_is_auto(trait_def_id) {
|
||||
self.check_auto_trait(trait_def_id, item.span);
|
||||
}
|
||||
|
||||
self.for_item(item).with_fcx(|fcx, this| {
|
||||
let predicates = fcx.tcx.predicates_of(trait_def_id).instantiate_identity(fcx.tcx);
|
||||
let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
|
||||
@ -733,12 +667,6 @@ fn error_192(tcx: TyCtxt, span: Span) {
|
||||
default impls (e.g., `Send` and `Sync`)")
|
||||
}
|
||||
|
||||
fn error_380(tcx: TyCtxt, span: Span) {
|
||||
span_err!(tcx.sess, span, E0380,
|
||||
"traits with default impls (`e.g. impl \
|
||||
Trait for ..`) must have no methods or associated items")
|
||||
}
|
||||
|
||||
fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name)
|
||||
-> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(tcx.sess, span, E0392,
|
||||
|
@ -712,9 +712,9 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let item = tcx.hir.expect_item(node_id);
|
||||
|
||||
let unsafety = match item.node {
|
||||
hir::ItemTrait(_, unsafety, ..) => unsafety,
|
||||
hir::ItemTraitAlias(..) => hir::Unsafety::Normal,
|
||||
let (is_auto, unsafety) = match item.node {
|
||||
hir::ItemTrait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
|
||||
hir::ItemTraitAlias(..) => (hir::IsAuto::No, hir::Unsafety::Normal),
|
||||
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
|
||||
};
|
||||
|
||||
@ -731,10 +731,6 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
let def_path_hash = tcx.def_path_hash(def_id);
|
||||
let is_auto = match item.node {
|
||||
hir::ItemTrait(hir::IsAuto::Yes, ..) => true,
|
||||
_ => tcx.hir.trait_is_auto(def_id),
|
||||
};
|
||||
let def = ty::TraitDef::new(def_id,
|
||||
unsafety,
|
||||
paren_sugar,
|
||||
|
@ -2531,13 +2531,6 @@ struct Bar<S, T> { x: Foo<S, T> }
|
||||
```
|
||||
"##,
|
||||
|
||||
E0318: r##"
|
||||
Default impls for a trait must be located in the same crate where the trait was
|
||||
defined. For more information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
||||
"##,
|
||||
|
||||
E0321: r##"
|
||||
A cross-crate opt-out trait was implemented on something which wasn't a struct
|
||||
or enum type. Erroneous code example:
|
||||
@ -3170,13 +3163,6 @@ impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
||||
struct.
|
||||
"##,
|
||||
|
||||
E0380: r##"
|
||||
Default impls are only allowed for traits with no methods or associated items.
|
||||
For more information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
||||
"##,
|
||||
|
||||
E0390: r##"
|
||||
You tried to implement methods for a primitive type. Erroneous code example:
|
||||
|
||||
@ -4729,13 +4715,10 @@ fn foo<U: Iterator>(&self, _: &U) { } // error method `foo` has incompatible
|
||||
// E0372, // coherence not object safe
|
||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
// between structures with the same definition
|
||||
E0521, // redundant auto implementations of trait
|
||||
E0533, // `{}` does not name a unit variant, unit struct or a constant
|
||||
// E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
|
||||
E0564, // only named lifetimes are allowed in `impl Trait`,
|
||||
// but `{}` was found in the type `{}`
|
||||
E0567, // auto traits can not have type parameters
|
||||
E0568, // auto-traits can not have predicates,
|
||||
E0587, // struct has conflicting packed and align representation hints
|
||||
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
|
||||
E0592, // duplicate definitions with name `{}`
|
||||
|
@ -11,12 +11,9 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
auto trait Generic<T> {}
|
||||
//~^ ERROR auto traits cannot have generics
|
||||
//~^^ traits with auto impls (`e.g. impl Trait for ..`) can not have type parameters
|
||||
//~^ Auto traits cannot have type parameters [E0567]
|
||||
auto trait Bound : Copy {}
|
||||
//~^ ERROR auto traits cannot have super traits
|
||||
//~^^ traits with auto impls (`e.g. impl Trait for ..`) cannot have predicates
|
||||
//~^ Auto traits cannot have predicates [E0568]
|
||||
auto trait MyTrait { fn foo() {} }
|
||||
//~^ ERROR auto traits cannot contain items
|
||||
//~^^ traits with default impls (`e.g. impl Trait for ..`) must have no methods or associated items
|
||||
//~^ Auto traits cannot have methods or associated items [E0380]
|
||||
fn main() {}
|
||||
|
@ -14,13 +14,11 @@
|
||||
|
||||
struct Foo;
|
||||
|
||||
#[allow(auto_impl)]
|
||||
unsafe impl MySafeTrait for Foo {}
|
||||
//~^ ERROR implementing the trait `MySafeTrait` is not unsafe
|
||||
|
||||
unsafe auto trait MyUnsafeTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyUnsafeTrait for Foo {}
|
||||
//~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
|
||||
|
||||
|
@ -22,4 +22,5 @@ fn call_method<T: Trait>(x: T) {}
|
||||
fn main() {
|
||||
// ICE
|
||||
call_method(());
|
||||
//~^ ERROR
|
||||
}
|
||||
|
@ -22,6 +22,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
struct NoClone;
|
||||
|
||||
fn main() {
|
||||
let (a, b) = copy(NoClone);
|
||||
let (a, b) = copy(NoClone); //~ ERROR
|
||||
println!("{:?} {:?}", a, b);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user