Auto merge of #47416 - petrochenkov:remove-impl-for-dot-dot, r=petrochenkov
Remove `impl Foo for .. {}` in favor `auto trait Foo {}` Rebase of https://github.com/rust-lang/rust/pull/46480 with restored parsing support.
This commit is contained in:
commit
cf4c3cbe55
@ -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> {}
|
||||
|
@ -496,7 +496,6 @@ define_dep_nodes!( <'tcx>
|
||||
[] SuperPredicatesOfItem(DefId),
|
||||
[] TraitDefOfItem(DefId),
|
||||
[] AdtDefOfItem(DefId),
|
||||
[] IsAutoImpl(DefId),
|
||||
[] ImplTraitRef(DefId),
|
||||
[] ImplPolarity(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
|
||||
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);
|
||||
|
@ -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,
|
||||
|
@ -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(..) =>
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
});
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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) => {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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>,
|
||||
|
@ -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!()); }
|
||||
|
@ -2400,8 +2400,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Returns true if this is an `auto trait`.
|
||||
///
|
||||
/// NB. For a limited time, also returns true if `impl Trait for .. { }` is in the code-base.
|
||||
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
|
||||
self.trait_def(trait_def_id).has_auto_impl
|
||||
}
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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>",
|
||||
|
@ -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 => {
|
||||
|
@ -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>)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(..) => {
|
||||
|
@ -215,8 +215,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
fn visit_item(&mut self, item: &'a Item) {
|
||||
match item.node {
|
||||
ItemKind::Impl(.., Some(..), _, ref impl_items) => {
|
||||
ItemKind::Impl(.., Some(..), ref ty, ref impl_items) => {
|
||||
self.invalid_visibility(&item.vis, item.span, None);
|
||||
if ty.node == TyKind::Err {
|
||||
self.err_handler()
|
||||
.struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax")
|
||||
.help("use `auto trait Trait {}` instead").emit();
|
||||
}
|
||||
for impl_item in impl_items {
|
||||
self.invalid_visibility(&impl_item.vis, impl_item.span, None);
|
||||
if let ImplItemKind::Method(ref sig, _) = impl_item.node {
|
||||
@ -229,9 +234,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
item.span,
|
||||
Some("place qualifiers on individual impl items instead"));
|
||||
}
|
||||
ItemKind::AutoImpl(..) => {
|
||||
self.invalid_visibility(&item.vis, item.span, None);
|
||||
}
|
||||
ItemKind::ForeignMod(..) => {
|
||||
self.invalid_visibility(&item.vis,
|
||||
item.span,
|
||||
@ -250,16 +252,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
if is_auto == IsAuto::Yes {
|
||||
// Auto traits cannot have generics, super traits nor contain items.
|
||||
if generics.is_parameterized() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"auto traits cannot have generics");
|
||||
struct_span_err!(self.session, item.span, E0567,
|
||||
"auto traits cannot have generic parameters").emit();
|
||||
}
|
||||
if !bounds.is_empty() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"auto traits cannot have super traits");
|
||||
struct_span_err!(self.session, item.span, E0568,
|
||||
"auto traits cannot have super traits").emit();
|
||||
}
|
||||
if !trait_items.is_empty() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"auto traits cannot contain items");
|
||||
struct_span_err!(self.session, item.span, E0380,
|
||||
"auto traits cannot have methods or associated items").emit();
|
||||
}
|
||||
}
|
||||
self.no_questions_in_bounds(bounds, "supertraits", true);
|
||||
|
@ -150,6 +150,13 @@ Trait methods cannot be declared `const` by design. For more information, see
|
||||
[RFC 911]: https://github.com/rust-lang/rfcs/pull/911
|
||||
"##,
|
||||
|
||||
E0380: r##"
|
||||
Auto traits cannot have methods or associated items.
|
||||
For more information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
||||
"##,
|
||||
|
||||
E0449: r##"
|
||||
A visibility qualifier was used when it was unnecessary. Erroneous code
|
||||
examples:
|
||||
@ -264,5 +271,7 @@ register_diagnostics! {
|
||||
E0226, // only a single explicit lifetime bound is permitted
|
||||
E0472, // asm! is unsupported on this target
|
||||
E0561, // patterns aren't allowed in function pointer types
|
||||
E0567, // auto traits can not have generic parameters
|
||||
E0568, // auto traits can not have super traits
|
||||
E0642, // patterns aren't allowed in methods without bodies
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -275,74 +275,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
});
|
||||
}
|
||||
|
||||
fn check_auto_trait(&mut self, trait_def_id: DefId, span: Span) {
|
||||
// We want to ensure:
|
||||
//
|
||||
// 1) that there are no items contained within
|
||||
// the trait definition
|
||||
//
|
||||
// 2) that the definition doesn't violate the no-super trait rule
|
||||
// for auto traits.
|
||||
//
|
||||
// 3) that the trait definition does not have any type parameters
|
||||
|
||||
let predicates = self.tcx.predicates_of(trait_def_id);
|
||||
|
||||
// We must exclude the Self : Trait predicate contained by all
|
||||
// traits.
|
||||
let has_predicates =
|
||||
predicates.predicates.iter().any(|predicate| {
|
||||
match predicate {
|
||||
&ty::Predicate::Trait(ref poly_trait_ref) => {
|
||||
let self_ty = poly_trait_ref.0.self_ty();
|
||||
!(self_ty.is_self() && poly_trait_ref.def_id() == trait_def_id)
|
||||
},
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
|
||||
let has_ty_params = self.tcx.generics_of(trait_def_id).types.len() > 1;
|
||||
|
||||
// We use an if-else here, since the generics will also trigger
|
||||
// an extraneous error message when we find predicates like
|
||||
// `T : Sized` for a trait like: `trait Magic<T>`.
|
||||
//
|
||||
// We also put the check on the number of items here,
|
||||
// as it seems confusing to report an error about
|
||||
// extraneous predicates created by things like
|
||||
// an associated type inside the trait.
|
||||
let mut err = None;
|
||||
if !self.tcx.associated_item_def_ids(trait_def_id).is_empty() {
|
||||
error_380(self.tcx, span);
|
||||
} else if has_ty_params {
|
||||
err = Some(struct_span_err!(self.tcx.sess, span, E0567,
|
||||
"traits with auto impls (`e.g. impl \
|
||||
Trait for ..`) can not have type parameters"));
|
||||
} else if has_predicates {
|
||||
err = Some(struct_span_err!(self.tcx.sess, span, E0568,
|
||||
"traits with auto impls (`e.g. impl \
|
||||
Trait for ..`) cannot have predicates"));
|
||||
}
|
||||
|
||||
// Finally if either of the above conditions apply we should add a note
|
||||
// indicating that this error is the result of a recent soundness fix.
|
||||
match err {
|
||||
None => {},
|
||||
Some(mut e) => {
|
||||
e.note("the new auto trait rules are the result of a \
|
||||
recent soundness fix; see #29859 for more details");
|
||||
e.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait(&mut self, item: &hir::Item) {
|
||||
let trait_def_id = self.tcx.hir.local_def_id(item.id);
|
||||
|
||||
if self.tcx.trait_is_auto(trait_def_id) {
|
||||
self.check_auto_trait(trait_def_id, item.span);
|
||||
}
|
||||
|
||||
self.for_item(item).with_fcx(|fcx, this| {
|
||||
let predicates = fcx.tcx.predicates_of(trait_def_id).instantiate_identity(fcx.tcx);
|
||||
let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
|
||||
@ -733,12 +667,6 @@ fn error_192(tcx: TyCtxt, span: Span) {
|
||||
default impls (e.g., `Send` and `Sync`)")
|
||||
}
|
||||
|
||||
fn error_380(tcx: TyCtxt, span: Span) {
|
||||
span_err!(tcx.sess, span, E0380,
|
||||
"traits with default impls (`e.g. impl \
|
||||
Trait for ..`) must have no methods or associated items")
|
||||
}
|
||||
|
||||
fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name)
|
||||
-> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(tcx.sess, span, E0392,
|
||||
|
@ -16,6 +16,7 @@
|
||||
// mappings. That mapping code resides here.
|
||||
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::maps::Providers;
|
||||
|
||||
@ -25,7 +26,6 @@ mod builtin;
|
||||
mod inherent_impls;
|
||||
mod inherent_impls_overlap;
|
||||
mod orphan;
|
||||
mod overlap;
|
||||
mod unsafety;
|
||||
|
||||
fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
|
||||
@ -119,7 +119,7 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
|
||||
check_impl(tcx, impl_id);
|
||||
}
|
||||
for &impl_id in impls {
|
||||
overlap::check_impl(tcx, impl_id);
|
||||
check_impl_overlap(tcx, impl_id);
|
||||
}
|
||||
builtin::check_trait(tcx, def_id);
|
||||
}
|
||||
@ -131,9 +131,51 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
|
||||
unsafety::check(tcx);
|
||||
orphan::check(tcx);
|
||||
overlap::check_auto_impls(tcx);
|
||||
|
||||
// these queries are executed for side-effects (error reporting):
|
||||
ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
|
||||
ty::maps::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
|
||||
}
|
||||
|
||||
/// Overlap: No two impls for the same trait are implemented for the
|
||||
/// same type. Likewise, no two inherent impls for a given type
|
||||
/// constructor provide a method with the same name.
|
||||
fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
|
||||
let impl_def_id = tcx.hir.local_def_id(node_id);
|
||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
|
||||
if trait_ref.references_error() {
|
||||
debug!("coherence: skipping impl {:?} with error {:?}",
|
||||
impl_def_id, trait_ref);
|
||||
return
|
||||
}
|
||||
|
||||
// Trigger building the specialization graph for the trait of this impl.
|
||||
// This will detect any overlap errors.
|
||||
tcx.specialization_graph_of(trait_def_id);
|
||||
|
||||
// check for overlap with the automatic `impl Trait for Trait`
|
||||
if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
|
||||
// This is something like impl Trait1 for Trait2. Illegal
|
||||
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
|
||||
|
||||
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
|
||||
// This is an error, but it will be reported by wfcheck. Ignore it here.
|
||||
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
|
||||
} else {
|
||||
let mut supertrait_def_ids =
|
||||
traits::supertrait_def_ids(tcx,
|
||||
data.principal().unwrap().def_id());
|
||||
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
||||
span_err!(tcx.sess,
|
||||
tcx.span_of_impl(impl_def_id).unwrap(),
|
||||
E0371,
|
||||
"the object type `{}` automatically \
|
||||
implements the trait `{}`",
|
||||
trait_ref.self_ty(),
|
||||
tcx.item_path_str(trait_def_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,110 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Overlap: No two impls for the same trait are implemented for the
|
||||
//! same type. Likewise, no two inherent impls for a given type
|
||||
//! constructor provide a method with the same name.
|
||||
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||
use syntax::ast;
|
||||
use rustc::hir;
|
||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
|
||||
pub fn check_auto_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
let mut overlap = OverlapChecker { tcx };
|
||||
|
||||
// this secondary walk specifically checks for some other cases,
|
||||
// like defaulted traits, for which additional overlap rules exist
|
||||
tcx.hir.krate().visit_all_item_likes(&mut overlap);
|
||||
}
|
||||
|
||||
pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
|
||||
let impl_def_id = tcx.hir.local_def_id(node_id);
|
||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
|
||||
if trait_ref.references_error() {
|
||||
debug!("coherence: skipping impl {:?} with error {:?}",
|
||||
impl_def_id, trait_ref);
|
||||
return
|
||||
}
|
||||
|
||||
// Trigger building the specialization graph for the trait of this impl.
|
||||
// This will detect any overlap errors.
|
||||
tcx.specialization_graph_of(trait_def_id);
|
||||
|
||||
|
||||
// check for overlap with the automatic `impl Trait for Trait`
|
||||
if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
|
||||
// This is something like impl Trait1 for Trait2. Illegal
|
||||
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
|
||||
|
||||
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
|
||||
// This is an error, but it will be reported by wfcheck. Ignore it here.
|
||||
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
|
||||
} else {
|
||||
let mut supertrait_def_ids =
|
||||
traits::supertrait_def_ids(tcx,
|
||||
data.principal().unwrap().def_id());
|
||||
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
||||
span_err!(tcx.sess,
|
||||
tcx.span_of_impl(impl_def_id).unwrap(),
|
||||
E0371,
|
||||
"the object type `{}` automatically \
|
||||
implements the trait `{}`",
|
||||
trait_ref.self_ty(),
|
||||
tcx.item_path_str(trait_def_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct OverlapChecker<'cx, 'tcx: 'cx> {
|
||||
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
|
||||
fn visit_item(&mut self, item: &'v hir::Item) {
|
||||
match item.node {
|
||||
hir::ItemAutoImpl(..) => {
|
||||
// look for another auto impl; note that due to the
|
||||
// general orphan/coherence rules, it must always be
|
||||
// in this crate.
|
||||
let impl_def_id = self.tcx.hir.local_def_id(item.id);
|
||||
let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
|
||||
let prev_id = self.tcx.hir.trait_auto_impl(trait_ref.def_id).unwrap();
|
||||
if prev_id != item.id {
|
||||
let mut err = struct_span_err!(self.tcx.sess,
|
||||
self.tcx.span_of_impl(impl_def_id).unwrap(),
|
||||
E0521,
|
||||
"redundant auto implementations of trait \
|
||||
`{}`:",
|
||||
trait_ref);
|
||||
err.span_note(self.tcx
|
||||
.span_of_impl(self.tcx.hir.local_def_id(prev_id))
|
||||
.unwrap(),
|
||||
"redundant implementation is here:");
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
hir::ItemImpl(.., Some(_), _, _) => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -73,7 +73,6 @@ pub fn provide(providers: &mut Providers) {
|
||||
impl_trait_ref,
|
||||
impl_polarity,
|
||||
is_foreign_item,
|
||||
is_auto_impl,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
@ -424,9 +423,6 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
|
||||
tcx.predicates_of(def_id);
|
||||
convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
|
||||
},
|
||||
hir::ItemAutoImpl(..) => {
|
||||
tcx.impl_trait_ref(def_id);
|
||||
}
|
||||
hir::ItemImpl(..) => {
|
||||
tcx.generics_of(def_id);
|
||||
tcx.type_of(def_id);
|
||||
@ -716,9 +712,9 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let item = tcx.hir.expect_item(node_id);
|
||||
|
||||
let unsafety = match item.node {
|
||||
hir::ItemTrait(_, unsafety, ..) => unsafety,
|
||||
hir::ItemTraitAlias(..) => hir::Unsafety::Normal,
|
||||
let (is_auto, unsafety) = match item.node {
|
||||
hir::ItemTrait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
|
||||
hir::ItemTraitAlias(..) => (false, hir::Unsafety::Normal),
|
||||
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
|
||||
};
|
||||
|
||||
@ -735,10 +731,6 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
let def_path_hash = tcx.def_path_hash(def_id);
|
||||
let is_auto = match item.node {
|
||||
hir::ItemTrait(hir::IsAuto::Yes, ..) => true,
|
||||
_ => tcx.hir.trait_is_auto(def_id),
|
||||
};
|
||||
let def = ty::TraitDef::new(def_id,
|
||||
unsafety,
|
||||
paren_sugar,
|
||||
@ -1109,7 +1101,6 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let substs = Substs::identity_for_item(tcx, def_id);
|
||||
tcx.mk_adt(def, substs)
|
||||
}
|
||||
ItemAutoImpl(..) |
|
||||
ItemTrait(..) | ItemTraitAlias(..) |
|
||||
ItemMod(..) |
|
||||
ItemForeignMod(..) |
|
||||
@ -1278,11 +1269,6 @@ fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
match tcx.hir.expect_item(node_id).node {
|
||||
hir::ItemAutoImpl(_, ref ast_trait_ref) => {
|
||||
Some(AstConv::instantiate_mono_trait_ref(&icx,
|
||||
ast_trait_ref,
|
||||
tcx.mk_self_type()))
|
||||
}
|
||||
hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
|
||||
opt_trait_ref.as_ref().map(|ast_trait_ref| {
|
||||
let selfty = tcx.type_of(def_id);
|
||||
@ -1728,14 +1714,3 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_auto_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> bool {
|
||||
match tcx.hir.get_if_local(def_id) {
|
||||
Some(hir_map::NodeItem(&hir::Item { node: hir::ItemAutoImpl(..), .. }))
|
||||
=> true,
|
||||
Some(_) => false,
|
||||
_ => bug!("is_auto_impl applied to non-local def-id {:?}", def_id)
|
||||
}
|
||||
}
|
||||
|
@ -1854,14 +1854,12 @@ unsafe impl !Clone for Foo { }
|
||||
|
||||
This will compile:
|
||||
|
||||
```ignore (ignore auto_trait future compatibility warning)
|
||||
```
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
trait Enterprise {}
|
||||
|
||||
impl Enterprise for .. { }
|
||||
auto trait Enterprise {}
|
||||
|
||||
impl !Enterprise for Foo { }
|
||||
```
|
||||
@ -2533,13 +2531,6 @@ struct Bar<S, T> { x: Foo<S, T> }
|
||||
```
|
||||
"##,
|
||||
|
||||
E0318: r##"
|
||||
Default impls for a trait must be located in the same crate where the trait was
|
||||
defined. For more information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
||||
"##,
|
||||
|
||||
E0321: r##"
|
||||
A cross-crate opt-out trait was implemented on something which wasn't a struct
|
||||
or enum type. Erroneous code example:
|
||||
@ -3172,13 +3163,6 @@ containing the unsized type is the last and only unsized type field in the
|
||||
struct.
|
||||
"##,
|
||||
|
||||
E0380: r##"
|
||||
Default impls are only allowed for traits with no methods or associated items.
|
||||
For more information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
||||
"##,
|
||||
|
||||
E0390: r##"
|
||||
You tried to implement methods for a primitive type. Erroneous code example:
|
||||
|
||||
@ -4731,13 +4715,10 @@ register_diagnostics! {
|
||||
// E0372, // coherence not object safe
|
||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
// between structures with the same definition
|
||||
E0521, // redundant auto implementations of trait
|
||||
E0533, // `{}` does not name a unit variant, unit struct or a constant
|
||||
// E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
|
||||
E0564, // only named lifetimes are allowed in `impl Trait`,
|
||||
// but `{}` was found in the type `{}`
|
||||
E0567, // auto traits can not have type parameters
|
||||
E0568, // auto-traits can not have predicates,
|
||||
E0587, // struct has conflicting packed and align representation hints
|
||||
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
|
||||
E0592, // duplicate definitions with name `{}`
|
||||
|
@ -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
|
||||
|
@ -430,7 +430,6 @@ pub enum ItemEnum {
|
||||
PrimitiveItem(PrimitiveType),
|
||||
AssociatedConstItem(Type, Option<String>),
|
||||
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
||||
AutoImplItem(AutoImpl),
|
||||
/// An item that has been stripped by a rustdoc pass
|
||||
StrippedItem(Box<ItemEnum>),
|
||||
}
|
||||
@ -481,7 +480,6 @@ impl Clean<Item> for doctree::Module {
|
||||
items.extend(self.traits.iter().map(|x| x.clean(cx)));
|
||||
items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
|
||||
items.extend(self.macros.iter().map(|x| x.clean(cx)));
|
||||
items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
|
||||
|
||||
// determine if we should display the inner contents or
|
||||
// the outer `mod` item for the source code.
|
||||
@ -2941,30 +2939,6 @@ fn build_deref_target_impls(cx: &DocContext,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct AutoImpl {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub trait_: Type,
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::AutoImpl {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.whence.clean(cx),
|
||||
def_id: cx.tcx.hir.local_def_id(self.id),
|
||||
visibility: Some(Public),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: AutoImplItem(AutoImpl {
|
||||
unsafety: self.unsafety,
|
||||
trait_: self.trait_.clean(cx),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::ExternCrate {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
|
@ -44,7 +44,6 @@ pub struct Module {
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub depr: Option<attr::Deprecation>,
|
||||
pub impls: Vec<Impl>,
|
||||
pub def_traits: Vec<AutoImpl>,
|
||||
pub foreigns: Vec<hir::ForeignMod>,
|
||||
pub macros: Vec<Macro>,
|
||||
pub is_crate: bool,
|
||||
@ -73,7 +72,6 @@ impl Module {
|
||||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
impls : Vec::new(),
|
||||
def_traits : Vec::new(),
|
||||
foreigns : Vec::new(),
|
||||
macros : Vec::new(),
|
||||
is_crate : false,
|
||||
@ -227,14 +225,6 @@ pub struct Impl {
|
||||
pub id: ast::NodeId,
|
||||
}
|
||||
|
||||
pub struct AutoImpl {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub trait_: hir::TraitRef,
|
||||
pub id: ast::NodeId,
|
||||
pub attrs: hir::HirVec<ast::Attribute>,
|
||||
pub whence: Span,
|
||||
}
|
||||
|
||||
// For Macro we store the DefId instead of the NodeId, since we also create
|
||||
// these imported macro_rules (which only have a DUMMY_NODE_ID).
|
||||
pub struct Macro {
|
||||
|
@ -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!(),
|
||||
}
|
||||
|
@ -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"),
|
||||
|
@ -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(..) => {}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ pub use panicking::{take_hook, set_hook, PanicInfo, Location};
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
|
||||
across an unwind boundary"]
|
||||
pub trait UnwindSafe {}
|
||||
pub auto trait UnwindSafe {}
|
||||
|
||||
/// A marker trait representing types where a shared reference is considered
|
||||
/// unwind safe.
|
||||
@ -115,7 +115,7 @@ pub trait UnwindSafe {}
|
||||
#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
|
||||
and a reference may not be safely transferrable \
|
||||
across a catch_unwind boundary"]
|
||||
pub trait RefUnwindSafe {}
|
||||
pub auto trait RefUnwindSafe {}
|
||||
|
||||
/// A simple wrapper around a type to assert that it is unwind safe.
|
||||
///
|
||||
@ -187,10 +187,7 @@ pub struct AssertUnwindSafe<T>(
|
||||
// * Unique, an owning pointer, lifts an implementation
|
||||
// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
|
||||
// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
#[allow(unknown_lints)]
|
||||
#[allow(auto_impl)]
|
||||
impl UnwindSafe for .. {}
|
||||
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
@ -219,14 +216,10 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
|
||||
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
|
||||
|
||||
// Pretty simple implementations for the `RefUnwindSafe` marker trait,
|
||||
// basically just saying that this is a marker trait and `UnsafeCell` is the
|
||||
// basically just saying that `UnsafeCell` is the
|
||||
// only thing which doesn't implement it (which then transitively applies to
|
||||
// everything else).
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
#[allow(unknown_lints)]
|
||||
#[allow(auto_impl)]
|
||||
impl RefUnwindSafe for .. {}
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1532,13 +1532,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
"trait aliases are not yet fully implemented");
|
||||
}
|
||||
|
||||
ast::ItemKind::AutoImpl(..) => {
|
||||
gate_feature_post!(&self, optin_builtin_traits,
|
||||
i.span,
|
||||
"auto trait implementations are experimental \
|
||||
and possibly buggy");
|
||||
}
|
||||
|
||||
ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => {
|
||||
if polarity == ast::ImplPolarity::Negative {
|
||||
gate_feature_post!(&self, optin_builtin_traits,
|
||||
|
@ -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,
|
||||
|
@ -4084,14 +4084,14 @@ impl<'a> Parser<'a> {
|
||||
self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
|
||||
}
|
||||
|
||||
fn eat_auto_trait(&mut self) -> bool {
|
||||
if self.token.is_keyword(keywords::Auto)
|
||||
&& self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
|
||||
{
|
||||
self.eat_keyword(keywords::Auto) && self.eat_keyword(keywords::Trait)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
fn is_auto_trait_item(&mut self) -> bool {
|
||||
// auto trait
|
||||
(self.token.is_keyword(keywords::Auto)
|
||||
&& self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
|
||||
|| // unsafe auto trait
|
||||
(self.token.is_keyword(keywords::Unsafe) &&
|
||||
self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) &&
|
||||
self.look_ahead(2, |t| t.is_keyword(keywords::Trait)))
|
||||
}
|
||||
|
||||
fn is_defaultness(&self) -> bool {
|
||||
@ -4194,7 +4194,8 @@ impl<'a> Parser<'a> {
|
||||
node: StmtKind::Item(macro_def),
|
||||
span: lo.to(self.prev_span),
|
||||
}
|
||||
// Starts like a simple path, but not a union item or item with `crate` visibility.
|
||||
// Starts like a simple path, being careful to avoid contextual keywords
|
||||
// such as a union items, item with `crate` visibility or auto trait items.
|
||||
// Our goal here is to parse an arbitrary path `a::b::c` but not something that starts
|
||||
// like a path (1 token), but it fact not a path.
|
||||
// `union::b::c` - path, `union U { ... }` - not a path.
|
||||
@ -4204,7 +4205,8 @@ impl<'a> Parser<'a> {
|
||||
!self.token.is_qpath_start() &&
|
||||
!self.is_union_item() &&
|
||||
!self.is_crate_vis() &&
|
||||
!self.is_extern_non_path() {
|
||||
!self.is_extern_non_path() &&
|
||||
!self.is_auto_trait_item() {
|
||||
let pth = self.parse_path(PathStyle::Expr)?;
|
||||
|
||||
if !self.eat(&token::Not) {
|
||||
@ -5374,11 +5376,9 @@ impl<'a> Parser<'a> {
|
||||
/// Parses items implementations variants
|
||||
/// impl<T> Foo { ... }
|
||||
/// impl<T> ToString for &'static T { ... }
|
||||
/// impl Send for .. {}
|
||||
fn parse_item_impl(&mut self,
|
||||
unsafety: ast::Unsafety,
|
||||
defaultness: Defaultness) -> PResult<'a, ItemInfo> {
|
||||
let impl_span = self.span;
|
||||
|
||||
// First, parse type parameters if necessary.
|
||||
let mut generics = self.parse_generics()?;
|
||||
@ -5421,48 +5421,35 @@ impl<'a> Parser<'a> {
|
||||
None
|
||||
};
|
||||
|
||||
if opt_trait.is_some() && self.eat(&token::DotDot) {
|
||||
if generics.is_parameterized() {
|
||||
self.span_err(impl_span, "auto trait implementations are not \
|
||||
allowed to have generics");
|
||||
if opt_trait.is_some() {
|
||||
ty = if self.eat(&token::DotDot) {
|
||||
P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID })
|
||||
} else {
|
||||
self.parse_ty()?
|
||||
}
|
||||
}
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
|
||||
if let ast::Defaultness::Default = defaultness {
|
||||
self.span_err(impl_span, "`default impl` is not allowed for \
|
||||
auto trait implementations");
|
||||
}
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
let attrs = self.parse_inner_attributes()?;
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
self.expect(&token::CloseDelim(token::Brace))?;
|
||||
Ok((keywords::Invalid.ident(),
|
||||
ItemKind::AutoImpl(unsafety, opt_trait.unwrap()), None))
|
||||
} else {
|
||||
if opt_trait.is_some() {
|
||||
ty = self.parse_ty()?;
|
||||
}
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
let attrs = self.parse_inner_attributes()?;
|
||||
|
||||
let mut impl_items = vec![];
|
||||
while !self.eat(&token::CloseDelim(token::Brace)) {
|
||||
let mut at_end = false;
|
||||
match self.parse_impl_item(&mut at_end) {
|
||||
Ok(item) => impl_items.push(item),
|
||||
Err(mut e) => {
|
||||
e.emit();
|
||||
if !at_end {
|
||||
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
|
||||
}
|
||||
let mut impl_items = vec![];
|
||||
while !self.eat(&token::CloseDelim(token::Brace)) {
|
||||
let mut at_end = false;
|
||||
match self.parse_impl_item(&mut at_end) {
|
||||
Ok(item) => impl_items.push(item),
|
||||
Err(mut e) => {
|
||||
e.emit();
|
||||
if !at_end {
|
||||
self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((keywords::Invalid.ident(),
|
||||
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
|
||||
Some(attrs)))
|
||||
}
|
||||
|
||||
Ok((keywords::Invalid.ident(),
|
||||
ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
|
||||
Some(attrs)))
|
||||
}
|
||||
|
||||
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
|
||||
@ -6387,7 +6374,8 @@ impl<'a> Parser<'a> {
|
||||
let is_auto = if self.eat_keyword(keywords::Trait) {
|
||||
IsAuto::No
|
||||
} else {
|
||||
self.eat_auto_trait();
|
||||
self.expect_keyword(keywords::Auto)?;
|
||||
self.expect_keyword(keywords::Trait)?;
|
||||
IsAuto::Yes
|
||||
};
|
||||
let (ident, item_, extra_attrs) =
|
||||
@ -6501,7 +6489,8 @@ impl<'a> Parser<'a> {
|
||||
let is_auto = if self.eat_keyword(keywords::Trait) {
|
||||
IsAuto::No
|
||||
} else {
|
||||
self.eat_auto_trait();
|
||||
self.expect_keyword(keywords::Auto)?;
|
||||
self.expect_keyword(keywords::Trait)?;
|
||||
IsAuto::Yes
|
||||
};
|
||||
// TRAIT ITEM
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -11,12 +11,9 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
auto trait Generic<T> {}
|
||||
//~^ ERROR auto traits cannot have generics
|
||||
//~^^ traits with auto impls (`e.g. impl Trait for ..`) can not have type parameters
|
||||
//~^ auto traits cannot have generic parameters [E0567]
|
||||
auto trait Bound : Copy {}
|
||||
//~^ ERROR auto traits cannot have super traits
|
||||
//~^^ traits with auto impls (`e.g. impl Trait for ..`) cannot have predicates
|
||||
//~^ auto traits cannot have super traits [E0568]
|
||||
auto trait MyTrait { fn foo() {} }
|
||||
//~^ ERROR auto traits cannot contain items
|
||||
//~^^ traits with default impls (`e.g. impl Trait for ..`) must have no methods or associated items
|
||||
//~^ auto traits cannot have methods or associated items [E0380]
|
||||
fn main() {}
|
||||
|
@ -11,8 +11,6 @@
|
||||
#![feature(optin_builtin_traits, core)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
pub trait DefaultedTrait { }
|
||||
#[allow(auto_impl)]
|
||||
impl DefaultedTrait for .. { }
|
||||
pub auto trait DefaultedTrait { }
|
||||
|
||||
pub struct Something<T> { t: T }
|
||||
|
@ -10,25 +10,16 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait { fn foo() {} }
|
||||
auto trait MySafeTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyTrait for .. {}
|
||||
//~^ ERROR redundant auto implementations of trait `MyTrait`
|
||||
struct Foo;
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyTrait for .. {}
|
||||
|
||||
trait MySafeTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
unsafe impl MySafeTrait for .. {}
|
||||
unsafe impl MySafeTrait for Foo {}
|
||||
//~^ ERROR implementing the trait `MySafeTrait` is not unsafe
|
||||
|
||||
unsafe trait MyUnsafeTrait {}
|
||||
unsafe auto trait MyUnsafeTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyUnsafeTrait for .. {}
|
||||
impl MyUnsafeTrait for Foo {}
|
||||
//~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
|
||||
|
||||
fn main() {}
|
||||
|
@ -12,17 +12,15 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
unsafe trait Trait {
|
||||
unsafe auto trait Trait {
|
||||
//~^ ERROR E0380
|
||||
type Output;
|
||||
}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
unsafe impl Trait for .. {}
|
||||
|
||||
fn call_method<T: Trait>(x: T) {}
|
||||
|
||||
fn main() {
|
||||
// ICE
|
||||
call_method(());
|
||||
//~^ ERROR
|
||||
}
|
||||
|
@ -12,16 +12,13 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
unsafe trait Trait {
|
||||
unsafe auto trait Trait {
|
||||
//~^ ERROR E0380
|
||||
fn method(&self) {
|
||||
println!("Hello");
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
unsafe impl Trait for .. {}
|
||||
|
||||
fn call_method<T: Trait>(x: T) {
|
||||
x.method();
|
||||
}
|
||||
|
@ -16,10 +16,7 @@
|
||||
|
||||
use std::marker::{PhantomData};
|
||||
|
||||
unsafe trait Zen {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
unsafe impl Zen for .. {}
|
||||
unsafe auto trait Zen {}
|
||||
|
||||
unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MarkerTr {}
|
||||
pub trait Tr {
|
||||
fn f();
|
||||
const C: u8;
|
||||
@ -21,8 +20,6 @@ pub struct S {
|
||||
}
|
||||
struct Ts(pub u8);
|
||||
|
||||
#[allow(auto_impl)]
|
||||
pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
|
||||
pub impl Tr for S { //~ ERROR unnecessary visibility qualifier
|
||||
pub fn f() {} //~ ERROR unnecessary visibility qualifier
|
||||
pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
|
||||
@ -39,7 +36,6 @@ pub extern "C" { //~ ERROR unnecessary visibility qualifier
|
||||
}
|
||||
|
||||
const MAIN: u8 = {
|
||||
trait MarkerTr {}
|
||||
pub trait Tr {
|
||||
fn f();
|
||||
const C: u8;
|
||||
@ -50,8 +46,6 @@ const MAIN: u8 = {
|
||||
}
|
||||
struct Ts(pub u8);
|
||||
|
||||
#[allow(auto_impl)]
|
||||
pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
|
||||
pub impl Tr for S { //~ ERROR unnecessary visibility qualifier
|
||||
pub fn f() {} //~ ERROR unnecessary visibility qualifier
|
||||
pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
|
||||
@ -71,7 +65,6 @@ const MAIN: u8 = {
|
||||
};
|
||||
|
||||
fn main() {
|
||||
trait MarkerTr {}
|
||||
pub trait Tr {
|
||||
fn f();
|
||||
const C: u8;
|
||||
@ -82,8 +75,6 @@ fn main() {
|
||||
}
|
||||
struct Ts(pub u8);
|
||||
|
||||
#[allow(auto_impl)]
|
||||
pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
|
||||
pub impl Tr for S { //~ ERROR unnecessary visibility qualifier
|
||||
pub fn f() {} //~ ERROR unnecessary visibility qualifier
|
||||
pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
|
||||
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(specialization)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Foo {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
default impl Foo for .. {}
|
||||
//~^ ERROR `default impl` is not allowed for auto trait implementations
|
||||
|
||||
fn main() {}
|
@ -13,18 +13,12 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(specialization)]
|
||||
|
||||
trait Foo {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl Foo for .. {}
|
||||
auto trait Foo {}
|
||||
|
||||
impl<T> Foo for T {}
|
||||
impl !Foo for u8 {} //~ ERROR E0119
|
||||
|
||||
trait Bar {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl Bar for .. {}
|
||||
auto trait Bar {}
|
||||
|
||||
impl<T> !Bar for T {}
|
||||
impl Bar for u8 {} //~ ERROR E0119
|
||||
|
@ -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() {}
|
@ -14,9 +14,7 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Magic: Copy {} //~ ERROR E0568
|
||||
#[allow(auto_impl)]
|
||||
impl Magic for .. {}
|
||||
auto trait Magic: Copy {} //~ ERROR E0568
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
||||
@ -24,6 +22,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
struct NoClone;
|
||||
|
||||
fn main() {
|
||||
let (a, b) = copy(NoClone);
|
||||
let (a, b) = copy(NoClone); //~ ERROR
|
||||
println!("{:?} {:?}", a, b);
|
||||
}
|
||||
|
@ -10,9 +10,7 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
|
||||
#[allow(auto_impl)]
|
||||
impl Magic for .. {}
|
||||
auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
@ -34,9 +34,7 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Magic: Copy {} //~ ERROR E0568
|
||||
#[allow(auto_impl)]
|
||||
impl Magic for .. {}
|
||||
auto trait Magic: Copy {} //~ ERROR E0568
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
@ -1,15 +0,0 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Magic<T> {} //~ ERROR E0567
|
||||
#[allow(auto_impl)]
|
||||
impl Magic<isize> for .. {}
|
@ -10,10 +10,7 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyTrait for .. {}
|
||||
auto trait MyTrait {}
|
||||
|
||||
struct MyS;
|
||||
|
||||
|
@ -10,10 +10,8 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait {}
|
||||
auto trait MyTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyTrait for .. {}
|
||||
impl<T> !MyTrait for *mut T {}
|
||||
|
||||
struct MyS;
|
||||
|
@ -10,15 +10,9 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait {}
|
||||
auto trait MyTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl MyTrait for .. {}
|
||||
|
||||
unsafe trait MyUnsafeTrait {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
unsafe impl MyUnsafeTrait for .. {}
|
||||
unsafe auto trait MyUnsafeTrait {}
|
||||
|
||||
struct ThisImplsTrait;
|
||||
|
||||
|
@ -10,14 +10,12 @@
|
||||
|
||||
// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies
|
||||
// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
|
||||
// other words, the `..` impl only applies if there are no existing
|
||||
// other words, the auto impl only applies if there are no existing
|
||||
// impls whose types unify.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Defaulted { }
|
||||
#[allow(auto_impl)]
|
||||
impl Defaulted for .. { }
|
||||
auto trait Defaulted { }
|
||||
impl<'a,T:Signed> Defaulted for &'a T { }
|
||||
impl<'a,T:Signed> Defaulted for &'a mut T { }
|
||||
fn is_defaulted<T:Defaulted>() { }
|
||||
|
@ -80,6 +80,4 @@ pub mod marker {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
trait Freeze {}
|
||||
#[allow(auto_impl)]
|
||||
impl Freeze for .. {}
|
||||
auto trait Freeze {}
|
||||
|
@ -18,9 +18,7 @@ trait Copy { }
|
||||
trait Sized { }
|
||||
|
||||
#[lang = "freeze"]
|
||||
trait Freeze {}
|
||||
#[allow(auto_impl)]
|
||||
impl Freeze for .. {}
|
||||
auto trait Freeze {}
|
||||
|
||||
#[lang="start"]
|
||||
fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 }
|
||||
|
@ -11,10 +11,6 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
auto trait Auto {}
|
||||
// Redundant but accepted until we remove it.
|
||||
#[allow(auto_impl)]
|
||||
impl Auto for .. {}
|
||||
|
||||
unsafe auto trait AutoUnsafe {}
|
||||
|
||||
impl !Auto for bool {}
|
||||
@ -29,6 +25,10 @@ fn take_auto<T: Auto>(_: T) {}
|
||||
fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
// Parse inside functions.
|
||||
auto trait AutoInner {}
|
||||
unsafe auto trait AutoUnsafeInner {}
|
||||
|
||||
take_auto(0);
|
||||
take_auto(AutoBool(true));
|
||||
take_auto_unsafe(0);
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait NotSame {}
|
||||
#[allow(auto_impl)]
|
||||
impl NotSame for .. {}
|
||||
auto trait NotSame {}
|
||||
|
||||
impl<A> !NotSame for (A, A) {}
|
||||
|
||||
trait OneOfEach {}
|
||||
|
@ -14,10 +14,7 @@
|
||||
pub mod bar {
|
||||
use std::marker;
|
||||
|
||||
pub trait Bar {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl Bar for .. {}
|
||||
pub auto trait Bar {}
|
||||
|
||||
pub trait Foo {
|
||||
fn foo(&self) {}
|
||||
|
@ -10,7 +10,4 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
pub trait AnOibit {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl AnOibit for .. {}
|
||||
pub auto trait AnOibit {}
|
||||
|
@ -10,10 +10,7 @@
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
pub trait AnOibit {}
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl AnOibit for .. {}
|
||||
pub auto trait AnOibit {}
|
||||
|
||||
pub struct Foo<T> { field: T }
|
||||
|
||||
|
@ -20,10 +20,6 @@ trait DummyTrait {
|
||||
auto trait AutoDummyTrait {}
|
||||
//~^ ERROR auto traits are experimental and possibly buggy
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl DummyTrait for .. {}
|
||||
//~^ ERROR auto trait implementations are experimental and possibly buggy
|
||||
|
||||
impl !DummyTrait for DummyStruct {}
|
||||
//~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
|
||||
|
||||
|
@ -6,21 +6,13 @@ error: auto traits are experimental and possibly buggy (see issue #13231)
|
||||
|
|
||||
= help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
|
||||
|
||||
error: auto trait implementations are experimental and possibly buggy (see issue #13231)
|
||||
--> $DIR/feature-gate-optin-builtin-traits.rs:24:1
|
||||
|
|
||||
24 | impl DummyTrait for .. {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
|
||||
|
||||
error: negative trait bounds are not yet fully implemented; use marker types for now (see issue #13231)
|
||||
--> $DIR/feature-gate-optin-builtin-traits.rs:27:1
|
||||
--> $DIR/feature-gate-optin-builtin-traits.rs:23:1
|
||||
|
|
||||
27 | impl !DummyTrait for DummyStruct {}
|
||||
23 | impl !DummyTrait for DummyStruct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -8,9 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
trait Trait1 {}
|
||||
trait Trait2 {}
|
||||
|
||||
trait Foo {}
|
||||
impl Foo for .. {}
|
||||
//~^ ERROR The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`
|
||||
//~^^ WARN this was previously accepted by the compiler
|
||||
#[cfg(not_enabled)]
|
||||
impl Trait1 for .. {}
|
||||
|
||||
impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
|
||||
|
||||
fn main() {}
|
10
src/test/ui/obsolete-syntax-impl-for-dotdot.stderr
Normal file
10
src/test/ui/obsolete-syntax-impl-for-dotdot.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error: `impl Trait for .. {}` is an obsolete syntax
|
||||
--> $DIR/obsolete-syntax-impl-for-dotdot.rs:17:1
|
||||
|
|
||||
17 | impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: use `auto trait Trait {}` instead
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,15 +0,0 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
#[allow(auto_impl)]
|
||||
impl Copy for .. {} //~ ERROR E0318
|
||||
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user