The WF checks are now done as an AST validation.
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);
[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:
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
}
});
}
- 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);
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,
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"),
};
}
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,
```
"##,
-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:
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:
// 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 `{}`
#![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() {}
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
fn main() {
// ICE
call_method(());
+ //~^ ERROR
}
struct NoClone;
fn main() {
- let (a, b) = copy(NoClone);
+ let (a, b) = copy(NoClone); //~ ERROR
println!("{:?} {:?}", a, b);
}