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.
This commit is contained in:
leonardo.yvens 2017-12-01 10:01:23 -02:00 committed by Vadim Petrochenkov
parent 9b2f8ac29e
commit f93183adb4
54 changed files with 95 additions and 448 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,

View File

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

View File

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

View File

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

View File

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

View File

@ -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);

View File

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

View File

@ -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) {
}
}

View File

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

View File

@ -73,7 +73,6 @@ pub fn provide(providers: &mut Providers) {
impl_trait_ref,
impl_polarity,
is_foreign_item,
is_auto_impl,
..*providers
};
}
@ -424,9 +423,6 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
tcx.predicates_of(def_id);
convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
},
hir::ItemAutoImpl(..) => {
tcx.impl_trait_ref(def_id);
}
hir::ItemImpl(..) => {
tcx.generics_of(def_id);
tcx.type_of(def_id);
@ -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<hir::Ty>]>)
-> Vec<ImplTraitUniversalInfo<'tcx>>
{
// 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()
}

View File

@ -1854,14 +1854,12 @@ unsafe impl !Clone for Foo { }
This will compile:
```ignore (ignore auto_trait future compatibility warning)
```
#![feature(optin_builtin_traits)]
struct Foo;
trait Enterprise {}
impl Enterprise for .. { }
auto trait Enterprise {}
impl !Enterprise for Foo { }
```

View File

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

View File

@ -430,7 +430,6 @@ pub enum ItemEnum {
PrimitiveItem(PrimitiveType),
AssociatedConstItem(Type, Option<String>),
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
AutoImplItem(AutoImpl),
/// An item that has been stripped by a rustdoc pass
StrippedItem(Box<ItemEnum>),
}
@ -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<Item> for doctree::AutoImpl {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: cx.tcx.hir.local_def_id(self.id),
visibility: Some(Public),
stability: None,
deprecation: None,
inner: AutoImplItem(AutoImpl {
unsafety: self.unsafety,
trait_: self.trait_.clean(cx),
}),
}
}
}
impl Clean<Item> for doctree::ExternCrate {
fn clean(&self, cx: &DocContext) -> Item {
Item {

View File

@ -44,7 +44,6 @@ pub struct Module {
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub impls: Vec<Impl>,
pub def_traits: Vec<AutoImpl>,
pub foreigns: Vec<hir::ForeignMod>,
pub macros: Vec<Macro>,
pub is_crate: bool,
@ -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<ast::Attribute>,
pub whence: Span,
}
// For Macro we store the DefId instead of the NodeId, since we also create
// these imported macro_rules (which only have a DUMMY_NODE_ID).
pub struct Macro {

View File

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

View File

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

View File

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

View File

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

View File

@ -187,10 +187,7 @@ pub struct AssertUnwindSafe<T>(
// * Unique, an owning pointer, lifts an implementation
// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl UnwindSafe for .. {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
@ -219,14 +216,10 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
// Pretty simple implementations for the `RefUnwindSafe` marker trait,
// basically just saying that this is a marker trait and `UnsafeCell` is the
// basically just saying that `UnsafeCell` is the
// only thing which doesn't implement it (which then transitively applies to
// everything else).
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[allow(unknown_lints)]
#[allow(auto_impl)]
impl RefUnwindSafe for .. {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}

View File

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

View File

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

View File

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

View File

@ -5374,11 +5374,9 @@ impl<'a> Parser<'a> {
/// Parses items implementations variants
/// impl<T> Foo { ... }
/// impl<T> ToString for &'static T { ... }
/// impl Send for .. {}
fn parse_item_impl(&mut self,
unsafety: ast::Unsafety,
defaultness: Defaultness) -> PResult<'a, ItemInfo> {
let impl_span = self.span;
// First, parse type parameters if necessary.
let mut generics = self.parse_generics()?;
@ -5421,48 +5419,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 opt_trait.is_some() {
ty = self.parse_ty()?;
}
generics.where_clause = self.parse_where_clause()?;
if let ast::Defaultness::Default = defaultness {
self.span_err(impl_span, "`default impl` is not allowed for \
auto trait implementations");
}
self.expect(&token::OpenDelim(token::Brace))?;
let attrs = self.parse_inner_attributes()?;
self.expect(&token::OpenDelim(token::Brace))?;
self.expect(&token::CloseDelim(token::Brace))?;
Ok((keywords::Invalid.ident(),
ItemKind::AutoImpl(unsafety, opt_trait.unwrap()), None))
} else {
if opt_trait.is_some() {
ty = self.parse_ty()?;
}
generics.where_clause = self.parse_where_clause()?;
self.expect(&token::OpenDelim(token::Brace))?;
let attrs = self.parse_inner_attributes()?;
let mut impl_items = vec![];
while !self.eat(&token::CloseDelim(token::Brace)) {
let mut at_end = false;
match self.parse_impl_item(&mut at_end) {
Ok(item) => impl_items.push(item),
Err(mut e) => {
e.emit();
if !at_end {
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
}
let mut impl_items = vec![];
while !self.eat(&token::CloseDelim(token::Brace)) {
let mut at_end = false;
match self.parse_impl_item(&mut at_end) {
Ok(item) => impl_items.push(item),
Err(mut e) => {
e.emit();
if !at_end {
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
}
}
}
Ok((keywords::Invalid.ident(),
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
Some(attrs)))
}
Ok((keywords::Invalid.ident(),
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
Some(attrs)))
}
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,19 +0,0 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(optin_builtin_traits)]
trait MyAutoImpl {}
#[allow(auto_impl)]
impl<T> MyAutoImpl for .. {}
//~^ ERROR auto trait implementations are not allowed to have generics
fn main() {}