From e4f6d986523c45e87e7f783ae914ee4807f03929 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Fri, 1 Dec 2017 10:01:23 -0200 Subject: [PATCH 1/8] Remove `impl Foo for ..` in favor of `auto trait Foo` No longer parse it. Remove AutoTrait variant from AST and HIR. Remove backwards compatibility lint. Remove coherence checks, they make no sense for the new syntax. Remove from rustdoc. --- src/libcore/marker.rs | 20 +----- src/liblibc | 2 +- src/librustc/dep_graph/dep_node.rs | 1 - src/librustc/hir/intravisit.rs | 4 -- src/librustc/hir/lowering.rs | 10 --- src/librustc/hir/map/def_collector.rs | 3 +- src/librustc/hir/map/mod.rs | 1 - src/librustc/hir/mod.rs | 7 +- src/librustc/hir/print.rs | 12 ---- src/librustc/ich/impls_hir.rs | 1 - src/librustc/middle/dead.rs | 1 - src/librustc/middle/reachable.rs | 3 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/traits/select.rs | 4 +- src/librustc/ty/item_path.rs | 4 +- src/librustc/ty/maps/mod.rs | 3 - src/librustc/ty/maps/plumbing.rs | 1 - src/librustc/ty/mod.rs | 2 - src/librustc_driver/test.rs | 3 +- .../persist/dirty_clean.rs | 3 - src/librustc_lint/builtin.rs | 25 ------- src/librustc_lint/lib.rs | 5 -- src/librustc_metadata/cstore_impl.rs | 1 - src/librustc_metadata/decoder.rs | 11 +--- src/librustc_metadata/encoder.rs | 12 ---- src/librustc_metadata/schema.rs | 2 - src/librustc_mir/monomorphize/collector.rs | 1 - src/librustc_passes/ast_validation.rs | 3 - src/librustc_privacy/lib.rs | 10 +-- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/lib.rs | 6 -- src/librustc_save_analysis/sig.rs | 11 ---- src/librustc_typeck/coherence/mod.rs | 1 - src/librustc_typeck/coherence/orphan.rs | 18 ----- src/librustc_typeck/coherence/overlap.rs | 52 --------------- src/librustc_typeck/coherence/unsafety.rs | 3 - src/librustc_typeck/collect.rs | 66 ++++++++++++++----- src/librustc_typeck/diagnostics.rs | 6 +- src/librustdoc/clean/inline.rs | 21 ------ src/librustdoc/clean/mod.rs | 25 ------- src/librustdoc/doctree.rs | 9 --- src/librustdoc/html/item_type.rs | 1 - src/librustdoc/html/render.rs | 16 +---- src/librustdoc/passes/mod.rs | 2 +- src/librustdoc/visit_ast.rs | 13 ---- src/libstd/panic.rs | 11 +--- src/libsyntax/ast.rs | 7 +- src/libsyntax/feature_gate.rs | 7 -- src/libsyntax/fold.rs | 3 - src/libsyntax/parse/parser.rs | 57 ++++++---------- src/libsyntax/print/pprust.rs | 12 ---- src/libsyntax/visit.rs | 3 - src/rtstartup/rsbegin.rs | 10 +-- src/rtstartup/rsend.rs | 5 +- .../syntaxt-default-trait-impls.rs | 19 ------ 55 files changed, 95 insertions(+), 448 deletions(-) delete mode 100644 src/test/compile-fail/syntaxt-default-trait-impls.rs diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 17e77654cf5ef..3032fb2de33ad 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -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 !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 !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 !Freeze for UnsafeCell {} unsafe impl Freeze for PhantomData {} diff --git a/src/liblibc b/src/liblibc index ef9eefb6df3f3..1a2f9639f8d29 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit ef9eefb6df3f3a2cb989e8050519661faa7d7118 +Subproject commit 1a2f9639f8d293cefbe050053a574decbfe863f7 diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 29839bb565bb4..8289f8fb290c5 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -496,7 +496,6 @@ define_dep_nodes!( <'tcx> [] SuperPredicatesOfItem(DefId), [] TraitDefOfItem(DefId), [] AdtDefOfItem(DefId), - [] IsAutoImpl(DefId), [] ImplTraitRef(DefId), [] ImplPolarity(DefId), [] FnSignature(DefId), diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 74714edfc8646..ce35e6552ca83 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -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); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1f7e7000d6555..49a9ac23eea40 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1951,16 +1951,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, diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 002849c0399c3..d68b18dd2f17d 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -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(..) => diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 33debf6aeb0dd..5d55212c3a68d 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -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) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7d3699b35eb23..8893ee7e2313f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -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 Trait for Foo { .. }` ItemImpl(Unsafety, ImplPolarity, @@ -1996,8 +1992,7 @@ impl Item_ { ItemUnion(..) => "union", ItemTrait(..) => "trait", ItemTraitAlias(..) => "trait alias", - ItemImpl(..) | - ItemAutoImpl(..) => "item", + ItemImpl(..) => "item", } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 2f9fc70252f8d..a8e55674ae521 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -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, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 125b82ab4d0d4..cc1b028480e4d 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -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) }); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 21eb772b1b376..5952d8bad7489 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -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, }; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 6f457c9d1e1b2..e11609ea9b798 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -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) => { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8b302dbe67a42..935dfd75dd8b7 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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. diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 6482ecc7ee161..51d2bc8701a4e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -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 diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 0fecb5314bf44..0c920a6f13e59 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -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); diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 7c9d274e1fe06..701fd67cd9403 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -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, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index ea71367d8852f..c384bd825fcf0 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -800,7 +800,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!()); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2cea8c01cdf96..5e94d2261fcd2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2406,8 +2406,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 } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 6765ea5e67a60..371f0e79a3ad1 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -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), }; diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index b17503137f508..96f6339d56fb1 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -392,9 +392,6 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { // //HirItem::ItemTrait(..) => ("ItemTrait", LABELS_TRAIT), - // `impl Trait for .. {}` - HirItem::ItemAutoImpl(..) => ("ItemAutoImpl", LABELS_IMPL), - // An implementation, eg `impl Trait for Foo { .. }` HirItem::ItemImpl(..) => ("ItemImpl", LABELS_IMPL), diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a2a6a0da68ff0..f2ca1f65bf2c9 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 3d7f05afefc1f..699765dde03ff 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -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 ", - }, FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 955648208cd8b..b04bcf73e1757 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -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 => { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index fb4a73891a34e..d940055e3d4a5 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -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>) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 5ddbb18450e2e..09f55307d7d22 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -928,17 +928,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 { @@ -1533,7 +1522,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 diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 8ff327463917a..ffcb5c27e537e 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -303,7 +303,6 @@ pub enum EntryKind<'tcx> { Generator(Lazy>), Trait(Lazy>), Impl(Lazy>), - AutoImpl(Lazy>), Method(Lazy>), AssociatedType(AssociatedContainer), AssociatedConst(AssociatedContainer, u8), @@ -359,7 +358,6 @@ impl<'gcx> HashStable> 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); } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index e9a8c2427b373..c61c61bd5e123 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -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(..) => { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 61f54774163d4..d929bae7f68a1 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -229,9 +229,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, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index bb0a4be49c2a8..bcc1ca3a8eae1 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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) => { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 5866c8f93f094..59d0ff8dc5cad 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b49d9d2c7cf11..13d9038de9e60 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1893,12 +1893,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, diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 9211ddfab671e..0c890ce19d081 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -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, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index adf154968c229..952c0e18644c3 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -131,7 +131,6 @@ 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); diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 9f18397362189..ab19a862a66fd 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -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 } diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 5cc6eaa5602fb..8c7db918f5ac2 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -15,16 +15,6 @@ 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); @@ -66,45 +56,3 @@ pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { } } } - -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) { - } -} diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 280fb04e04001..c924a3364ebf0 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -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); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 0a6d87e5a60b7..fcce25d371d2d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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); @@ -1109,7 +1105,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 +1273,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); @@ -1729,13 +1719,53 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -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) +struct ImplTraitUniversalInfo<'hir> { + id: ast::NodeId, + def_id: DefId, + span: Span, + bounds: &'hir [hir::TyParamBound], +} + +/// Take some possible list of arguments and return the DefIds of the ImplTraitUniversal +/// arguments +fn extract_universal_impl_trait_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + opt_inputs: Option<&'tcx [P]>) + -> Vec> +{ + // A visitor for simply collecting Universally quantified impl Trait arguments + struct ImplTraitUniversalVisitor<'tcx> { + items: Vec<&'tcx hir::Ty> } + + impl<'tcx> Visitor<'tcx> for ImplTraitUniversalVisitor<'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::None + } + + fn visit_ty(&mut self, ty: &'tcx hir::Ty) { + if let hir::TyImplTraitUniversal(..) = ty.node { + self.items.push(ty); + } + intravisit::walk_ty(self, ty); + } + } + + let mut visitor = ImplTraitUniversalVisitor { items: Vec::new() }; + + if let Some(inputs) = opt_inputs { + for t in inputs.iter() { + visitor.visit_ty(t); + } + } + + visitor.items.into_iter().map(|ty| if let hir::TyImplTraitUniversal(_, ref bounds) = ty.node { + ImplTraitUniversalInfo { + id: ty.id, + def_id: tcx.hir.local_def_id(ty.id), + span: ty.span, + bounds: bounds + } + } else { + span_bug!(ty.span, "this type should be a universally quantified impl trait. this is a bug") + }).collect() } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 770d0cd4f1fc4..a9a6273b31de3 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -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 { } ``` diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 914365b003e18..56a2a9c3d03aa 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -300,27 +300,6 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec) { } } - // 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 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 10cb2e5f3fdaf..dbd6f5e402022 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -430,7 +430,6 @@ pub enum ItemEnum { PrimitiveItem(PrimitiveType), AssociatedConstItem(Type, Option), AssociatedTypeItem(Vec, Option), - AutoImplItem(AutoImpl), /// An item that has been stripped by a rustdoc pass StrippedItem(Box), } @@ -2941,30 +2940,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 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 for doctree::ExternCrate { fn clean(&self, cx: &DocContext) -> Item { Item { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index c21bfd8842f72..b5c173b15d6d8 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -44,7 +44,6 @@ pub struct Module { pub stab: Option, pub depr: Option, pub impls: Vec, - pub def_traits: Vec, pub foreigns: Vec, pub macros: Vec, pub is_crate: bool, @@ -227,14 +226,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, - 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 { diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index c214c15ed4b2b..81087cd412e2c 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -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!(), } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index afbaf037c7def..c5364a2cf50a3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1983,12 +1983,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::>(); + let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()) + .collect::>(); // the order of item types in the listing fn reorder(ty: ItemType) -> u8 { @@ -4013,13 +4009,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"), diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 3e15d3d3007ac..32f0bcada1d20 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -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(..) => {} diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index be78935cadfbb..dfadb71a6a5eb 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -547,19 +547,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); - } - } } } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 219e55d6c1206..1be3844e29a1c 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -187,10 +187,7 @@ pub struct AssertUnwindSafe( // * 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 UnwindSafe for Rc {} impl UnwindSafe for Arc {} // 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 !RefUnwindSafe for UnsafeCell {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl RefUnwindSafe for AssertUnwindSafe {} diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 15682b2d459fa..e2afbabb115fb 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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 Trait for .. {}` - AutoImpl(Unsafety, TraitRef), /// An implementation. /// /// E.g. `impl Foo { .. }` or `impl Trait for Foo { .. }` @@ -2064,8 +2060,7 @@ impl ItemKind { ItemKind::TraitAlias(..) => "trait alias", ItemKind::Mac(..) | ItemKind::MacroDef(..) | - ItemKind::Impl(..) | - ItemKind::AutoImpl(..) => "item" + ItemKind::Impl(..) => "item" } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e5ef9393e7bf7..8cadec2562a03 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1530,13 +1530,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, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6682a3439f1b9..c304e3a9f5052 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -911,9 +911,6 @@ pub fn noop_fold_item_kind(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, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 812e3c4967a9d..943d664906ebc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5325,11 +5325,9 @@ impl<'a> Parser<'a> { /// Parses items implementations variants /// impl Foo { ... } /// impl 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()?; @@ -5372,48 +5370,31 @@ 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 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))?; - 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()?; + 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()?; + 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> { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index dd343a2384b1f..5374bf180f49a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bd68d7cf8f5d8..b5fc9236ad39a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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, diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs index d33b52486296f..7d5581bb774b0 100644 --- a/src/rtstartup/rsbegin.rs +++ b/src/rtstartup/rsbegin.rs @@ -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] diff --git a/src/rtstartup/rsend.rs b/src/rtstartup/rsend.rs index 410366d0d7ff5..f487f1d410e03 100644 --- a/src/rtstartup/rsend.rs +++ b/src/rtstartup/rsend.rs @@ -22,10 +22,7 @@ impl 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] diff --git a/src/test/compile-fail/syntaxt-default-trait-impls.rs b/src/test/compile-fail/syntaxt-default-trait-impls.rs deleted file mode 100644 index 45303cbf70025..0000000000000 --- a/src/test/compile-fail/syntaxt-default-trait-impls.rs +++ /dev/null @@ -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 or the MIT license -// , 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 MyAutoImpl for .. {} -//~^ ERROR auto trait implementations are not allowed to have generics - -fn main() {} From 2896f52cbf086df488f82d3b4f003deb39a5c409 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Sun, 3 Dec 2017 10:56:53 -0200 Subject: [PATCH 2/8] Adjust tests for removal of `impl Foo for .. {}` --- src/libstd/panic.rs | 4 ++-- .../compile-fail/auto-impl-future-compat.rs | 16 --------------- .../auxiliary/tdticc_coherence_lib.rs | 4 +--- .../coherence-default-trait-impl.rs | 17 +++++----------- src/test/compile-fail/issue-23080-2.rs | 5 +---- src/test/compile-fail/issue-23080.rs | 5 +---- src/test/compile-fail/phantom-oibit.rs | 5 +---- src/test/compile-fail/privacy-sanity.rs | 9 --------- ...zation-no-default-trait-implementations.rs | 20 ------------------- .../specialization/specialization-polarity.rs | 10 ++-------- ...its-inductive-overflow-supertrait-oibit.rs | 4 +--- .../typeck-auto-trait-no-supertraits-2.rs | 4 +--- .../typeck-auto-trait-no-supertraits.rs | 4 +--- .../typeck-auto-trait-no-typeparams.rs | 15 -------------- ...-default-trait-impl-constituent-types-2.rs | 5 +---- ...ck-default-trait-impl-constituent-types.rs | 4 +--- .../typeck-default-trait-impl-negation.rs | 10 ++-------- .../typeck-default-trait-impl-precedence.rs | 6 ++---- src/test/run-make/simd-ffi/simd.rs | 4 +--- src/test/run-make/target-specs/foo.rs | 4 +--- src/test/run-pass/auto-traits.rs | 3 --- src/test/run-pass/issue-29516.rs | 5 ++--- .../rustdoc/auxiliary/rustdoc-default-impl.rs | 5 +---- .../rustdoc-impl-parts-crosscrate.rs | 5 +---- src/test/rustdoc/impl-parts.rs | 5 +---- .../ui/feature-gate-optin-builtin-traits.rs | 4 ---- ...typeck-default-trait-impl-outside-crate.rs | 15 -------------- 27 files changed, 29 insertions(+), 168 deletions(-) delete mode 100644 src/test/compile-fail/auto-impl-future-compat.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs delete mode 100644 src/test/compile-fail/typeck-auto-trait-no-typeparams.rs delete mode 100644 src/test/ui/typeck-default-trait-impl-outside-crate.rs diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 1be3844e29a1c..53c2211745c32 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -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. /// diff --git a/src/test/compile-fail/auto-impl-future-compat.rs b/src/test/compile-fail/auto-impl-future-compat.rs deleted file mode 100644 index 5c32a75639880..0000000000000 --- a/src/test/compile-fail/auto-impl-future-compat.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(optin_builtin_traits)] - -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 diff --git a/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs b/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs index 1e1c55de87e17..f6f7a250174ba 100644 --- a/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs +++ b/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs @@ -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 } diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs index 9c26b8b05f259..a01bc791a45f2 100644 --- a/src/test/compile-fail/coherence-default-trait-impl.rs +++ b/src/test/compile-fail/coherence-default-trait-impl.rs @@ -10,25 +10,18 @@ #![feature(optin_builtin_traits)] -trait MyTrait { fn foo() {} } +auto trait MySafeTrait {} -#[allow(auto_impl)] -impl MyTrait for .. {} -//~^ ERROR redundant auto implementations of trait `MyTrait` - -#[allow(auto_impl)] -impl MyTrait for .. {} - -trait MySafeTrait {} +struct Foo; #[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() {} diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs index bf44cd53f67dc..0be80f41661ec 100644 --- a/src/test/compile-fail/issue-23080-2.rs +++ b/src/test/compile-fail/issue-23080-2.rs @@ -12,14 +12,11 @@ #![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(x: T) {} fn main() { diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs index 1fb63391d5608..153b6fd07e6d1 100644 --- a/src/test/compile-fail/issue-23080.rs +++ b/src/test/compile-fail/issue-23080.rs @@ -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(x: T) { x.method(); } diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs index 1c1cb396a54f2..52bc0126612bf 100644 --- a/src/test/compile-fail/phantom-oibit.rs +++ b/src/test/compile-fail/phantom-oibit.rs @@ -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 {} diff --git a/src/test/compile-fail/privacy-sanity.rs b/src/test/compile-fail/privacy-sanity.rs index 34082adb8f9a5..f245b7cef29b9 100644 --- a/src/test/compile-fail/privacy-sanity.rs +++ b/src/test/compile-fail/privacy-sanity.rs @@ -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 diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs deleted file mode 100644 index cad43ffeacec9..0000000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs +++ /dev/null @@ -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 or the MIT license -// , 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() {} diff --git a/src/test/compile-fail/specialization/specialization-polarity.rs b/src/test/compile-fail/specialization/specialization-polarity.rs index c97cb3f6bb70b..b28a63c8293ae 100644 --- a/src/test/compile-fail/specialization/specialization-polarity.rs +++ b/src/test/compile-fail/specialization/specialization-polarity.rs @@ -13,18 +13,12 @@ #![feature(optin_builtin_traits)] #![feature(specialization)] -trait Foo {} - -#[allow(auto_impl)] -impl Foo for .. {} +auto trait Foo {} impl Foo for T {} impl !Foo for u8 {} //~ ERROR E0119 -trait Bar {} - -#[allow(auto_impl)] -impl Bar for .. {} +auto trait Bar {} impl !Bar for T {} impl Bar for u8 {} //~ ERROR E0119 diff --git a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs index 6c7928f13f894..61c504d3e1be3 100644 --- a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs +++ b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs @@ -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(x: T) -> (T, T) { (x, x) } diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs index 173582ed22fdc..fa63088d00088 100644 --- a/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs +++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs @@ -10,9 +10,7 @@ #![feature(optin_builtin_traits)] -trait Magic : Sized where Option : Magic {} //~ ERROR E0568 -#[allow(auto_impl)] -impl Magic for .. {} +auto trait Magic : Sized where Option : Magic {} //~ ERROR E0568 impl Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs index 6802f72504b7d..c8cf96f52fcf1 100644 --- a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs +++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs @@ -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 Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } diff --git a/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs b/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs deleted file mode 100644 index 3c409d1b371eb..0000000000000 --- a/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs +++ /dev/null @@ -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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(optin_builtin_traits)] - -trait Magic {} //~ ERROR E0567 -#[allow(auto_impl)] -impl Magic for .. {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs index a837d8c9ca74e..6e7c9afb6749a 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs @@ -10,10 +10,7 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} - -#[allow(auto_impl)] -impl MyTrait for .. {} +auto trait MyTrait {} struct MyS; diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs index bed184eb4ccca..4660ecf4fb4b4 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs @@ -10,10 +10,8 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +auto trait MyTrait {} -#[allow(auto_impl)] -impl MyTrait for .. {} impl !MyTrait for *mut T {} struct MyS; diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation.rs b/src/test/compile-fail/typeck-default-trait-impl-negation.rs index f3a6d8a342e22..b28cdd8aa2450 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-negation.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-negation.rs @@ -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; diff --git a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs index bdd6487b86d74..d63d70bad2204 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs @@ -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() { } diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs index 185476fb704f7..94b91c711cce0 100644 --- a/src/test/run-make/simd-ffi/simd.rs +++ b/src/test/run-make/simd-ffi/simd.rs @@ -80,6 +80,4 @@ pub mod marker { } #[lang = "freeze"] -trait Freeze {} -#[allow(auto_impl)] -impl Freeze for .. {} +auto trait Freeze {} diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index a0feb72702834..bbd1c5d900faf 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -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 } diff --git a/src/test/run-pass/auto-traits.rs b/src/test/run-pass/auto-traits.rs index e42aca9ccbd13..2511488c94ee8 100644 --- a/src/test/run-pass/auto-traits.rs +++ b/src/test/run-pass/auto-traits.rs @@ -11,9 +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 {} diff --git a/src/test/run-pass/issue-29516.rs b/src/test/run-pass/issue-29516.rs index 5fa0a002a10db..465986583b155 100644 --- a/src/test/run-pass/issue-29516.rs +++ b/src/test/run-pass/issue-29516.rs @@ -10,9 +10,8 @@ #![feature(optin_builtin_traits)] -trait NotSame {} -#[allow(auto_impl)] -impl NotSame for .. {} +auto trait NotSame {} + impl !NotSame for (A, A) {} trait OneOfEach {} diff --git a/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs index 4fd55bd482cd9..34a1331353dca 100644 --- a/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs +++ b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs @@ -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) {} diff --git a/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs b/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs index d886778278dfd..977d98ca87b10 100644 --- a/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs +++ b/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs @@ -10,7 +10,4 @@ #![feature(optin_builtin_traits)] -pub trait AnOibit {} - -#[allow(auto_impl)] -impl AnOibit for .. {} +pub auto trait AnOibit {} diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs index f74f66ce72905..6e472da379c59 100644 --- a/src/test/rustdoc/impl-parts.rs +++ b/src/test/rustdoc/impl-parts.rs @@ -10,10 +10,7 @@ #![feature(optin_builtin_traits)] -pub trait AnOibit {} - -#[allow(auto_impl)] -impl AnOibit for .. {} +pub auto trait AnOibit {} pub struct Foo { field: T } diff --git a/src/test/ui/feature-gate-optin-builtin-traits.rs b/src/test/ui/feature-gate-optin-builtin-traits.rs index 4c5502cec18a8..ab3313af16d5d 100644 --- a/src/test/ui/feature-gate-optin-builtin-traits.rs +++ b/src/test/ui/feature-gate-optin-builtin-traits.rs @@ -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 diff --git a/src/test/ui/typeck-default-trait-impl-outside-crate.rs b/src/test/ui/typeck-default-trait-impl-outside-crate.rs deleted file mode 100644 index ff0446e23e63e..0000000000000 --- a/src/test/ui/typeck-default-trait-impl-outside-crate.rs +++ /dev/null @@ -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 or the MIT license -// , 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() {} From 9c72171c320c29bb89b42485d444696c6c83d4da Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Sun, 3 Dec 2017 20:07:50 -0200 Subject: [PATCH 3/8] Remove wfcheck for auto traits, remove dead error codes The WF checks are now done as an AST validation. --- src/librustc_passes/ast_validation.rs | 12 ++-- src/librustc_passes/diagnostics.rs | 9 +++ src/librustc_typeck/check/wfcheck.rs | 72 ------------------- src/librustc_typeck/collect.rs | 10 +-- src/librustc_typeck/diagnostics.rs | 17 ----- .../compile-fail/auto-trait-validation.rs | 9 +-- .../coherence-default-trait-impl.rs | 2 - src/test/compile-fail/issue-23080-2.rs | 1 + ...its-inductive-overflow-supertrait-oibit.rs | 2 +- 9 files changed, 23 insertions(+), 111 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index d929bae7f68a1..ba819cbf5388d 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -247,16 +247,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 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); diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 3597a6f18287e..2244463518eab 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -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 type parameters + E0568, // auto traits can not have predicates E0642, // patterns aren't allowed in methods without bodies } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 385b9321db71a..f518482b73a01 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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`. - // - // 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, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fcce25d371d2d..4754aaceff45d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index a9a6273b31de3..c1714379087cb 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -2531,13 +2531,6 @@ struct Bar { x: Foo } ``` "##, -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 @@ 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: @@ -4703,13 +4689,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 `{}` diff --git a/src/test/compile-fail/auto-trait-validation.rs b/src/test/compile-fail/auto-trait-validation.rs index b28b776d9c2a6..782e352c471b0 100644 --- a/src/test/compile-fail/auto-trait-validation.rs +++ b/src/test/compile-fail/auto-trait-validation.rs @@ -11,12 +11,9 @@ #![feature(optin_builtin_traits)] auto trait Generic {} -//~^ 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() {} diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs index a01bc791a45f2..751d0a14c57ee 100644 --- a/src/test/compile-fail/coherence-default-trait-impl.rs +++ b/src/test/compile-fail/coherence-default-trait-impl.rs @@ -14,13 +14,11 @@ auto trait MySafeTrait {} 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 diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs index 0be80f41661ec..2aa87f8424b95 100644 --- a/src/test/compile-fail/issue-23080-2.rs +++ b/src/test/compile-fail/issue-23080-2.rs @@ -22,4 +22,5 @@ fn call_method(x: T) {} fn main() { // ICE call_method(()); + //~^ ERROR } diff --git a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs index 61c504d3e1be3..59d5dc6c58b47 100644 --- a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs +++ b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs @@ -22,6 +22,6 @@ fn copy(x: T) -> (T, T) { (x, x) } struct NoClone; fn main() { - let (a, b) = copy(NoClone); + let (a, b) = copy(NoClone); //~ ERROR println!("{:?} {:?}", a, b); } From 2043b896e730fa020298d54ebfd60b0d2a522e9c Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Sun, 3 Dec 2017 20:29:17 -0200 Subject: [PATCH 4/8] Move coherence/overlap.rs into coherence/mod.rs `fn check_impl` was feeling lonely with a file all for itself. --- src/librustc_typeck/coherence/mod.rs | 47 ++++++++++++++++++- src/librustc_typeck/coherence/overlap.rs | 58 ------------------------ 2 files changed, 45 insertions(+), 60 deletions(-) delete mode 100644 src/librustc_typeck/coherence/overlap.rs diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 952c0e18644c3..f65d627781f0f 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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); } @@ -136,3 +136,46 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { 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)); + } + } + } +} diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs deleted file mode 100644 index 8c7db918f5ac2..0000000000000 --- a/src/librustc_typeck/coherence/overlap.rs +++ /dev/null @@ -1,58 +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 or the MIT license -// , 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; - -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)); - } - } - } -} From c05631e7317a7bd57aa3ff4e1146fde9b9c38a40 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Mon, 4 Dec 2017 08:07:01 -0200 Subject: [PATCH 5/8] Fix rustdoc --- src/librustdoc/clean/mod.rs | 1 - src/librustdoc/doctree.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dbd6f5e402022..d772a7734a7d8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -480,7 +480,6 @@ impl Clean 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. diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index b5c173b15d6d8..776ec7f409c44 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -72,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, From 792ecaab2183482c92f3d2bca3e390f916200cab Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Mon, 4 Dec 2017 16:26:20 -0200 Subject: [PATCH 6/8] Parse `auto trait` inside fns. Also refactored parsing auto traits. --- src/libsyntax/parse/parser.rs | 28 ++++++++++++++++------------ src/test/run-pass/auto-traits.rs | 5 ++++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 943d664906ebc..daae2f9a5d78c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4037,14 +4037,14 @@ impl<'a> Parser<'a> { self.token.is_keyword(keywords::Crate) && 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 { @@ -4147,7 +4147,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. @@ -4155,7 +4156,8 @@ impl<'a> Parser<'a> { } else if self.token.is_path_start() && !self.token.is_qpath_start() && !self.is_union_item() && - !self.is_crate_vis() { + !self.is_crate_vis() && + !self.is_auto_trait_item() { let pth = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { @@ -6314,7 +6316,8 @@ impl<'a> Parser<'a> { let is_auto = if self.eat_keyword(keywords::Trait) { IsAuto::No } else { - self.eat_auto_trait(); + self.eat_keyword(keywords::Auto); + self.eat_keyword(keywords::Trait); IsAuto::Yes }; let (ident, item_, extra_attrs) = @@ -6428,7 +6431,8 @@ impl<'a> Parser<'a> { let is_auto = if self.eat_keyword(keywords::Trait) { IsAuto::No } else { - self.eat_auto_trait(); + self.eat_keyword(keywords::Auto); + self.eat_keyword(keywords::Trait); IsAuto::Yes }; // TRAIT ITEM diff --git a/src/test/run-pass/auto-traits.rs b/src/test/run-pass/auto-traits.rs index 2511488c94ee8..2a18b402bc64d 100644 --- a/src/test/run-pass/auto-traits.rs +++ b/src/test/run-pass/auto-traits.rs @@ -11,7 +11,6 @@ #![feature(optin_builtin_traits)] auto trait Auto {} - unsafe auto trait AutoUnsafe {} impl !Auto for bool {} @@ -26,6 +25,10 @@ fn take_auto(_: T) {} fn take_auto_unsafe(_: T) {} fn main() { + // Parse inside functions. + auto trait AutoInner {} + unsafe auto trait AutoUnsafeInner {} + take_auto(0); take_auto(AutoBool(true)); take_auto_unsafe(0); From 4e0aec84992eea8ab631f4866cb0986680161a94 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Mon, 4 Dec 2017 20:55:14 -0200 Subject: [PATCH 7/8] Address review. --- src/librustc_passes/ast_validation.rs | 6 +-- src/librustc_passes/diagnostics.rs | 4 +- src/librustc_typeck/collect.rs | 53 +------------------ src/libsyntax/parse/parser.rs | 8 +-- .../compile-fail/auto-trait-validation.rs | 6 +-- .../feature-gate-optin-builtin-traits.stderr | 14 ++--- 6 files changed, 16 insertions(+), 75 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index ba819cbf5388d..8342af6011d0c 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -248,15 +248,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Auto traits cannot have generics, super traits nor contain items. if generics.is_parameterized() { struct_span_err!(self.session, item.span, E0567, - "Auto traits cannot have generic parameters").emit(); + "auto traits cannot have generic parameters").emit(); } if !bounds.is_empty() { struct_span_err!(self.session, item.span, E0568, - "Auto traits cannot have predicates").emit(); + "auto traits cannot have super traits").emit(); } if !trait_items.is_empty() { struct_span_err!(self.session, item.span, E0380, - "Auto traits cannot have methods or associated items").emit(); + "auto traits cannot have methods or associated items").emit(); } } self.no_questions_in_bounds(bounds, "supertraits", true); diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 2244463518eab..cbfdace7e0ff2 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -271,7 +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 type parameters - E0568, // auto traits can not have predicates + 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 } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4754aaceff45d..5485045b70438 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -714,7 +714,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, 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), + hir::ItemTraitAlias(..) => (false, hir::Unsafety::Normal), _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; @@ -1714,54 +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) } } - -struct ImplTraitUniversalInfo<'hir> { - id: ast::NodeId, - def_id: DefId, - span: Span, - bounds: &'hir [hir::TyParamBound], -} - -/// Take some possible list of arguments and return the DefIds of the ImplTraitUniversal -/// arguments -fn extract_universal_impl_trait_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - opt_inputs: Option<&'tcx [P]>) - -> Vec> -{ - // A visitor for simply collecting Universally quantified impl Trait arguments - struct ImplTraitUniversalVisitor<'tcx> { - items: Vec<&'tcx hir::Ty> - } - - impl<'tcx> Visitor<'tcx> for ImplTraitUniversalVisitor<'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::None - } - - fn visit_ty(&mut self, ty: &'tcx hir::Ty) { - if let hir::TyImplTraitUniversal(..) = ty.node { - self.items.push(ty); - } - intravisit::walk_ty(self, ty); - } - } - - let mut visitor = ImplTraitUniversalVisitor { items: Vec::new() }; - - if let Some(inputs) = opt_inputs { - for t in inputs.iter() { - visitor.visit_ty(t); - } - } - - visitor.items.into_iter().map(|ty| if let hir::TyImplTraitUniversal(_, ref bounds) = ty.node { - ImplTraitUniversalInfo { - id: ty.id, - def_id: tcx.hir.local_def_id(ty.id), - span: ty.span, - bounds: bounds - } - } else { - span_bug!(ty.span, "this type should be a universally quantified impl trait. this is a bug") - }).collect() -} diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index daae2f9a5d78c..58a51d09f8502 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6316,8 +6316,8 @@ impl<'a> Parser<'a> { let is_auto = if self.eat_keyword(keywords::Trait) { IsAuto::No } else { - self.eat_keyword(keywords::Auto); - self.eat_keyword(keywords::Trait); + self.expect_keyword(keywords::Auto)?; + self.expect_keyword(keywords::Trait)?; IsAuto::Yes }; let (ident, item_, extra_attrs) = @@ -6431,8 +6431,8 @@ impl<'a> Parser<'a> { let is_auto = if self.eat_keyword(keywords::Trait) { IsAuto::No } else { - self.eat_keyword(keywords::Auto); - self.eat_keyword(keywords::Trait); + self.expect_keyword(keywords::Auto)?; + self.expect_keyword(keywords::Trait)?; IsAuto::Yes }; // TRAIT ITEM diff --git a/src/test/compile-fail/auto-trait-validation.rs b/src/test/compile-fail/auto-trait-validation.rs index 782e352c471b0..92b222e1322b8 100644 --- a/src/test/compile-fail/auto-trait-validation.rs +++ b/src/test/compile-fail/auto-trait-validation.rs @@ -11,9 +11,9 @@ #![feature(optin_builtin_traits)] auto trait Generic {} -//~^ Auto traits cannot have type parameters [E0567] +//~^ auto traits cannot have generic parameters [E0567] auto trait Bound : Copy {} -//~^ Auto traits cannot have predicates [E0568] +//~^ auto traits cannot have super traits [E0568] auto trait MyTrait { fn foo() {} } -//~^ Auto traits cannot have methods or associated items [E0380] +//~^ auto traits cannot have methods or associated items [E0380] fn main() {} diff --git a/src/test/ui/feature-gate-optin-builtin-traits.stderr b/src/test/ui/feature-gate-optin-builtin-traits.stderr index c5e9614c29ad7..d66da1224f8b9 100644 --- a/src/test/ui/feature-gate-optin-builtin-traits.stderr +++ b/src/test/ui/feature-gate-optin-builtin-traits.stderr @@ -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 From bba03d96329d9bad4049cc4a5aab968875383fb8 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Fri, 5 Jan 2018 16:39:17 -0200 Subject: [PATCH 8/8] update crossbeam --- src/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 52bfa2ab1090e..fe81c227fe23a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ "cargotest 0.1.0", "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.14.0", - "crossbeam 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -435,12 +435,12 @@ dependencies = [ [[package]] name = "crossbeam" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -876,7 +876,7 @@ name = "ignore" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2813,8 +2813,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum compiletest_rs 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "562bafeec9aef1e3e08f1c5b0c542220bb80ff2894e5373a1f9d17c346412c66" "checksum core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8047f547cd6856d45b1cdd75ef8d2f21f3d0e4bf1dab0a0041b0ae9a5dda9c0e" "checksum core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "152195421a2e6497a8179195672e9d4ee8e45ed8c465b626f1606d27a08ebcd5" -"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" -"checksum crossbeam 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8837ab96533202c5b610ed44bc7f4183e7957c1c8f56e8cc78bb098593c8ba0a" +"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" +"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34903878eec1694faf53cae8473a088df333181de421d4d3d48061d6559fe602" "checksum cssparser 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef6124306e5ebc5ab11891d063aeafdd0cdc308079b708c8b566125f3680292b" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"