Auto merge of #47416 - petrochenkov:remove-impl-for-dot-dot, r=petrochenkov

Remove `impl Foo for .. {}` in favor `auto trait Foo {}`

Rebase of https://github.com/rust-lang/rust/pull/46480 with restored parsing support.
This commit is contained in:
bors 2018-01-13 21:48:12 +00:00
commit cf4c3cbe55
85 changed files with 193 additions and 804 deletions

View File

@ -40,15 +40,10 @@ use hash::Hasher;
/// [ub]: ../../reference/behavior-considered-undefined.html
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
pub unsafe trait Send {
pub unsafe auto trait Send {
// empty.
}
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
unsafe impl Send for .. { }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Send for *const T { }
#[stable(feature = "rust1", since = "1.0.0")]
@ -345,15 +340,10 @@ pub trait Copy : Clone {
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "sync"]
#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
pub unsafe trait Sync {
pub unsafe auto trait Sync {
// Empty
}
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
unsafe impl Sync for .. { }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Sync for *const T { }
#[stable(feature = "rust1", since = "1.0.0")]
@ -563,11 +553,7 @@ mod impls {
/// This affects, for example, whether a `static` of that type is
/// placed in read-only static memory or writable static memory.
#[lang = "freeze"]
unsafe trait Freeze {}
#[allow(unknown_lints)]
#[allow(auto_impl)]
unsafe impl Freeze for .. {}
unsafe auto trait Freeze {}
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}

View File

@ -496,7 +496,6 @@ define_dep_nodes!( <'tcx>
[] SuperPredicatesOfItem(DefId),
[] TraitDefOfItem(DefId),
[] AdtDefOfItem(DefId),
[] IsAutoImpl(DefId),
[] ImplTraitRef(DefId),
[] ImplPolarity(DefId),
[] FnSignature(DefId),

View File

@ -498,10 +498,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
// visit_enum_def() takes care of visiting the Item's NodeId
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
}
ItemAutoImpl(_, ref trait_ref) => {
visitor.visit_id(item.id);
visitor.visit_trait_ref(trait_ref)
}
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_refs) => {
visitor.visit_id(item.id);
visitor.visit_generics(type_parameters);

View File

@ -1952,16 +1952,6 @@ impl<'a> LoweringContext<'a> {
let vdata = self.lower_variant_data(vdata);
hir::ItemUnion(vdata, self.lower_generics(generics))
}
ItemKind::AutoImpl(unsafety, ref trait_ref) => {
let trait_ref = self.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed);
if let Def::Trait(def_id) = trait_ref.path.def {
self.trait_auto_impl.insert(def_id, id);
}
hir::ItemAutoImpl(self.lower_unsafety(unsafety),
trait_ref)
}
ItemKind::Impl(unsafety,
polarity,
defaultness,

View File

@ -104,8 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
// Pick the def data. This need not be unique, but the more
// information we encapsulate into
let def_data = match i.node {
ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
DefPathData::Impl,
ItemKind::Impl(..) => DefPathData::Impl,
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>

View File

@ -1192,7 +1192,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
ItemTrait(..) => "trait",
ItemTraitAlias(..) => "trait alias",
ItemImpl(..) => "impl",
ItemAutoImpl(..) => "default impl",
};
format!("{} {}{}", item_str, path_str(), id_str)
}

View File

@ -1965,10 +1965,6 @@ pub enum Item_ {
/// Represents a Trait Alias Declaration
ItemTraitAlias(Generics, TyParamBounds),
/// Auto trait implementations
///
/// `impl Trait for .. {}`
ItemAutoImpl(Unsafety, TraitRef),
/// An implementation, eg `impl<A> Trait for Foo { .. }`
ItemImpl(Unsafety,
ImplPolarity,
@ -1996,8 +1992,7 @@ impl Item_ {
ItemUnion(..) => "union",
ItemTrait(..) => "trait",
ItemTraitAlias(..) => "trait alias",
ItemImpl(..) |
ItemAutoImpl(..) => "item",
ItemImpl(..) => "item",
}
}

View File

@ -652,18 +652,6 @@ impl<'a> State<'a> {
self.head(&visibility_qualified(&item.vis, "union"))?;
self.print_struct(struct_def, generics, item.name, item.span, true)?;
}
hir::ItemAutoImpl(unsafety, ref trait_ref) => {
self.head("")?;
self.print_visibility(&item.vis)?;
self.print_unsafety(unsafety)?;
self.word_nbsp("impl")?;
self.print_trait_ref(trait_ref)?;
self.s.space()?;
self.word_space("for")?;
self.word_space("..")?;
self.bopen()?;
self.bclose(item.span)?;
}
hir::ItemImpl(unsafety,
polarity,
defaultness,

View File

@ -854,7 +854,6 @@ impl_stable_hash_for!(enum hir::Item_ {
ItemUnion(variant_data, generics),
ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
ItemTraitAlias(generics, bounds),
ItemAutoImpl(unsafety, trait_ref),
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
});

View File

@ -564,7 +564,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
hir::ItemStruct(..) |
hir::ItemUnion(..) |
hir::ItemTrait(..) |
hir::ItemAutoImpl(..) |
hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span),
_ => item.span,
};

View File

@ -270,8 +270,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::ItemMod(..) | hir::ItemForeignMod(..) |
hir::ItemImpl(..) | hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
hir::ItemStruct(..) | hir::ItemEnum(..) |
hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
hir::ItemGlobalAsm(..) => {}
hir::ItemUnion(..) | hir::ItemGlobalAsm(..) => {}
}
}
hir_map::NodeTraitItem(trait_method) => {

View File

@ -461,10 +461,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
intravisit::walk_item(this, item);
});
}
hir::ItemExternCrate(_)
| hir::ItemUse(..)
| hir::ItemMod(..)
| hir::ItemAutoImpl(..)
| hir::ItemForeignMod(..)
| hir::ItemGlobalAsm(..) => {
// These sorts of items have no lifetime parameters at all.

View File

@ -2434,7 +2434,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
VtableBuiltinData { nested: obligations }
}
/// This handles the case where a `impl Foo for ..` impl is being used.
/// This handles the case where a `auto trait Foo` impl is being used.
/// The idea is that the impl applies to `X : Foo` if the following conditions are met:
///
/// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
@ -3276,7 +3276,7 @@ impl<'tcx> TraitObligation<'tcx> {
/*!
* Creates a cause for obligations that are derived from
* `obligation` by a recursive search (e.g., for a builtin
* bound, or eventually a `impl Foo for ..`). If `obligation`
* bound, or eventually a `auto trait Foo`). If `obligation`
* is itself a derived obligation, this is just a clone, but
* otherwise we create a "derived obligation" cause so as to
* keep track of the original root obligation for error

View File

@ -232,11 +232,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// Always use types for non-local impls, where types are always
// available, and filename/line-number is mostly uninteresting.
let use_types = !self.is_auto_impl(impl_def_id) && (!impl_def_id.is_local() || {
let use_types = !impl_def_id.is_local() || {
// Otherwise, use filename/line-number if forced.
let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
!force_no_types
});
};
if !use_types {
return self.push_impl_path_fallback(buffer, impl_def_id);

View File

@ -112,9 +112,6 @@ define_maps! { <'tcx>
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
[] fn is_foreign_item: IsForeignItem(DefId) -> bool,
/// True if this is an auto impl (aka impl Foo for ..)
[] fn is_auto_impl: IsAutoImpl(DefId) -> bool,
/// Get a map with the variance of every item; use `item_variance`
/// instead.
[] fn crate_variances: crate_variances(CrateNum) -> Rc<ty::CrateVariancesMap>,

View File

@ -801,7 +801,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
DepKind::IsAutoImpl => { force!(is_auto_impl, def_id!()); }
DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
DepKind::FnSignature => { force!(fn_sig, def_id!()); }

View File

@ -2400,8 +2400,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
/// Returns true if this is an `auto trait`.
///
/// NB. For a limited time, also returns true if `impl Trait for .. { }` is in the code-base.
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).has_auto_impl
}

View File

@ -246,8 +246,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
hir::ItemUnion(..) |
hir::ItemTrait(..) |
hir::ItemTraitAlias(..) |
hir::ItemImpl(..) |
hir::ItemAutoImpl(..) => None,
hir::ItemImpl(..) => None,
hir::ItemMod(ref m) => search_mod(this, m, idx, names),
};

View File

@ -393,9 +393,6 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
//
//HirItem::ItemTrait(..) => ("ItemTrait", LABELS_TRAIT),
// `impl Trait for .. {}`
HirItem::ItemAutoImpl(..) => ("ItemAutoImpl", LABELS_IMPL),
// An implementation, eg `impl<A> Trait for Foo { .. }`
HirItem::ItemImpl(..) => ("ItemImpl", LABELS_IMPL),

View File

@ -55,31 +55,6 @@ use bad_style::{MethodLateContext, method_context};
// hardwired lints from librustc
pub use lint::builtin::*;
declare_lint! {
pub AUTO_IMPL,
Deny,
"The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`"
}
#[derive(Copy, Clone)]
pub struct AutoImpl;
impl LintPass for AutoImpl {
fn get_lints(&self) -> LintArray {
lint_array!(AUTO_IMPL)
}
}
impl EarlyLintPass for AutoImpl {
fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
let msg = "The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`";
match item.node {
ast::ItemKind::AutoImpl(..) => cx.span_lint(AUTO_IMPL, item.span, msg),
_ => ()
}
}
}
declare_lint! {
WHILE_TRUE,
Warn,

View File

@ -109,7 +109,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
AnonymousParameters,
IllegalFloatLiteralPattern,
UnusedDocComment,
AutoImpl,
);
add_early_builtin_with_new!(sess,
@ -183,10 +182,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
// - Eventually, remove lint
store.register_future_incompatible(sess,
vec![
FutureIncompatibleInfo {
id: LintId::of(AUTO_IMPL),
reference: "issue #13231 <https://github.com/rust-lang/rust/issues/13231>",
},
FutureIncompatibleInfo {
id: LintId::of(PRIVATE_IN_PUBLIC),
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",

View File

@ -143,7 +143,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
is_const_fn => { cdata.is_const_fn(def_id.index) }
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
is_auto_impl => { cdata.is_auto_impl(def_id.index) }
describe_def => { cdata.get_def(def_id.index) }
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
lookup_stability => {

View File

@ -404,7 +404,6 @@ impl<'tcx> EntryKind<'tcx> {
EntryKind::ForeignMod |
EntryKind::Impl(_) |
EntryKind::AutoImpl(_) |
EntryKind::Field |
EntryKind::Generator(_) |
EntryKind::Closure(_) => return None,
@ -690,8 +689,7 @@ impl<'a, 'tcx> CrateMetadata {
}
continue;
}
EntryKind::Impl(_) |
EntryKind::AutoImpl(_) => continue,
EntryKind::Impl(_) => continue,
_ => {}
}
@ -1045,13 +1043,6 @@ impl<'a, 'tcx> CrateMetadata {
self.dllimport_foreign_items.contains(&id)
}
pub fn is_auto_impl(&self, impl_id: DefIndex) -> bool {
match self.entry(impl_id).kind {
EntryKind::AutoImpl(_) => true,
_ => false,
}
}
pub fn fn_sig(&self,
id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)

View File

@ -974,17 +974,6 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_sig: None,
}), repr_options)
}
hir::ItemAutoImpl(..) => {
let data = ImplData {
polarity: hir::ImplPolarity::Positive,
defaultness: hir::Defaultness::Final,
parent_impl: None,
coerce_unsized_info: None,
trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
};
EntryKind::AutoImpl(self.lazy(&data))
}
hir::ItemImpl(_, polarity, defaultness, ..) => {
let trait_ref = tcx.impl_trait_ref(def_id);
let parent = if let Some(trait_ref) = trait_ref {
@ -1579,7 +1568,6 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
hir::ItemGlobalAsm(..) |
hir::ItemExternCrate(..) |
hir::ItemUse(..) |
hir::ItemAutoImpl(..) |
hir::ItemTy(..) |
hir::ItemTraitAlias(..) => {
// no sub-item recording needed in these cases

View File

@ -303,7 +303,6 @@ pub enum EntryKind<'tcx> {
Generator(Lazy<GeneratorData<'tcx>>),
Trait(Lazy<TraitData<'tcx>>),
Impl(Lazy<ImplData<'tcx>>),
AutoImpl(Lazy<ImplData<'tcx>>),
Method(Lazy<MethodData<'tcx>>),
AssociatedType(AssociatedContainer),
AssociatedConst(AssociatedContainer, u8),
@ -359,7 +358,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for EntryKind<'gcx> {
EntryKind::Trait(ref trait_data) => {
trait_data.hash_stable(hcx, hasher);
}
EntryKind::AutoImpl(ref impl_data) |
EntryKind::Impl(ref impl_data) => {
impl_data.hash_stable(hcx, hasher);
}

View File

@ -910,7 +910,6 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
hir::ItemUse(..) |
hir::ItemForeignMod(..) |
hir::ItemTy(..) |
hir::ItemAutoImpl(..) |
hir::ItemTrait(..) |
hir::ItemTraitAlias(..) |
hir::ItemMod(..) => {

View File

@ -215,8 +215,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_item(&mut self, item: &'a Item) {
match item.node {
ItemKind::Impl(.., Some(..), _, ref impl_items) => {
ItemKind::Impl(.., Some(..), ref ty, ref impl_items) => {
self.invalid_visibility(&item.vis, item.span, None);
if ty.node == TyKind::Err {
self.err_handler()
.struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax")
.help("use `auto trait Trait {}` instead").emit();
}
for impl_item in impl_items {
self.invalid_visibility(&impl_item.vis, impl_item.span, None);
if let ImplItemKind::Method(ref sig, _) = impl_item.node {
@ -229,9 +234,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
item.span,
Some("place qualifiers on individual impl items instead"));
}
ItemKind::AutoImpl(..) => {
self.invalid_visibility(&item.vis, item.span, None);
}
ItemKind::ForeignMod(..) => {
self.invalid_visibility(&item.vis,
item.span,
@ -250,16 +252,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
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 super traits").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);

View File

@ -150,6 +150,13 @@ Trait methods cannot be declared `const` by design. For more information, see
[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 @@ register_diagnostics! {
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 generic parameters
E0568, // auto traits can not have super traits
E0642, // patterns aren't allowed in methods without bodies
}

View File

@ -147,10 +147,6 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
let def_id = self.tcx.hir.local_def_id(item.id);
cmp::min(self.item_ty_level(def_id), self.impl_trait_level(def_id))
}
hir::ItemAutoImpl(..) => {
let def_id = self.tcx.hir.local_def_id(item.id);
self.impl_trait_level(def_id)
}
// Foreign mods inherit level from parents
hir::ItemForeignMod(..) => {
self.prev_level
@ -214,7 +210,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
}
hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) | hir::ItemTraitAlias(..) |
hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemAutoImpl(..) => {}
hir::ItemFn(..) | hir::ItemExternCrate(..) => {}
}
// Mark all items in interfaces of reachable items as reachable
@ -226,8 +222,6 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
// Reexports are handled in visit_mod
hir::ItemUse(..) => {}
// The interface is empty
hir::ItemAutoImpl(..) => {}
// The interface is empty
hir::ItemGlobalAsm(..) => {}
// Visit everything
hir::ItemConst(..) | hir::ItemStatic(..) |
@ -1571,8 +1565,6 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
self.check(field.id, min(item_visibility, field_visibility)).ty();
}
}
// The interface is empty
hir::ItemAutoImpl(..) => {}
// An inherent impl is public when its type is public
// Subitems of inherent impls have their own publicity
hir::ItemImpl(.., None, _, ref impl_item_refs) => {

View File

@ -400,7 +400,7 @@ impl<'a> Resolver<'a> {
self.insert_field_names(item_def_id, field_names);
}
ItemKind::AutoImpl(..) | ItemKind::Impl(..) => {}
ItemKind::Impl(..) => {}
ItemKind::Trait(..) => {
let def_id = self.definitions.local_def_id(item.id);

View File

@ -1902,12 +1902,6 @@ impl<'a> Resolver<'a> {
|this| visit::walk_item(this, item));
}
ItemKind::AutoImpl(_, ref trait_ref) => {
self.with_optional_trait_ref(Some(trait_ref), |this, _| {
// Resolve type arguments in trait path
visit::walk_trait_ref(this, trait_ref);
});
}
ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
self.resolve_implementation(generics,
opt_trait_ref,

View File

@ -511,17 +511,6 @@ impl Sig for ast::Item {
Ok(sig)
}
ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
let mut text = String::new();
if unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
text.push_str("impl ");
let trait_sig = trait_ref.path.make(offset + text.len(), id, scx)?;
text.push_str(&trait_sig.text);
text.push_str(" for .. {}");
Ok(replace_text(trait_sig, text))
}
ast::ItemKind::Impl(
unsafety,
polarity,

View File

@ -275,74 +275,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
});
}
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,

View File

@ -16,6 +16,7 @@
// mappings. That mapping code resides here.
use hir::def_id::{DefId, LOCAL_CRATE};
use rustc::traits;
use rustc::ty::{self, TyCtxt, TypeFoldable};
use rustc::ty::maps::Providers;
@ -25,7 +26,6 @@ mod builtin;
mod inherent_impls;
mod inherent_impls_overlap;
mod orphan;
mod overlap;
mod unsafety;
fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
@ -119,7 +119,7 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
check_impl(tcx, impl_id);
}
for &impl_id in impls {
overlap::check_impl(tcx, impl_id);
check_impl_overlap(tcx, impl_id);
}
builtin::check_trait(tcx, def_id);
}
@ -131,9 +131,51 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
unsafety::check(tcx);
orphan::check(tcx);
overlap::check_auto_impls(tcx);
// these queries are executed for side-effects (error reporting):
ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
ty::maps::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
}
/// Overlap: No two impls for the same trait are implemented for the
/// same type. Likewise, no two inherent impls for a given type
/// constructor provide a method with the same name.
fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
let impl_def_id = tcx.hir.local_def_id(node_id);
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let trait_def_id = trait_ref.def_id;
if trait_ref.references_error() {
debug!("coherence: skipping impl {:?} with error {:?}",
impl_def_id, trait_ref);
return
}
// Trigger building the specialization graph for the trait of this impl.
// This will detect any overlap errors.
tcx.specialization_graph_of(trait_def_id);
// check for overlap with the automatic `impl Trait for Trait`
if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
// This is something like impl Trait1 for Trait2. Illegal
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
// This is an error, but it will be reported by wfcheck. Ignore it here.
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
} else {
let mut supertrait_def_ids =
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));
}
}
}
}

View File

@ -142,24 +142,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
}
}
}
hir::ItemAutoImpl(_, ref item_trait_ref) => {
// "Trait" impl
debug!("coherence2::orphan check: default trait impl {}",
self.tcx.hir.node_to_string(item.id));
let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
if !trait_ref.def_id.is_local() {
struct_span_err!(self.tcx.sess,
item_trait_ref.path.span,
E0318,
"cannot create default implementations for traits outside \
the crate they're defined in; define a new trait instead")
.span_label(item_trait_ref.path.span,
format!("`{}` trait not defined in this crate",
self.tcx.hir.node_to_pretty_string(item_trait_ref.ref_id)))
.emit();
return;
}
}
_ => {
// Not an impl
}

View File

@ -1,110 +0,0 @@
// Copyright 2014 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.
//! Overlap: No two impls for the same trait are implemented for the
//! same type. Likewise, no two inherent impls for a given type
//! constructor provide a method with the same name.
use rustc::traits;
use rustc::ty::{self, TyCtxt, TypeFoldable};
use syntax::ast;
use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
pub fn check_auto_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut overlap = OverlapChecker { tcx };
// this secondary walk specifically checks for some other cases,
// like defaulted traits, for which additional overlap rules exist
tcx.hir.krate().visit_all_item_likes(&mut overlap);
}
pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
let impl_def_id = tcx.hir.local_def_id(node_id);
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let trait_def_id = trait_ref.def_id;
if trait_ref.references_error() {
debug!("coherence: skipping impl {:?} with error {:?}",
impl_def_id, trait_ref);
return
}
// Trigger building the specialization graph for the trait of this impl.
// This will detect any overlap errors.
tcx.specialization_graph_of(trait_def_id);
// check for overlap with the automatic `impl Trait for Trait`
if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
// This is something like impl Trait1 for Trait2. Illegal
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
// This is an error, but it will be reported by wfcheck. Ignore it here.
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
} else {
let mut supertrait_def_ids =
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));
}
}
}
}
struct OverlapChecker<'cx, 'tcx: 'cx> {
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
}
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &'v hir::Item) {
match item.node {
hir::ItemAutoImpl(..) => {
// look for another auto impl; note that due to the
// general orphan/coherence rules, it must always be
// in this crate.
let impl_def_id = self.tcx.hir.local_def_id(item.id);
let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
let prev_id = self.tcx.hir.trait_auto_impl(trait_ref.def_id).unwrap();
if prev_id != item.id {
let mut err = struct_span_err!(self.tcx.sess,
self.tcx.span_of_impl(impl_def_id).unwrap(),
E0521,
"redundant auto implementations of trait \
`{}`:",
trait_ref);
err.span_note(self.tcx
.span_of_impl(self.tcx.hir.local_def_id(prev_id))
.unwrap(),
"redundant implementation is here:");
err.emit();
}
}
hir::ItemImpl(.., Some(_), _, _) => {
}
_ => {}
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View File

@ -84,9 +84,6 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &'v hir::Item) {
match item.node {
hir::ItemAutoImpl(unsafety, _) => {
self.check_unsafety_coherence(item, None, unsafety, hir::ImplPolarity::Positive);
}
hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => {
self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
}

View File

@ -73,7 +73,6 @@ pub fn provide(providers: &mut Providers) {
impl_trait_ref,
impl_polarity,
is_foreign_item,
is_auto_impl,
..*providers
};
}
@ -424,9 +423,6 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
tcx.predicates_of(def_id);
convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
},
hir::ItemAutoImpl(..) => {
tcx.impl_trait_ref(def_id);
}
hir::ItemImpl(..) => {
tcx.generics_of(def_id);
tcx.type_of(def_id);
@ -716,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(..) => (false, hir::Unsafety::Normal),
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
};
@ -735,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,
@ -1109,7 +1101,6 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_adt(def, substs)
}
ItemAutoImpl(..) |
ItemTrait(..) | ItemTraitAlias(..) |
ItemMod(..) |
ItemForeignMod(..) |
@ -1278,11 +1269,6 @@ fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
match tcx.hir.expect_item(node_id).node {
hir::ItemAutoImpl(_, ref ast_trait_ref) => {
Some(AstConv::instantiate_mono_trait_ref(&icx,
ast_trait_ref,
tcx.mk_self_type()))
}
hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
opt_trait_ref.as_ref().map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id);
@ -1728,14 +1714,3 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
}
}
fn is_auto_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> bool {
match tcx.hir.get_if_local(def_id) {
Some(hir_map::NodeItem(&hir::Item { node: hir::ItemAutoImpl(..), .. }))
=> true,
Some(_) => false,
_ => bug!("is_auto_impl applied to non-local def-id {:?}", def_id)
}
}

View File

@ -1854,14 +1854,12 @@ unsafe impl !Clone for Foo { }
This will compile:
```ignore (ignore auto_trait future compatibility warning)
```
#![feature(optin_builtin_traits)]
struct Foo;
trait Enterprise {}
impl Enterprise for .. { }
auto trait Enterprise {}
impl !Enterprise for Foo { }
```
@ -2533,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:
@ -3172,13 +3163,6 @@ containing the unsized type is the last and only unsized type field in the
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:
@ -4731,13 +4715,10 @@ register_diagnostics! {
// 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 `{}`

View File

@ -300,27 +300,6 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
}
}
// If this is an auto impl, then bail out early here
if tcx.is_auto_impl(did) {
return ret.push(clean::Item {
inner: clean::AutoImplItem(clean::AutoImpl {
// FIXME: this should be decoded
unsafety: hir::Unsafety::Normal,
trait_: match associated_trait.as_ref().unwrap().clean(cx) {
clean::TraitBound(polyt, _) => polyt.trait_,
clean::RegionBound(..) => unreachable!(),
},
}),
source: tcx.def_span(did).clean(cx),
name: None,
attrs,
visibility: Some(clean::Inherited),
stability: tcx.lookup_stability(did).clean(cx),
deprecation: tcx.lookup_deprecation(did).clean(cx),
def_id: did,
});
}
let for_ = tcx.type_of(did).clean(cx);
// Only inline impl if the implementing type is

View File

@ -430,7 +430,6 @@ pub enum ItemEnum {
PrimitiveItem(PrimitiveType),
AssociatedConstItem(Type, Option<String>),
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
AutoImplItem(AutoImpl),
/// An item that has been stripped by a rustdoc pass
StrippedItem(Box<ItemEnum>),
}
@ -481,7 +480,6 @@ impl Clean<Item> for doctree::Module {
items.extend(self.traits.iter().map(|x| x.clean(cx)));
items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
items.extend(self.macros.iter().map(|x| x.clean(cx)));
items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
// determine if we should display the inner contents or
// the outer `mod` item for the source code.
@ -2941,30 +2939,6 @@ fn build_deref_target_impls(cx: &DocContext,
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct AutoImpl {
pub unsafety: hir::Unsafety,
pub trait_: Type,
}
impl Clean<Item> for doctree::AutoImpl {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: cx.tcx.hir.local_def_id(self.id),
visibility: Some(Public),
stability: None,
deprecation: None,
inner: AutoImplItem(AutoImpl {
unsafety: self.unsafety,
trait_: self.trait_.clean(cx),
}),
}
}
}
impl Clean<Item> for doctree::ExternCrate {
fn clean(&self, cx: &DocContext) -> Item {
Item {

View File

@ -44,7 +44,6 @@ pub struct Module {
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub impls: Vec<Impl>,
pub def_traits: Vec<AutoImpl>,
pub foreigns: Vec<hir::ForeignMod>,
pub macros: Vec<Macro>,
pub is_crate: bool,
@ -73,7 +72,6 @@ impl Module {
constants : Vec::new(),
traits : Vec::new(),
impls : Vec::new(),
def_traits : Vec::new(),
foreigns : Vec::new(),
macros : Vec::new(),
is_crate : false,
@ -227,14 +225,6 @@ pub struct Impl {
pub id: ast::NodeId,
}
pub struct AutoImpl {
pub unsafety: hir::Unsafety,
pub trait_: hir::TraitRef,
pub id: ast::NodeId,
pub attrs: hir::HirVec<ast::Attribute>,
pub whence: Span,
}
// For Macro we store the DefId instead of the NodeId, since we also create
// these imported macro_rules (which only have a DUMMY_NODE_ID).
pub struct Macro {

View File

@ -82,7 +82,6 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::PrimitiveItem(..) => ItemType::Primitive,
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
clean::AutoImplItem(..) => ItemType::Impl,
clean::ForeignTypeItem => ItemType::ForeignType,
clean::StrippedItem(..) => unreachable!(),
}

View File

@ -1964,12 +1964,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
document(w, cx, item)?;
let mut indices = (0..items.len()).filter(|i| {
if let clean::AutoImplItem(..) = items[*i].inner {
return false;
}
!items[*i].is_stripped()
}).collect::<Vec<usize>>();
let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped())
.collect::<Vec<usize>>();
// the order of item types in the listing
fn reorder(ty: ItemType) -> u8 {
@ -3973,13 +3969,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
ItemType::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl,
ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
if items.iter().any(|it| {
if let clean::AutoImplItem(..) = it.inner {
false
} else {
!it.is_stripped() && it.type_() == myty
}
}) {
if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
let (short, name) = match myty {
ItemType::ExternCrate |
ItemType::Import => ("reexports", "Reexports"),

View File

@ -116,7 +116,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
// handled in the `strip-priv-imports` pass
clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
clean::AutoImplItem(..) | clean::ImplItem(..) => {}
clean::ImplItem(..) => {}
// tymethods/macros have no control over privacy
clean::MacroItem(..) | clean::TyMethodItem(..) => {}

View File

@ -548,19 +548,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
om.impls.push(i);
}
},
hir::ItemAutoImpl(unsafety, ref trait_ref) => {
// See comment above about ItemImpl.
if !self.inlining {
let i = AutoImpl {
unsafety,
trait_: trait_ref.clone(),
id: item.id,
attrs: item.attrs.clone(),
whence: item.span,
};
om.def_traits.push(i);
}
}
}
}

View File

@ -101,7 +101,7 @@ pub use panicking::{take_hook, set_hook, PanicInfo, Location};
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
across an unwind boundary"]
pub trait UnwindSafe {}
pub auto trait UnwindSafe {}
/// A marker trait representing types where a shared reference is considered
/// unwind safe.
@ -115,7 +115,7 @@ pub trait UnwindSafe {}
#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
and a reference may not be safely transferrable \
across a catch_unwind boundary"]
pub trait RefUnwindSafe {}
pub auto trait RefUnwindSafe {}
/// A simple wrapper around a type to assert that it is unwind safe.
///
@ -187,10 +187,7 @@ pub struct AssertUnwindSafe<T>(
// * Unique, an owning pointer, lifts an implementation
// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl UnwindSafe for .. {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
@ -219,14 +216,10 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
// Pretty simple implementations for the `RefUnwindSafe` marker trait,
// basically just saying that this is a marker trait and `UnsafeCell` is the
// basically just saying that `UnsafeCell` is the
// only thing which doesn't implement it (which then transitively applies to
// everything else).
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl RefUnwindSafe for .. {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}

View File

@ -2022,10 +2022,6 @@ pub enum ItemKind {
///
/// E.g. `trait Foo = Bar + Quux;`
TraitAlias(Generics, TyParamBounds),
/// Auto trait implementation.
///
/// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
AutoImpl(Unsafety, TraitRef),
/// An implementation.
///
/// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
@ -2064,8 +2060,7 @@ impl ItemKind {
ItemKind::TraitAlias(..) => "trait alias",
ItemKind::Mac(..) |
ItemKind::MacroDef(..) |
ItemKind::Impl(..) |
ItemKind::AutoImpl(..) => "item"
ItemKind::Impl(..) => "item"
}
}
}

View File

@ -1532,13 +1532,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
"trait aliases are not yet fully implemented");
}
ast::ItemKind::AutoImpl(..) => {
gate_feature_post!(&self, optin_builtin_traits,
i.span,
"auto trait implementations are experimental \
and possibly buggy");
}
ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => {
if polarity == ast::ImplPolarity::Negative {
gate_feature_post!(&self, optin_builtin_traits,

View File

@ -911,9 +911,6 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
let generics = folder.fold_generics(generics);
ItemKind::Union(folder.fold_variant_data(struct_def), generics)
}
ItemKind::AutoImpl(unsafety, ref trait_ref) => {
ItemKind::AutoImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
}
ItemKind::Impl(unsafety,
polarity,
defaultness,

View File

@ -4084,14 +4084,14 @@ impl<'a> Parser<'a> {
self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
}
fn eat_auto_trait(&mut self) -> bool {
if self.token.is_keyword(keywords::Auto)
&& self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
{
self.eat_keyword(keywords::Auto) && self.eat_keyword(keywords::Trait)
} else {
false
}
fn is_auto_trait_item(&mut self) -> bool {
// auto trait
(self.token.is_keyword(keywords::Auto)
&& self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
|| // unsafe auto trait
(self.token.is_keyword(keywords::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) &&
self.look_ahead(2, |t| t.is_keyword(keywords::Trait)))
}
fn is_defaultness(&self) -> bool {
@ -4194,7 +4194,8 @@ impl<'a> Parser<'a> {
node: StmtKind::Item(macro_def),
span: lo.to(self.prev_span),
}
// Starts like a simple path, but not a union item or item with `crate` visibility.
// Starts like a simple path, being careful to avoid contextual keywords
// such as a union items, item with `crate` visibility or auto trait items.
// Our goal here is to parse an arbitrary path `a::b::c` but not something that starts
// like a path (1 token), but it fact not a path.
// `union::b::c` - path, `union U { ... }` - not a path.
@ -4204,7 +4205,8 @@ impl<'a> Parser<'a> {
!self.token.is_qpath_start() &&
!self.is_union_item() &&
!self.is_crate_vis() &&
!self.is_extern_non_path() {
!self.is_extern_non_path() &&
!self.is_auto_trait_item() {
let pth = self.parse_path(PathStyle::Expr)?;
if !self.eat(&token::Not) {
@ -5374,11 +5376,9 @@ impl<'a> Parser<'a> {
/// Parses items implementations variants
/// impl<T> Foo { ... }
/// impl<T> ToString for &'static T { ... }
/// impl Send for .. {}
fn parse_item_impl(&mut self,
unsafety: ast::Unsafety,
defaultness: Defaultness) -> PResult<'a, ItemInfo> {
let impl_span = self.span;
// First, parse type parameters if necessary.
let mut generics = self.parse_generics()?;
@ -5421,48 +5421,35 @@ impl<'a> Parser<'a> {
None
};
if opt_trait.is_some() && self.eat(&token::DotDot) {
if generics.is_parameterized() {
self.span_err(impl_span, "auto trait implementations are not \
allowed to have generics");
if opt_trait.is_some() {
ty = if self.eat(&token::DotDot) {
P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID })
} else {
self.parse_ty()?
}
}
generics.where_clause = self.parse_where_clause()?;
if let ast::Defaultness::Default = defaultness {
self.span_err(impl_span, "`default impl` is not allowed for \
auto trait implementations");
}
self.expect(&token::OpenDelim(token::Brace))?;
let attrs = self.parse_inner_attributes()?;
self.expect(&token::OpenDelim(token::Brace))?;
self.expect(&token::CloseDelim(token::Brace))?;
Ok((keywords::Invalid.ident(),
ItemKind::AutoImpl(unsafety, opt_trait.unwrap()), None))
} else {
if opt_trait.is_some() {
ty = self.parse_ty()?;
}
generics.where_clause = self.parse_where_clause()?;
self.expect(&token::OpenDelim(token::Brace))?;
let attrs = self.parse_inner_attributes()?;
let mut impl_items = vec![];
while !self.eat(&token::CloseDelim(token::Brace)) {
let mut at_end = false;
match self.parse_impl_item(&mut at_end) {
Ok(item) => impl_items.push(item),
Err(mut e) => {
e.emit();
if !at_end {
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
}
let mut impl_items = vec![];
while !self.eat(&token::CloseDelim(token::Brace)) {
let mut at_end = false;
match self.parse_impl_item(&mut at_end) {
Ok(item) => impl_items.push(item),
Err(mut e) => {
e.emit();
if !at_end {
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
}
}
}
Ok((keywords::Invalid.ident(),
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
Some(attrs)))
}
Ok((keywords::Invalid.ident(),
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
Some(attrs)))
}
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
@ -6387,7 +6374,8 @@ impl<'a> Parser<'a> {
let is_auto = if self.eat_keyword(keywords::Trait) {
IsAuto::No
} else {
self.eat_auto_trait();
self.expect_keyword(keywords::Auto)?;
self.expect_keyword(keywords::Trait)?;
IsAuto::Yes
};
let (ident, item_, extra_attrs) =
@ -6501,7 +6489,8 @@ impl<'a> Parser<'a> {
let is_auto = if self.eat_keyword(keywords::Trait) {
IsAuto::No
} else {
self.eat_auto_trait();
self.expect_keyword(keywords::Auto)?;
self.expect_keyword(keywords::Trait)?;
IsAuto::Yes
};
// TRAIT ITEM

View File

@ -1294,18 +1294,6 @@ impl<'a> State<'a> {
self.head(&visibility_qualified(&item.vis, "union"))?;
self.print_struct(struct_def, generics, item.ident, item.span, true)?;
}
ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
self.head("")?;
self.print_visibility(&item.vis)?;
self.print_unsafety(unsafety)?;
self.word_nbsp("impl")?;
self.print_trait_ref(trait_ref)?;
self.s.space()?;
self.word_space("for")?;
self.word_space("..")?;
self.bopen()?;
self.bclose(item.span)?;
}
ast::ItemKind::Impl(unsafety,
polarity,
defaultness,

View File

@ -259,9 +259,6 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_generics(type_parameters);
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
}
ItemKind::AutoImpl(_, ref trait_ref) => {
visitor.visit_trait_ref(trait_ref)
}
ItemKind::Impl(_, _, _,
ref type_parameters,
ref opt_trait_reference,

View File

@ -30,17 +30,11 @@
#[lang = "sized"]
trait Sized {}
#[lang = "sync"]
trait Sync {}
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl Sync for .. {}
auto trait Sync {}
#[lang = "copy"]
trait Copy {}
#[lang = "freeze"]
trait Freeze {}
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl Freeze for .. {}
auto trait Freeze {}
#[lang = "drop_in_place"]
#[inline]

View File

@ -22,10 +22,7 @@ impl<T> Sync for T {}
#[lang = "copy"]
trait Copy {}
#[lang = "freeze"]
trait Freeze {}
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl Freeze for .. {}
auto trait Freeze {}
#[lang = "drop_in_place"]
#[inline]

View File

@ -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 generic 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 super traits [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() {}

View File

@ -11,8 +11,6 @@
#![feature(optin_builtin_traits, core)]
#![crate_type = "rlib"]
pub trait DefaultedTrait { }
#[allow(auto_impl)]
impl DefaultedTrait for .. { }
pub auto trait DefaultedTrait { }
pub struct Something<T> { t: T }

View File

@ -10,25 +10,16 @@
#![feature(optin_builtin_traits)]
trait MyTrait { fn foo() {} }
auto trait MySafeTrait {}
#[allow(auto_impl)]
impl MyTrait for .. {}
//~^ ERROR redundant auto implementations of trait `MyTrait`
struct Foo;
#[allow(auto_impl)]
impl MyTrait for .. {}
trait MySafeTrait {}
#[allow(auto_impl)]
unsafe impl MySafeTrait for .. {}
unsafe impl MySafeTrait for Foo {}
//~^ ERROR implementing the trait `MySafeTrait` is not unsafe
unsafe trait MyUnsafeTrait {}
unsafe auto trait MyUnsafeTrait {}
#[allow(auto_impl)]
impl MyUnsafeTrait for .. {}
impl MyUnsafeTrait for Foo {}
//~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
fn main() {}

View File

@ -12,17 +12,15 @@
#![feature(optin_builtin_traits)]
unsafe trait Trait {
unsafe auto trait Trait {
//~^ ERROR E0380
type Output;
}
#[allow(auto_impl)]
unsafe impl Trait for .. {}
fn call_method<T: Trait>(x: T) {}
fn main() {
// ICE
call_method(());
//~^ ERROR
}

View File

@ -12,16 +12,13 @@
#![feature(optin_builtin_traits)]
unsafe trait Trait {
unsafe auto trait Trait {
//~^ ERROR E0380
fn method(&self) {
println!("Hello");
}
}
#[allow(auto_impl)]
unsafe impl Trait for .. {}
fn call_method<T: Trait>(x: T) {
x.method();
}

View File

@ -16,10 +16,7 @@
use std::marker::{PhantomData};
unsafe trait Zen {}
#[allow(auto_impl)]
unsafe impl Zen for .. {}
unsafe auto trait Zen {}
unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}

View File

@ -10,7 +10,6 @@
#![feature(optin_builtin_traits)]
trait MarkerTr {}
pub trait Tr {
fn f();
const C: u8;
@ -21,8 +20,6 @@ pub struct S {
}
struct Ts(pub u8);
#[allow(auto_impl)]
pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
pub impl Tr for S { //~ ERROR unnecessary visibility qualifier
pub fn f() {} //~ ERROR unnecessary visibility qualifier
pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
@ -39,7 +36,6 @@ pub extern "C" { //~ ERROR unnecessary visibility qualifier
}
const MAIN: u8 = {
trait MarkerTr {}
pub trait Tr {
fn f();
const C: u8;
@ -50,8 +46,6 @@ const MAIN: u8 = {
}
struct Ts(pub u8);
#[allow(auto_impl)]
pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
pub impl Tr for S { //~ ERROR unnecessary visibility qualifier
pub fn f() {} //~ ERROR unnecessary visibility qualifier
pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
@ -71,7 +65,6 @@ const MAIN: u8 = {
};
fn main() {
trait MarkerTr {}
pub trait Tr {
fn f();
const C: u8;
@ -82,8 +75,6 @@ fn main() {
}
struct Ts(pub u8);
#[allow(auto_impl)]
pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
pub impl Tr for S { //~ ERROR unnecessary visibility qualifier
pub fn f() {} //~ ERROR unnecessary visibility qualifier
pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier

View File

@ -1,20 +0,0 @@
// Copyright 2015 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(specialization)]
#![feature(optin_builtin_traits)]
trait Foo {}
#[allow(auto_impl)]
default impl Foo for .. {}
//~^ ERROR `default impl` is not allowed for auto trait implementations
fn main() {}

View File

@ -13,18 +13,12 @@
#![feature(optin_builtin_traits)]
#![feature(specialization)]
trait Foo {}
#[allow(auto_impl)]
impl Foo for .. {}
auto trait Foo {}
impl<T> Foo for T {}
impl !Foo for u8 {} //~ ERROR E0119
trait Bar {}
#[allow(auto_impl)]
impl Bar for .. {}
auto trait Bar {}
impl<T> !Bar for T {}
impl Bar for u8 {} //~ ERROR E0119

View File

@ -1,19 +0,0 @@
// Copyright 2015 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(optin_builtin_traits)]
trait MyAutoImpl {}
#[allow(auto_impl)]
impl<T> MyAutoImpl for .. {}
//~^ ERROR auto trait implementations are not allowed to have generics
fn main() {}

View File

@ -14,9 +14,7 @@
#![feature(optin_builtin_traits)]
trait Magic: Copy {} //~ ERROR E0568
#[allow(auto_impl)]
impl Magic for .. {}
auto trait Magic: Copy {} //~ ERROR E0568
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
@ -24,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);
}

View File

@ -10,9 +10,7 @@
#![feature(optin_builtin_traits)]
trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
#[allow(auto_impl)]
impl Magic for .. {}
auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
impl<T:Magic> Magic for T {}
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }

View File

@ -34,9 +34,7 @@
#![feature(optin_builtin_traits)]
trait Magic: Copy {} //~ ERROR E0568
#[allow(auto_impl)]
impl Magic for .. {}
auto trait Magic: Copy {} //~ ERROR E0568
impl<T:Magic> Magic for T {}
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }

View File

@ -1,15 +0,0 @@
// Copyright 2016 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(optin_builtin_traits)]
trait Magic<T> {} //~ ERROR E0567
#[allow(auto_impl)]
impl Magic<isize> for .. {}

View File

@ -10,10 +10,7 @@
#![feature(optin_builtin_traits)]
trait MyTrait {}
#[allow(auto_impl)]
impl MyTrait for .. {}
auto trait MyTrait {}
struct MyS;

View File

@ -10,10 +10,8 @@
#![feature(optin_builtin_traits)]
trait MyTrait {}
auto trait MyTrait {}
#[allow(auto_impl)]
impl MyTrait for .. {}
impl<T> !MyTrait for *mut T {}
struct MyS;

View File

@ -10,15 +10,9 @@
#![feature(optin_builtin_traits)]
trait MyTrait {}
auto trait MyTrait {}
#[allow(auto_impl)]
impl MyTrait for .. {}
unsafe trait MyUnsafeTrait {}
#[allow(auto_impl)]
unsafe impl MyUnsafeTrait for .. {}
unsafe auto trait MyUnsafeTrait {}
struct ThisImplsTrait;

View File

@ -10,14 +10,12 @@
// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies
// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
// other words, the `..` impl only applies if there are no existing
// other words, the auto impl only applies if there are no existing
// impls whose types unify.
#![feature(optin_builtin_traits)]
trait Defaulted { }
#[allow(auto_impl)]
impl Defaulted for .. { }
auto trait Defaulted { }
impl<'a,T:Signed> Defaulted for &'a T { }
impl<'a,T:Signed> Defaulted for &'a mut T { }
fn is_defaulted<T:Defaulted>() { }

View File

@ -80,6 +80,4 @@ pub mod marker {
}
#[lang = "freeze"]
trait Freeze {}
#[allow(auto_impl)]
impl Freeze for .. {}
auto trait Freeze {}

View File

@ -18,9 +18,7 @@ trait Copy { }
trait Sized { }
#[lang = "freeze"]
trait Freeze {}
#[allow(auto_impl)]
impl Freeze for .. {}
auto trait Freeze {}
#[lang="start"]
fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 }

View File

@ -11,10 +11,6 @@
#![feature(optin_builtin_traits)]
auto trait Auto {}
// Redundant but accepted until we remove it.
#[allow(auto_impl)]
impl Auto for .. {}
unsafe auto trait AutoUnsafe {}
impl !Auto for bool {}
@ -29,6 +25,10 @@ fn take_auto<T: Auto>(_: T) {}
fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
fn main() {
// Parse inside functions.
auto trait AutoInner {}
unsafe auto trait AutoUnsafeInner {}
take_auto(0);
take_auto(AutoBool(true));
take_auto_unsafe(0);

View File

@ -10,9 +10,8 @@
#![feature(optin_builtin_traits)]
trait NotSame {}
#[allow(auto_impl)]
impl NotSame for .. {}
auto trait NotSame {}
impl<A> !NotSame for (A, A) {}
trait OneOfEach {}

View File

@ -14,10 +14,7 @@
pub mod bar {
use std::marker;
pub trait Bar {}
#[allow(auto_impl)]
impl Bar for .. {}
pub auto trait Bar {}
pub trait Foo {
fn foo(&self) {}

View File

@ -10,7 +10,4 @@
#![feature(optin_builtin_traits)]
pub trait AnOibit {}
#[allow(auto_impl)]
impl AnOibit for .. {}
pub auto trait AnOibit {}

View File

@ -10,10 +10,7 @@
#![feature(optin_builtin_traits)]
pub trait AnOibit {}
#[allow(auto_impl)]
impl AnOibit for .. {}
pub auto trait AnOibit {}
pub struct Foo<T> { field: T }

View File

@ -20,10 +20,6 @@ trait DummyTrait {
auto trait AutoDummyTrait {}
//~^ ERROR auto traits are experimental and possibly buggy
#[allow(auto_impl)]
impl DummyTrait for .. {}
//~^ ERROR auto trait implementations are experimental and possibly buggy
impl !DummyTrait for DummyStruct {}
//~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now

View File

@ -6,21 +6,13 @@ error: auto traits are experimental and possibly buggy (see issue #13231)
|
= help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
error: auto trait implementations are experimental and possibly buggy (see issue #13231)
--> $DIR/feature-gate-optin-builtin-traits.rs:24:1
|
24 | impl DummyTrait for .. {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
error: negative trait bounds are not yet fully implemented; use marker types for now (see issue #13231)
--> $DIR/feature-gate-optin-builtin-traits.rs:27:1
--> $DIR/feature-gate-optin-builtin-traits.rs:23:1
|
27 | impl !DummyTrait for DummyStruct {}
23 | impl !DummyTrait for DummyStruct {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

View File

@ -8,9 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(optin_builtin_traits)]
trait Trait1 {}
trait Trait2 {}
trait Foo {}
impl Foo for .. {}
//~^ ERROR The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`
//~^^ WARN this was previously accepted by the compiler
#[cfg(not_enabled)]
impl Trait1 for .. {}
impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
fn main() {}

View File

@ -0,0 +1,10 @@
error: `impl Trait for .. {}` is an obsolete syntax
--> $DIR/obsolete-syntax-impl-for-dotdot.rs:17:1
|
17 | impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: use `auto trait Trait {}` instead
error: aborting due to previous error

View File

@ -1,15 +0,0 @@
// Copyright 2015 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(optin_builtin_traits)]
#[allow(auto_impl)]
impl Copy for .. {} //~ ERROR E0318
fn main() {}