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:
parent
9b2f8ac29e
commit
f93183adb4
54 changed files with 95 additions and 448 deletions
|
@ -40,15 +40,10 @@ use hash::Hasher;
|
||||||
/// [ub]: ../../reference/behavior-considered-undefined.html
|
/// [ub]: ../../reference/behavior-considered-undefined.html
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
|
#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
|
||||||
pub unsafe trait Send {
|
pub unsafe auto trait Send {
|
||||||
// empty.
|
// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: ?Sized> !Send for *const T { }
|
impl<T: ?Sized> !Send for *const T { }
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -345,15 +340,10 @@ pub trait Copy : Clone {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[lang = "sync"]
|
#[lang = "sync"]
|
||||||
#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
|
#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
|
||||||
pub unsafe trait Sync {
|
pub unsafe auto trait Sync {
|
||||||
// Empty
|
// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: ?Sized> !Sync for *const T { }
|
impl<T: ?Sized> !Sync for *const T { }
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -563,11 +553,7 @@ mod impls {
|
||||||
/// This affects, for example, whether a `static` of that type is
|
/// This affects, for example, whether a `static` of that type is
|
||||||
/// placed in read-only static memory or writable static memory.
|
/// placed in read-only static memory or writable static memory.
|
||||||
#[lang = "freeze"]
|
#[lang = "freeze"]
|
||||||
unsafe trait Freeze {}
|
unsafe auto trait Freeze {}
|
||||||
|
|
||||||
#[allow(unknown_lints)]
|
|
||||||
#[allow(auto_impl)]
|
|
||||||
unsafe impl Freeze for .. {}
|
|
||||||
|
|
||||||
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
|
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
|
||||||
unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}
|
unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}
|
||||||
|
|
|
@ -496,7 +496,6 @@ define_dep_nodes!( <'tcx>
|
||||||
[] SuperPredicatesOfItem(DefId),
|
[] SuperPredicatesOfItem(DefId),
|
||||||
[] TraitDefOfItem(DefId),
|
[] TraitDefOfItem(DefId),
|
||||||
[] AdtDefOfItem(DefId),
|
[] AdtDefOfItem(DefId),
|
||||||
[] IsAutoImpl(DefId),
|
|
||||||
[] ImplTraitRef(DefId),
|
[] ImplTraitRef(DefId),
|
||||||
[] ImplPolarity(DefId),
|
[] ImplPolarity(DefId),
|
||||||
[] FnSignature(DefId),
|
[] FnSignature(DefId),
|
||||||
|
|
|
@ -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
|
// visit_enum_def() takes care of visiting the Item's NodeId
|
||||||
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
|
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) => {
|
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_refs) => {
|
||||||
visitor.visit_id(item.id);
|
visitor.visit_id(item.id);
|
||||||
visitor.visit_generics(type_parameters);
|
visitor.visit_generics(type_parameters);
|
||||||
|
|
|
@ -1952,16 +1952,6 @@ impl<'a> LoweringContext<'a> {
|
||||||
let vdata = self.lower_variant_data(vdata);
|
let vdata = self.lower_variant_data(vdata);
|
||||||
hir::ItemUnion(vdata, self.lower_generics(generics))
|
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,
|
ItemKind::Impl(unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
defaultness,
|
defaultness,
|
||||||
|
|
|
@ -104,8 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
// Pick the def data. This need not be unique, but the more
|
// Pick the def data. This need not be unique, but the more
|
||||||
// information we encapsulate into
|
// information we encapsulate into
|
||||||
let def_data = match i.node {
|
let def_data = match i.node {
|
||||||
ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
|
ItemKind::Impl(..) => DefPathData::Impl,
|
||||||
DefPathData::Impl,
|
|
||||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
||||||
ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
|
ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
|
||||||
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
|
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
|
||||||
|
|
|
@ -1192,7 +1192,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
|
||||||
ItemTrait(..) => "trait",
|
ItemTrait(..) => "trait",
|
||||||
ItemTraitAlias(..) => "trait alias",
|
ItemTraitAlias(..) => "trait alias",
|
||||||
ItemImpl(..) => "impl",
|
ItemImpl(..) => "impl",
|
||||||
ItemAutoImpl(..) => "default impl",
|
|
||||||
};
|
};
|
||||||
format!("{} {}{}", item_str, path_str(), id_str)
|
format!("{} {}{}", item_str, path_str(), id_str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1965,10 +1965,6 @@ pub enum Item_ {
|
||||||
/// Represents a Trait Alias Declaration
|
/// Represents a Trait Alias Declaration
|
||||||
ItemTraitAlias(Generics, TyParamBounds),
|
ItemTraitAlias(Generics, TyParamBounds),
|
||||||
|
|
||||||
/// Auto trait implementations
|
|
||||||
///
|
|
||||||
/// `impl Trait for .. {}`
|
|
||||||
ItemAutoImpl(Unsafety, TraitRef),
|
|
||||||
/// An implementation, eg `impl<A> Trait for Foo { .. }`
|
/// An implementation, eg `impl<A> Trait for Foo { .. }`
|
||||||
ItemImpl(Unsafety,
|
ItemImpl(Unsafety,
|
||||||
ImplPolarity,
|
ImplPolarity,
|
||||||
|
@ -1996,8 +1992,7 @@ impl Item_ {
|
||||||
ItemUnion(..) => "union",
|
ItemUnion(..) => "union",
|
||||||
ItemTrait(..) => "trait",
|
ItemTrait(..) => "trait",
|
||||||
ItemTraitAlias(..) => "trait alias",
|
ItemTraitAlias(..) => "trait alias",
|
||||||
ItemImpl(..) |
|
ItemImpl(..) => "item",
|
||||||
ItemAutoImpl(..) => "item",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -652,18 +652,6 @@ impl<'a> State<'a> {
|
||||||
self.head(&visibility_qualified(&item.vis, "union"))?;
|
self.head(&visibility_qualified(&item.vis, "union"))?;
|
||||||
self.print_struct(struct_def, generics, item.name, item.span, true)?;
|
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,
|
hir::ItemImpl(unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
defaultness,
|
defaultness,
|
||||||
|
|
|
@ -854,7 +854,6 @@ impl_stable_hash_for!(enum hir::Item_ {
|
||||||
ItemUnion(variant_data, generics),
|
ItemUnion(variant_data, generics),
|
||||||
ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
|
ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
|
||||||
ItemTraitAlias(generics, bounds),
|
ItemTraitAlias(generics, bounds),
|
||||||
ItemAutoImpl(unsafety, trait_ref),
|
|
||||||
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
|
ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -564,7 +564,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
|
||||||
hir::ItemStruct(..) |
|
hir::ItemStruct(..) |
|
||||||
hir::ItemUnion(..) |
|
hir::ItemUnion(..) |
|
||||||
hir::ItemTrait(..) |
|
hir::ItemTrait(..) |
|
||||||
hir::ItemAutoImpl(..) |
|
|
||||||
hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span),
|
hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span),
|
||||||
_ => item.span,
|
_ => item.span,
|
||||||
};
|
};
|
||||||
|
|
|
@ -270,8 +270,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||||
hir::ItemMod(..) | hir::ItemForeignMod(..) |
|
hir::ItemMod(..) | hir::ItemForeignMod(..) |
|
||||||
hir::ItemImpl(..) | hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
|
hir::ItemImpl(..) | hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
|
||||||
hir::ItemStruct(..) | hir::ItemEnum(..) |
|
hir::ItemStruct(..) | hir::ItemEnum(..) |
|
||||||
hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
|
hir::ItemUnion(..) | hir::ItemGlobalAsm(..) => {}
|
||||||
hir::ItemGlobalAsm(..) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir_map::NodeTraitItem(trait_method) => {
|
hir_map::NodeTraitItem(trait_method) => {
|
||||||
|
|
|
@ -461,10 +461,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
intravisit::walk_item(this, item);
|
intravisit::walk_item(this, item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ItemExternCrate(_)
|
hir::ItemExternCrate(_)
|
||||||
| hir::ItemUse(..)
|
| hir::ItemUse(..)
|
||||||
| hir::ItemMod(..)
|
| hir::ItemMod(..)
|
||||||
| hir::ItemAutoImpl(..)
|
|
||||||
| hir::ItemForeignMod(..)
|
| hir::ItemForeignMod(..)
|
||||||
| hir::ItemGlobalAsm(..) => {
|
| hir::ItemGlobalAsm(..) => {
|
||||||
// These sorts of items have no lifetime parameters at all.
|
// These sorts of items have no lifetime parameters at all.
|
||||||
|
|
|
@ -2434,7 +2434,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
VtableBuiltinData { nested: obligations }
|
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:
|
/// 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
|
/// 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
|
* Creates a cause for obligations that are derived from
|
||||||
* `obligation` by a recursive search (e.g., for a builtin
|
* `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
|
* is itself a derived obligation, this is just a clone, but
|
||||||
* otherwise we create a "derived obligation" cause so as to
|
* otherwise we create a "derived obligation" cause so as to
|
||||||
* keep track of the original root obligation for error
|
* keep track of the original root obligation for error
|
||||||
|
|
|
@ -232,11 +232,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Always use types for non-local impls, where types are always
|
// Always use types for non-local impls, where types are always
|
||||||
// available, and filename/line-number is mostly uninteresting.
|
// 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.
|
// Otherwise, use filename/line-number if forced.
|
||||||
let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
|
let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
|
||||||
!force_no_types
|
!force_no_types
|
||||||
});
|
};
|
||||||
|
|
||||||
if !use_types {
|
if !use_types {
|
||||||
return self.push_impl_path_fallback(buffer, impl_def_id);
|
return self.push_impl_path_fallback(buffer, impl_def_id);
|
||||||
|
|
|
@ -112,9 +112,6 @@ define_maps! { <'tcx>
|
||||||
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
|
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
|
||||||
[] fn is_foreign_item: IsForeignItem(DefId) -> bool,
|
[] 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`
|
/// Get a map with the variance of every item; use `item_variance`
|
||||||
/// instead.
|
/// instead.
|
||||||
[] fn crate_variances: crate_variances(CrateNum) -> Rc<ty::CrateVariancesMap>,
|
[] fn crate_variances: crate_variances(CrateNum) -> Rc<ty::CrateVariancesMap>,
|
||||||
|
|
|
@ -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::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
|
||||||
DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
|
DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
|
||||||
DepKind::AdtDefOfItem => { force!(adt_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::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
|
||||||
DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
|
DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
|
||||||
DepKind::FnSignature => { force!(fn_sig, def_id!()); }
|
DepKind::FnSignature => { force!(fn_sig, def_id!()); }
|
||||||
|
|
|
@ -2405,8 +2405,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this is an `auto trait`.
|
/// 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 {
|
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
|
||||||
self.trait_def(trait_def_id).has_auto_impl
|
self.trait_def(trait_def_id).has_auto_impl
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,8 +246,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
||||||
hir::ItemUnion(..) |
|
hir::ItemUnion(..) |
|
||||||
hir::ItemTrait(..) |
|
hir::ItemTrait(..) |
|
||||||
hir::ItemTraitAlias(..) |
|
hir::ItemTraitAlias(..) |
|
||||||
hir::ItemImpl(..) |
|
hir::ItemImpl(..) => None,
|
||||||
hir::ItemAutoImpl(..) => None,
|
|
||||||
|
|
||||||
hir::ItemMod(ref m) => search_mod(this, m, idx, names),
|
hir::ItemMod(ref m) => search_mod(this, m, idx, names),
|
||||||
};
|
};
|
||||||
|
|
|
@ -393,9 +393,6 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
//HirItem::ItemTrait(..) => ("ItemTrait", LABELS_TRAIT),
|
//HirItem::ItemTrait(..) => ("ItemTrait", LABELS_TRAIT),
|
||||||
|
|
||||||
// `impl Trait for .. {}`
|
|
||||||
HirItem::ItemAutoImpl(..) => ("ItemAutoImpl", LABELS_IMPL),
|
|
||||||
|
|
||||||
// An implementation, eg `impl<A> Trait for Foo { .. }`
|
// An implementation, eg `impl<A> Trait for Foo { .. }`
|
||||||
HirItem::ItemImpl(..) => ("ItemImpl", LABELS_IMPL),
|
HirItem::ItemImpl(..) => ("ItemImpl", LABELS_IMPL),
|
||||||
|
|
||||||
|
|
|
@ -55,31 +55,6 @@ use bad_style::{MethodLateContext, method_context};
|
||||||
// hardwired lints from librustc
|
// hardwired lints from librustc
|
||||||
pub use lint::builtin::*;
|
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! {
|
declare_lint! {
|
||||||
WHILE_TRUE,
|
WHILE_TRUE,
|
||||||
Warn,
|
Warn,
|
||||||
|
|
|
@ -109,7 +109,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
AnonymousParameters,
|
AnonymousParameters,
|
||||||
IllegalFloatLiteralPattern,
|
IllegalFloatLiteralPattern,
|
||||||
UnusedDocComment,
|
UnusedDocComment,
|
||||||
AutoImpl,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
add_early_builtin_with_new!(sess,
|
add_early_builtin_with_new!(sess,
|
||||||
|
@ -183,10 +182,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
// - Eventually, remove lint
|
// - Eventually, remove lint
|
||||||
store.register_future_incompatible(sess,
|
store.register_future_incompatible(sess,
|
||||||
vec![
|
vec![
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(AUTO_IMPL),
|
|
||||||
reference: "issue #13231 <https://github.com/rust-lang/rust/issues/13231>",
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
FutureIncompatibleInfo {
|
||||||
id: LintId::of(PRIVATE_IN_PUBLIC),
|
id: LintId::of(PRIVATE_IN_PUBLIC),
|
||||||
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
||||||
|
|
|
@ -143,7 +143,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
||||||
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
|
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
|
||||||
is_const_fn => { cdata.is_const_fn(def_id.index) }
|
is_const_fn => { cdata.is_const_fn(def_id.index) }
|
||||||
is_foreign_item => { cdata.is_foreign_item(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) }
|
describe_def => { cdata.get_def(def_id.index) }
|
||||||
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
|
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
|
||||||
lookup_stability => {
|
lookup_stability => {
|
||||||
|
|
|
@ -404,7 +404,6 @@ impl<'tcx> EntryKind<'tcx> {
|
||||||
|
|
||||||
EntryKind::ForeignMod |
|
EntryKind::ForeignMod |
|
||||||
EntryKind::Impl(_) |
|
EntryKind::Impl(_) |
|
||||||
EntryKind::AutoImpl(_) |
|
|
||||||
EntryKind::Field |
|
EntryKind::Field |
|
||||||
EntryKind::Generator(_) |
|
EntryKind::Generator(_) |
|
||||||
EntryKind::Closure(_) => return None,
|
EntryKind::Closure(_) => return None,
|
||||||
|
@ -690,8 +689,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
EntryKind::Impl(_) |
|
EntryKind::Impl(_) => continue,
|
||||||
EntryKind::AutoImpl(_) => continue,
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1045,13 +1043,6 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
self.dllimport_foreign_items.contains(&id)
|
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,
|
pub fn fn_sig(&self,
|
||||||
id: DefIndex,
|
id: DefIndex,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||||
|
|
|
@ -974,17 +974,6 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||||
ctor_sig: None,
|
ctor_sig: None,
|
||||||
}), repr_options)
|
}), 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, ..) => {
|
hir::ItemImpl(_, polarity, defaultness, ..) => {
|
||||||
let trait_ref = tcx.impl_trait_ref(def_id);
|
let trait_ref = tcx.impl_trait_ref(def_id);
|
||||||
let parent = if let Some(trait_ref) = trait_ref {
|
let parent = if let Some(trait_ref) = trait_ref {
|
||||||
|
@ -1579,7 +1568,6 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||||
hir::ItemGlobalAsm(..) |
|
hir::ItemGlobalAsm(..) |
|
||||||
hir::ItemExternCrate(..) |
|
hir::ItemExternCrate(..) |
|
||||||
hir::ItemUse(..) |
|
hir::ItemUse(..) |
|
||||||
hir::ItemAutoImpl(..) |
|
|
||||||
hir::ItemTy(..) |
|
hir::ItemTy(..) |
|
||||||
hir::ItemTraitAlias(..) => {
|
hir::ItemTraitAlias(..) => {
|
||||||
// no sub-item recording needed in these cases
|
// no sub-item recording needed in these cases
|
||||||
|
|
|
@ -303,7 +303,6 @@ pub enum EntryKind<'tcx> {
|
||||||
Generator(Lazy<GeneratorData<'tcx>>),
|
Generator(Lazy<GeneratorData<'tcx>>),
|
||||||
Trait(Lazy<TraitData<'tcx>>),
|
Trait(Lazy<TraitData<'tcx>>),
|
||||||
Impl(Lazy<ImplData<'tcx>>),
|
Impl(Lazy<ImplData<'tcx>>),
|
||||||
AutoImpl(Lazy<ImplData<'tcx>>),
|
|
||||||
Method(Lazy<MethodData<'tcx>>),
|
Method(Lazy<MethodData<'tcx>>),
|
||||||
AssociatedType(AssociatedContainer),
|
AssociatedType(AssociatedContainer),
|
||||||
AssociatedConst(AssociatedContainer, u8),
|
AssociatedConst(AssociatedContainer, u8),
|
||||||
|
@ -359,7 +358,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for EntryKind<'gcx> {
|
||||||
EntryKind::Trait(ref trait_data) => {
|
EntryKind::Trait(ref trait_data) => {
|
||||||
trait_data.hash_stable(hcx, hasher);
|
trait_data.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
EntryKind::AutoImpl(ref impl_data) |
|
|
||||||
EntryKind::Impl(ref impl_data) => {
|
EntryKind::Impl(ref impl_data) => {
|
||||||
impl_data.hash_stable(hcx, hasher);
|
impl_data.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
|
|
|
@ -910,7 +910,6 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
||||||
hir::ItemUse(..) |
|
hir::ItemUse(..) |
|
||||||
hir::ItemForeignMod(..) |
|
hir::ItemForeignMod(..) |
|
||||||
hir::ItemTy(..) |
|
hir::ItemTy(..) |
|
||||||
hir::ItemAutoImpl(..) |
|
|
||||||
hir::ItemTrait(..) |
|
hir::ItemTrait(..) |
|
||||||
hir::ItemTraitAlias(..) |
|
hir::ItemTraitAlias(..) |
|
||||||
hir::ItemMod(..) => {
|
hir::ItemMod(..) => {
|
||||||
|
|
|
@ -229,9 +229,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
item.span,
|
item.span,
|
||||||
Some("place qualifiers on individual impl items instead"));
|
Some("place qualifiers on individual impl items instead"));
|
||||||
}
|
}
|
||||||
ItemKind::AutoImpl(..) => {
|
|
||||||
self.invalid_visibility(&item.vis, item.span, None);
|
|
||||||
}
|
|
||||||
ItemKind::ForeignMod(..) => {
|
ItemKind::ForeignMod(..) => {
|
||||||
self.invalid_visibility(&item.vis,
|
self.invalid_visibility(&item.vis,
|
||||||
item.span,
|
item.span,
|
||||||
|
|
|
@ -147,10 +147,6 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
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))
|
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
|
// Foreign mods inherit level from parents
|
||||||
hir::ItemForeignMod(..) => {
|
hir::ItemForeignMod(..) => {
|
||||||
self.prev_level
|
self.prev_level
|
||||||
|
@ -214,7 +210,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
|
hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
|
||||||
hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) | hir::ItemTraitAlias(..) |
|
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
|
// 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
|
// Reexports are handled in visit_mod
|
||||||
hir::ItemUse(..) => {}
|
hir::ItemUse(..) => {}
|
||||||
// The interface is empty
|
// The interface is empty
|
||||||
hir::ItemAutoImpl(..) => {}
|
|
||||||
// The interface is empty
|
|
||||||
hir::ItemGlobalAsm(..) => {}
|
hir::ItemGlobalAsm(..) => {}
|
||||||
// Visit everything
|
// Visit everything
|
||||||
hir::ItemConst(..) | hir::ItemStatic(..) |
|
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();
|
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
|
// An inherent impl is public when its type is public
|
||||||
// Subitems of inherent impls have their own publicity
|
// Subitems of inherent impls have their own publicity
|
||||||
hir::ItemImpl(.., None, _, ref impl_item_refs) => {
|
hir::ItemImpl(.., None, _, ref impl_item_refs) => {
|
||||||
|
|
|
@ -400,7 +400,7 @@ impl<'a> Resolver<'a> {
|
||||||
self.insert_field_names(item_def_id, field_names);
|
self.insert_field_names(item_def_id, field_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKind::AutoImpl(..) | ItemKind::Impl(..) => {}
|
ItemKind::Impl(..) => {}
|
||||||
|
|
||||||
ItemKind::Trait(..) => {
|
ItemKind::Trait(..) => {
|
||||||
let def_id = self.definitions.local_def_id(item.id);
|
let def_id = self.definitions.local_def_id(item.id);
|
||||||
|
|
|
@ -1902,12 +1902,6 @@ impl<'a> Resolver<'a> {
|
||||||
|this| visit::walk_item(this, item));
|
|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) =>
|
ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
|
||||||
self.resolve_implementation(generics,
|
self.resolve_implementation(generics,
|
||||||
opt_trait_ref,
|
opt_trait_ref,
|
||||||
|
|
|
@ -511,17 +511,6 @@ impl Sig for ast::Item {
|
||||||
|
|
||||||
Ok(sig)
|
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(
|
ast::ItemKind::Impl(
|
||||||
unsafety,
|
unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
|
|
|
@ -131,7 +131,6 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||||
|
|
||||||
unsafety::check(tcx);
|
unsafety::check(tcx);
|
||||||
orphan::check(tcx);
|
orphan::check(tcx);
|
||||||
overlap::check_auto_impls(tcx);
|
|
||||||
|
|
||||||
// these queries are executed for side-effects (error reporting):
|
// these queries are executed for side-effects (error reporting):
|
||||||
ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
|
ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
|
||||||
|
|
|
@ -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
|
// Not an impl
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,6 @@
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||||
use syntax::ast;
|
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) {
|
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 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) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -84,9 +84,6 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
|
||||||
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
|
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &'v hir::Item) {
|
fn visit_item(&mut self, item: &'v hir::Item) {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ItemAutoImpl(unsafety, _) => {
|
|
||||||
self.check_unsafety_coherence(item, None, unsafety, hir::ImplPolarity::Positive);
|
|
||||||
}
|
|
||||||
hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => {
|
hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => {
|
||||||
self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
|
self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ pub fn provide(providers: &mut Providers) {
|
||||||
impl_trait_ref,
|
impl_trait_ref,
|
||||||
impl_polarity,
|
impl_polarity,
|
||||||
is_foreign_item,
|
is_foreign_item,
|
||||||
is_auto_impl,
|
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -424,9 +423,6 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
|
||||||
tcx.predicates_of(def_id);
|
tcx.predicates_of(def_id);
|
||||||
convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
|
convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
|
||||||
},
|
},
|
||||||
hir::ItemAutoImpl(..) => {
|
|
||||||
tcx.impl_trait_ref(def_id);
|
|
||||||
}
|
|
||||||
hir::ItemImpl(..) => {
|
hir::ItemImpl(..) => {
|
||||||
tcx.generics_of(def_id);
|
tcx.generics_of(def_id);
|
||||||
tcx.type_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);
|
let substs = Substs::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_adt(def, substs)
|
tcx.mk_adt(def, substs)
|
||||||
}
|
}
|
||||||
ItemAutoImpl(..) |
|
|
||||||
ItemTrait(..) | ItemTraitAlias(..) |
|
ItemTrait(..) | ItemTraitAlias(..) |
|
||||||
ItemMod(..) |
|
ItemMod(..) |
|
||||||
ItemForeignMod(..) |
|
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();
|
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
match tcx.hir.expect_item(node_id).node {
|
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, _, _) => {
|
hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
|
||||||
opt_trait_ref.as_ref().map(|ast_trait_ref| {
|
opt_trait_ref.as_ref().map(|ast_trait_ref| {
|
||||||
let selfty = tcx.type_of(def_id);
|
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>,
|
struct ImplTraitUniversalInfo<'hir> {
|
||||||
def_id: DefId)
|
id: ast::NodeId,
|
||||||
-> bool {
|
def_id: DefId,
|
||||||
match tcx.hir.get_if_local(def_id) {
|
span: Span,
|
||||||
Some(hir_map::NodeItem(&hir::Item { node: hir::ItemAutoImpl(..), .. }))
|
bounds: &'hir [hir::TyParamBound],
|
||||||
=> true,
|
}
|
||||||
Some(_) => false,
|
|
||||||
_ => bug!("is_auto_impl applied to non-local def-id {:?}", def_id)
|
/// 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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1854,14 +1854,12 @@ unsafe impl !Clone for Foo { }
|
||||||
|
|
||||||
This will compile:
|
This will compile:
|
||||||
|
|
||||||
```ignore (ignore auto_trait future compatibility warning)
|
```
|
||||||
#![feature(optin_builtin_traits)]
|
#![feature(optin_builtin_traits)]
|
||||||
|
|
||||||
struct Foo;
|
struct Foo;
|
||||||
|
|
||||||
trait Enterprise {}
|
auto trait Enterprise {}
|
||||||
|
|
||||||
impl Enterprise for .. { }
|
|
||||||
|
|
||||||
impl !Enterprise for Foo { }
|
impl !Enterprise for Foo { }
|
||||||
```
|
```
|
||||||
|
|
|
@ -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);
|
let for_ = tcx.type_of(did).clean(cx);
|
||||||
|
|
||||||
// Only inline impl if the implementing type is
|
// Only inline impl if the implementing type is
|
||||||
|
|
|
@ -430,7 +430,6 @@ pub enum ItemEnum {
|
||||||
PrimitiveItem(PrimitiveType),
|
PrimitiveItem(PrimitiveType),
|
||||||
AssociatedConstItem(Type, Option<String>),
|
AssociatedConstItem(Type, Option<String>),
|
||||||
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
||||||
AutoImplItem(AutoImpl),
|
|
||||||
/// An item that has been stripped by a rustdoc pass
|
/// An item that has been stripped by a rustdoc pass
|
||||||
StrippedItem(Box<ItemEnum>),
|
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 {
|
impl Clean<Item> for doctree::ExternCrate {
|
||||||
fn clean(&self, cx: &DocContext) -> Item {
|
fn clean(&self, cx: &DocContext) -> Item {
|
||||||
Item {
|
Item {
|
||||||
|
|
|
@ -44,7 +44,6 @@ pub struct Module {
|
||||||
pub stab: Option<attr::Stability>,
|
pub stab: Option<attr::Stability>,
|
||||||
pub depr: Option<attr::Deprecation>,
|
pub depr: Option<attr::Deprecation>,
|
||||||
pub impls: Vec<Impl>,
|
pub impls: Vec<Impl>,
|
||||||
pub def_traits: Vec<AutoImpl>,
|
|
||||||
pub foreigns: Vec<hir::ForeignMod>,
|
pub foreigns: Vec<hir::ForeignMod>,
|
||||||
pub macros: Vec<Macro>,
|
pub macros: Vec<Macro>,
|
||||||
pub is_crate: bool,
|
pub is_crate: bool,
|
||||||
|
@ -227,14 +226,6 @@ pub struct Impl {
|
||||||
pub id: ast::NodeId,
|
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
|
// 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).
|
// these imported macro_rules (which only have a DUMMY_NODE_ID).
|
||||||
pub struct Macro {
|
pub struct Macro {
|
||||||
|
|
|
@ -82,7 +82,6 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
||||||
clean::PrimitiveItem(..) => ItemType::Primitive,
|
clean::PrimitiveItem(..) => ItemType::Primitive,
|
||||||
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
|
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
|
||||||
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
|
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
|
||||||
clean::AutoImplItem(..) => ItemType::Impl,
|
|
||||||
clean::ForeignTypeItem => ItemType::ForeignType,
|
clean::ForeignTypeItem => ItemType::ForeignType,
|
||||||
clean::StrippedItem(..) => unreachable!(),
|
clean::StrippedItem(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1964,12 +1964,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
|
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
|
||||||
document(w, cx, item)?;
|
document(w, cx, item)?;
|
||||||
|
|
||||||
let mut indices = (0..items.len()).filter(|i| {
|
let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped())
|
||||||
if let clean::AutoImplItem(..) = items[*i].inner {
|
.collect::<Vec<usize>>();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
!items[*i].is_stripped()
|
|
||||||
}).collect::<Vec<usize>>();
|
|
||||||
|
|
||||||
// the order of item types in the listing
|
// the order of item types in the listing
|
||||||
fn reorder(ty: ItemType) -> u8 {
|
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::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl,
|
||||||
ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
|
ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
|
||||||
ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
|
ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
|
||||||
if items.iter().any(|it| {
|
if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
|
||||||
if let clean::AutoImplItem(..) = it.inner {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
!it.is_stripped() && it.type_() == myty
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
let (short, name) = match myty {
|
let (short, name) = match myty {
|
||||||
ItemType::ExternCrate |
|
ItemType::ExternCrate |
|
||||||
ItemType::Import => ("reexports", "Reexports"),
|
ItemType::Import => ("reexports", "Reexports"),
|
||||||
|
|
|
@ -116,7 +116,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
||||||
// handled in the `strip-priv-imports` pass
|
// handled in the `strip-priv-imports` pass
|
||||||
clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
|
clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
|
||||||
|
|
||||||
clean::AutoImplItem(..) | clean::ImplItem(..) => {}
|
clean::ImplItem(..) => {}
|
||||||
|
|
||||||
// tymethods/macros have no control over privacy
|
// tymethods/macros have no control over privacy
|
||||||
clean::MacroItem(..) | clean::TyMethodItem(..) => {}
|
clean::MacroItem(..) | clean::TyMethodItem(..) => {}
|
||||||
|
|
|
@ -548,19 +548,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
om.impls.push(i);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,10 +187,7 @@ pub struct AssertUnwindSafe<T>(
|
||||||
// * Unique, an owning pointer, lifts an implementation
|
// * Unique, an owning pointer, lifts an implementation
|
||||||
// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
|
// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
|
||||||
// * Our custom AssertUnwindSafe wrapper is indeed 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")]
|
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||||
impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
|
impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[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> {}
|
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
|
||||||
|
|
||||||
// Pretty simple implementations for the `RefUnwindSafe` marker trait,
|
// 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
|
// only thing which doesn't implement it (which then transitively applies to
|
||||||
// everything else).
|
// everything else).
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[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> {}
|
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||||
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
|
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
|
||||||
|
|
|
@ -2022,10 +2022,6 @@ pub enum ItemKind {
|
||||||
///
|
///
|
||||||
/// E.g. `trait Foo = Bar + Quux;`
|
/// E.g. `trait Foo = Bar + Quux;`
|
||||||
TraitAlias(Generics, TyParamBounds),
|
TraitAlias(Generics, TyParamBounds),
|
||||||
/// Auto trait implementation.
|
|
||||||
///
|
|
||||||
/// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
|
|
||||||
AutoImpl(Unsafety, TraitRef),
|
|
||||||
/// An implementation.
|
/// An implementation.
|
||||||
///
|
///
|
||||||
/// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
|
/// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
|
||||||
|
@ -2064,8 +2060,7 @@ impl ItemKind {
|
||||||
ItemKind::TraitAlias(..) => "trait alias",
|
ItemKind::TraitAlias(..) => "trait alias",
|
||||||
ItemKind::Mac(..) |
|
ItemKind::Mac(..) |
|
||||||
ItemKind::MacroDef(..) |
|
ItemKind::MacroDef(..) |
|
||||||
ItemKind::Impl(..) |
|
ItemKind::Impl(..) => "item"
|
||||||
ItemKind::AutoImpl(..) => "item"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1540,13 +1540,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
"trait aliases are not yet fully implemented");
|
"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) => {
|
ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => {
|
||||||
if polarity == ast::ImplPolarity::Negative {
|
if polarity == ast::ImplPolarity::Negative {
|
||||||
gate_feature_post!(&self, optin_builtin_traits,
|
gate_feature_post!(&self, optin_builtin_traits,
|
||||||
|
|
|
@ -911,9 +911,6 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
|
||||||
let generics = folder.fold_generics(generics);
|
let generics = folder.fold_generics(generics);
|
||||||
ItemKind::Union(folder.fold_variant_data(struct_def), 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,
|
ItemKind::Impl(unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
defaultness,
|
defaultness,
|
||||||
|
|
|
@ -5374,11 +5374,9 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses items implementations variants
|
/// Parses items implementations variants
|
||||||
/// impl<T> Foo { ... }
|
/// impl<T> Foo { ... }
|
||||||
/// impl<T> ToString for &'static T { ... }
|
/// impl<T> ToString for &'static T { ... }
|
||||||
/// impl Send for .. {}
|
|
||||||
fn parse_item_impl(&mut self,
|
fn parse_item_impl(&mut self,
|
||||||
unsafety: ast::Unsafety,
|
unsafety: ast::Unsafety,
|
||||||
defaultness: Defaultness) -> PResult<'a, ItemInfo> {
|
defaultness: Defaultness) -> PResult<'a, ItemInfo> {
|
||||||
let impl_span = self.span;
|
|
||||||
|
|
||||||
// First, parse type parameters if necessary.
|
// First, parse type parameters if necessary.
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
|
@ -5421,48 +5419,31 @@ impl<'a> Parser<'a> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if opt_trait.is_some() && self.eat(&token::DotDot) {
|
if opt_trait.is_some() {
|
||||||
if generics.is_parameterized() {
|
ty = self.parse_ty()?;
|
||||||
self.span_err(impl_span, "auto trait implementations are not \
|
}
|
||||||
allowed to have generics");
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
}
|
|
||||||
|
|
||||||
if let ast::Defaultness::Default = defaultness {
|
self.expect(&token::OpenDelim(token::Brace))?;
|
||||||
self.span_err(impl_span, "`default impl` is not allowed for \
|
let attrs = self.parse_inner_attributes()?;
|
||||||
auto trait implementations");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.expect(&token::OpenDelim(token::Brace))?;
|
let mut impl_items = vec![];
|
||||||
self.expect(&token::CloseDelim(token::Brace))?;
|
while !self.eat(&token::CloseDelim(token::Brace)) {
|
||||||
Ok((keywords::Invalid.ident(),
|
let mut at_end = false;
|
||||||
ItemKind::AutoImpl(unsafety, opt_trait.unwrap()), None))
|
match self.parse_impl_item(&mut at_end) {
|
||||||
} else {
|
Ok(item) => impl_items.push(item),
|
||||||
if opt_trait.is_some() {
|
Err(mut e) => {
|
||||||
ty = self.parse_ty()?;
|
e.emit();
|
||||||
}
|
if !at_end {
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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>> {
|
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
|
||||||
|
|
|
@ -1294,18 +1294,6 @@ impl<'a> State<'a> {
|
||||||
self.head(&visibility_qualified(&item.vis, "union"))?;
|
self.head(&visibility_qualified(&item.vis, "union"))?;
|
||||||
self.print_struct(struct_def, generics, item.ident, item.span, true)?;
|
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,
|
ast::ItemKind::Impl(unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
defaultness,
|
defaultness,
|
||||||
|
|
|
@ -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_generics(type_parameters);
|
||||||
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
|
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(_, _, _,
|
ItemKind::Impl(_, _, _,
|
||||||
ref type_parameters,
|
ref type_parameters,
|
||||||
ref opt_trait_reference,
|
ref opt_trait_reference,
|
||||||
|
|
|
@ -30,17 +30,11 @@
|
||||||
#[lang = "sized"]
|
#[lang = "sized"]
|
||||||
trait Sized {}
|
trait Sized {}
|
||||||
#[lang = "sync"]
|
#[lang = "sync"]
|
||||||
trait Sync {}
|
auto trait Sync {}
|
||||||
#[allow(unknown_lints)]
|
|
||||||
#[allow(auto_impl)]
|
|
||||||
impl Sync for .. {}
|
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
trait Copy {}
|
trait Copy {}
|
||||||
#[lang = "freeze"]
|
#[lang = "freeze"]
|
||||||
trait Freeze {}
|
auto trait Freeze {}
|
||||||
#[allow(unknown_lints)]
|
|
||||||
#[allow(auto_impl)]
|
|
||||||
impl Freeze for .. {}
|
|
||||||
|
|
||||||
#[lang = "drop_in_place"]
|
#[lang = "drop_in_place"]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -22,10 +22,7 @@ impl<T> Sync for T {}
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
trait Copy {}
|
trait Copy {}
|
||||||
#[lang = "freeze"]
|
#[lang = "freeze"]
|
||||||
trait Freeze {}
|
auto trait Freeze {}
|
||||||
#[allow(unknown_lints)]
|
|
||||||
#[allow(auto_impl)]
|
|
||||||
impl Freeze for .. {}
|
|
||||||
|
|
||||||
#[lang = "drop_in_place"]
|
#[lang = "drop_in_place"]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -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() {}
|
|
Loading…
Add table
Add a link
Reference in a new issue