]> git.lizzy.rs Git - rust.git/commitdiff
Remove `#[default..]` and add `#[const_trait]`
authorDeadbeef <ent3rm4n@gmail.com>
Wed, 16 Mar 2022 09:49:54 +0000 (20:49 +1100)
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Mon, 30 May 2022 08:52:24 +0000 (08:52 +0000)
30 files changed:
compiler/rustc_const_eval/src/const_eval/machine.rs
compiler/rustc_const_eval/src/lib.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/check_consts/mod.rs
compiler/rustc_feature/src/builtin_attrs.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_middle/src/hir/map/mod.rs
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/check_const.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_ty_utils/src/ty.rs
library/core/src/clone.rs
library/core/src/cmp.rs
src/test/rustdoc/rfc-2632-const-trait-impl.rs
src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs
src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr
src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs
src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs
src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs
src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs
src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs
src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs
src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr
src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs
src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs
src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs

index 9de5541bfe36cec0e310bd9051e46beefd590fad..8bd8280497c098b5b2474ed3946bd5688238180b 100644 (file)
@@ -277,8 +277,9 @@ fn find_mir_or_eval_fn(
             // sensitive check here.  But we can at least rule out functions that are not const
             // at all.
             if !ecx.tcx.is_const_fn_raw(def.did) {
-                // allow calling functions marked with #[default_method_body_is_const].
-                if !ecx.tcx.has_attr(def.did, sym::default_method_body_is_const) {
+                // allow calling functions inside a trait marked with #[const_trait].
+                if !matches!(ecx.tcx.trait_of_item(def.did), Some(trait_id) if ecx.tcx.has_attr(trait_id, sym::const_trait))
+                {
                     // We certainly do *not* want to actually call the fn
                     // though, so be sure we return here.
                     throw_unsup_format!("calling non-const function `{}`", instance)
index eacb5978d993a18dcc76afd0abd17c025689fd5e..d2b5ef8ea6fa6fe03893c859fc35547c433375e0 100644 (file)
@@ -9,6 +9,7 @@
 #![feature(control_flow_enum)]
 #![feature(decl_macro)]
 #![feature(exact_size_is_empty)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
index 2c669dd6d9a9b494dc4f4124071e67d97b9a4216..57c073cca4dbab75f8d15c8c98f69ffc3885db7d 100644 (file)
@@ -774,13 +774,11 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                             }
                         }
                         _ if !tcx.is_const_fn_raw(callee) => {
-                            // At this point, it is only legal when the caller is marked with
-                            // #[default_method_body_is_const], and the callee is in the same
-                            // trait.
-                            let callee_trait = tcx.trait_of_item(callee);
-                            if callee_trait.is_some()
-                                && tcx.has_attr(caller.to_def_id(), sym::default_method_body_is_const)
-                                && callee_trait == tcx.trait_of_item(caller)
+                            // At this point, it is only legal when the caller is in a trait
+                            // marked with #[const_trait], and the callee is in the same trait.
+                            if let Some(callee_trait) = tcx.trait_of_item(callee)
+                                && tcx.has_attr(callee_trait, sym::const_trait)
+                                && Some(callee_trait) == tcx.trait_of_item(caller)
                                 // Can only call methods when it's `<Self as TheTrait>::f`.
                                 && tcx.types.self_param == substs.type_at(0)
                             {
@@ -875,7 +873,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
 
                 if !tcx.is_const_fn_raw(callee) {
                     if tcx.trait_of_item(callee).is_some() {
-                        if tcx.has_attr(callee, sym::default_method_body_is_const) {
+                        if let Some(callee_trait) = tcx.trait_of_item(callee) && tcx.has_attr(callee_trait, sym::const_trait) {
                             // To get to here we must have already found a const impl for the
                             // trait, but for it to still be non-const can be that the impl is
                             // using default method bodies.
index 0f79fe5513dd8790db99a80faba783ef77fb94e2..32cabb1f899effd66b9a0bf710a4c1d41c555702 100644 (file)
@@ -84,10 +84,10 @@ pub fn rustc_allow_const_fn_unstable(
 // functions are subject to more stringent restrictions than "const-unstable" functions: They
 // cannot use unstable features and can only call other "const-stable" functions.
 pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
-    // A default body marked const is not const-stable because const
+    // A default body in a `#[const_trait]` is not const-stable because const
     // trait fns currently cannot be const-stable. We shouldn't
     // restrict default bodies to only call const-stable functions.
-    if tcx.has_attr(def_id, sym::default_method_body_is_const) {
+    if let Some(trait_id) = tcx.trait_of_item(def_id) && tcx.has_attr(trait_id, sym::const_trait) {
         return false;
     }
 
index 097493e8985fb25ea4c8ec5339b57a940db871f8..5c0b87df49244fe841ad0d889784560b5e597d30 100644 (file)
@@ -473,9 +473,10 @@ pub struct BuiltinAttribute {
     ),
     // RFC 2632
     gated!(
-        default_method_body_is_const, Normal, template!(Word), WarnFollowing, const_trait_impl,
-        "`default_method_body_is_const` is a temporary placeholder for declaring default bodies \
-        as `const`, which may be removed or renamed in the future."
+        const_trait, Normal, template!(Word), WarnFollowing, const_trait_impl,
+        "`const` is a temporary placeholder for marking a trait that is suitable for `const` \
+        `impls` and all default bodies as `const`, which may be removed or renamed in the \
+        future."
     ),
     // lang-team MCP 147
     gated!(
index 339d2fc0867aeedf3e0801186fcc86543bb191cc..3e647f4a50ec0059565e8e31144bc55b855d279c 100644 (file)
@@ -891,9 +891,11 @@ fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) {
             let needs_inline = (generics.requires_monomorphization(tcx)
                 || tcx.codegen_fn_attrs(def_id).requests_inline())
                 && tcx.sess.opts.output_types.should_codegen();
-            // The function has a `const` modifier or is annotated with `default_method_body_is_const`.
-            let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id())
-                || tcx.has_attr(def_id.to_def_id(), sym::default_method_body_is_const);
+            // The function has a `const` modifier or is in a `#[const_trait]`.
+            let mut is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id());
+            if let Some(trait_) = tcx.trait_of_item(def_id.to_def_id()) {
+                is_const_fn = is_const_fn || tcx.has_attr(trait_, sym::const_trait);
+            }
             let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
             (is_const_fn, needs_inline || always_encode_mir)
         }
index 9976b0e9862041ba63e52ea09c21b8e8633a627c..6d7a8a46df1787f33763f6e8be7dd1b4c00847d3 100644 (file)
@@ -494,9 +494,7 @@ pub fn body_const_context(self, def_id: LocalDefId) -> Option<ConstContext> {
             BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
                 ConstContext::ConstFn
             }
-            BodyOwnerKind::Fn
-                if self.tcx.has_attr(def_id.to_def_id(), sym::default_method_body_is_const) =>
-            {
+            BodyOwnerKind::Fn if matches!(self.tcx.trait_of_item(def_id.to_def_id()), Some(trait_id) if self.tcx.has_attr(trait_id, sym::const_trait)) => {
                 ConstContext::ConstFn
             }
             BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,
index 3d5da114ecfde758cbb09e21d9738b8b0cb1d564..7753c20d3b5b36e20b2f5400236453a5db718cdc 100644 (file)
@@ -121,9 +121,7 @@ fn check_attributes(
                 | sym::rustc_if_this_changed
                 | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
                 sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
-                sym::default_method_body_is_const => {
-                    self.check_default_method_body_is_const(attr, span, target)
-                }
+                sym::const_trait => self.check_const_trait(attr, span, target),
                 sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
                 sym::must_use => self.check_must_use(hir_id, &attr, span, target),
                 sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target),
@@ -2081,23 +2079,14 @@ fn check_rustc_std_internal_symbol(
         }
     }
 
-    /// default_method_body_is_const should only be applied to trait methods with default bodies.
-    fn check_default_method_body_is_const(
-        &self,
-        attr: &Attribute,
-        span: Span,
-        target: Target,
-    ) -> bool {
+    /// `#[const_trait]` only applies to traits.
+    fn check_const_trait(&self, attr: &Attribute, _span: Span, target: Target) -> bool {
         match target {
-            Target::Method(MethodKind::Trait { body: true }) => true,
+            Target::Trait => true,
             _ => {
                 self.tcx
                     .sess
-                    .struct_span_err(
-                        attr.span,
-                        "attribute should be applied to a trait method with body",
-                    )
-                    .span_label(span, "not a trait method or missing a body")
+                    .struct_span_err(attr.span, "attribute should be applied to a trait")
                     .emit();
                 false
             }
@@ -2191,6 +2180,8 @@ fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute) {
                 "attribute `{}` without any lints has no effect",
                 attr.name_or_empty()
             )
+        } else if attr.name_or_empty() == sym::default_method_body_is_const {
+            format!("`default_method_body_is_const` has been removed")
         } else {
             return;
         };
index 04d6e9f205abd56b40cc5c9e8dedb7bcd78219bd..996ca66de0e45a6a3935992c4c16268521d686bb 100644 (file)
@@ -13,7 +13,6 @@
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
@@ -64,66 +63,6 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_const_bodies, ..*providers };
 }
 
-fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
-    let _: Option<_> = try {
-        if let hir::ItemKind::Impl(ref imp) = item.kind && let hir::Constness::Const = imp.constness {
-            let trait_def_id = imp.of_trait.as_ref()?.trait_def_id()?;
-            let ancestors = tcx
-                .trait_def(trait_def_id)
-                .ancestors(tcx, item.def_id.to_def_id())
-                .ok()?;
-            let mut to_implement = Vec::new();
-
-            for trait_item in tcx.associated_items(trait_def_id).in_definition_order()
-            {
-                if let ty::AssocItem {
-                    kind: ty::AssocKind::Fn,
-                    defaultness,
-                    def_id: trait_item_id,
-                    ..
-                } = *trait_item
-                {
-                    // we can ignore functions that do not have default bodies:
-                    // if those are unimplemented it will be caught by typeck.
-                    if !defaultness.has_value()
-                        || tcx
-                        .has_attr(trait_item_id, sym::default_method_body_is_const)
-                    {
-                        continue;
-                    }
-
-                    let is_implemented = ancestors
-                        .leaf_def(tcx, trait_item_id)
-                        .map(|node_item| !node_item.defining_node.is_from_trait())
-                        .unwrap_or(false);
-
-                    if !is_implemented {
-                        to_implement.push(trait_item_id);
-                    }
-                }
-            }
-
-            // all nonconst trait functions (not marked with #[default_method_body_is_const])
-            // must be implemented
-            if !to_implement.is_empty() {
-                let not_implemented = to_implement
-                    .into_iter()
-                    .map(|did| tcx.item_name(did).to_string())
-                    .collect::<Vec<_>>()
-                    .join("`, `");
-                tcx
-                    .sess
-                    .struct_span_err(
-                        item.span,
-                        "const trait implementations may not use non-const default functions",
-                    )
-                    .note(&format!("`{}` not implemented", not_implemented))
-                    .emit();
-            }
-        }
-    };
-}
-
 #[derive(Copy, Clone)]
 struct CheckConstVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -254,7 +193,6 @@ fn nested_visit_map(&mut self) -> Self::Map {
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         intravisit::walk_item(self, item);
-        check_item(self.tcx, item);
     }
 
     fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
index 406e9a4113ef394f6a9337ddf514553c614934ce..c4b4ac77ad68cf861e8924a20697670259c0b161 100644 (file)
         const_raw_ptr_deref,
         const_raw_ptr_to_usize_cast,
         const_refs_to_cell,
+        const_trait,
         const_trait_bound_opt_out,
         const_trait_impl,
         const_transmute,
index 23700e653e36a23359a66ebc382dd11183ec01f6..b52ee817509ca3604fff21b176494767ee53992b 100644 (file)
@@ -152,9 +152,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
 
     let constness = match hir_id {
         Some(hir_id) => match tcx.hir().get(hir_id) {
-            hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
-                if tcx.has_attr(def_id, sym::default_method_body_is_const) =>
-            {
+            hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) if matches!(tcx.trait_of_item(def_id), Some(trait_id) if tcx.has_attr(trait_id, sym::const_trait)) => {
                 hir::Constness::Const
             }
 
index 0444a9575d1af1c67d07baf167e6e83ffadd7d87..70f3fe853d97aad8202b86c23211042230f2ff99 100644 (file)
 #[lang = "clone"]
 #[rustc_diagnostic_item = "Clone"]
 #[rustc_trivial_field_reads]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Clone: Sized {
     /// Returns a copy of the value.
     ///
@@ -129,7 +130,7 @@ pub trait Clone: Sized {
     /// allocations.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[default_method_body_is_const]
+    #[cfg_attr(bootstrap, default_method_body_is_const)]
     fn clone_from(&mut self, source: &Self)
     where
         Self: ~const Destruct,
index 74328a3607d6447da45a261e05f1d80b7a05dbbc..f281e8429c693e40089326b9443e5a4a534e8f07 100644 (file)
         append_const_msg,
     )
 )]
+#[cfg_attr(not(bootstrap), const_trait)]
 #[rustc_diagnostic_item = "PartialEq"]
 pub trait PartialEq<Rhs: ?Sized = Self> {
     /// This method tests for `self` and `other` values to be equal, and is used
@@ -226,7 +227,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[default_method_body_is_const]
+    #[cfg_attr(bootstrap, default_method_body_is_const)]
     fn ne(&self, other: &Rhs) -> bool {
         !self.eq(other)
     }
@@ -1053,6 +1054,7 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
         append_const_msg,
     )
 )]
+#[cfg_attr(not(bootstrap), const_trait)]
 #[rustc_diagnostic_item = "PartialOrd"]
 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// This method returns an ordering between `self` and `other` values if one exists.
@@ -1096,7 +1098,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[default_method_body_is_const]
+    #[cfg_attr(bootstrap, default_method_body_is_const)]
     fn lt(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Less))
     }
@@ -1116,7 +1118,7 @@ fn lt(&self, other: &Rhs) -> bool {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[default_method_body_is_const]
+    #[cfg_attr(bootstrap, default_method_body_is_const)]
     fn le(&self, other: &Rhs) -> bool {
         // Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
         // FIXME: The root cause was fixed upstream in LLVM with:
@@ -1139,7 +1141,7 @@ fn le(&self, other: &Rhs) -> bool {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[default_method_body_is_const]
+    #[cfg_attr(bootstrap, default_method_body_is_const)]
     fn gt(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Greater))
     }
@@ -1159,7 +1161,7 @@ fn gt(&self, other: &Rhs) -> bool {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[default_method_body_is_const]
+    #[cfg_attr(bootstrap, default_method_body_is_const)]
     fn ge(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Greater | Equal))
     }
index f9173feeeec81dd0e0ee13938765a3ba6bdb98a8..ec70a69ff1060902588f892678289819da707fc4 100644 (file)
 // @has - '//pre[@class="rust trait"]/code/a[@class="trait"]' 'Clone'
 // @!has - '//pre[@class="rust trait"]/code/span[@class="where"]' '~const'
 // @has - '//pre[@class="rust trait"]/code/span[@class="where"]' ': Clone'
+#[const_trait]
 pub trait Tr<T> {
     // @!has - '//div[@id="method.a"]/h4[@class="code-header"]' '~const'
     // @has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
     // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
     // @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
-    #[default_method_body_is_const]
     fn a<A: ~const Clone + ~const Destruct>()
     where
         Option<A>: ~const Clone + ~const Destruct,
index be73ec09ceb3ba8ea50f807aa4215fdd4a0895f6..01ac74feff74dfe25fe6a573319715e2f3cefbf2 100644 (file)
@@ -1,13 +1,10 @@
 #![feature(const_trait_impl)]
 
-#[default_method_body_is_const] //~ ERROR attribute should be applied
+#[const_trait]
 trait A {
-    #[default_method_body_is_const] //~ ERROR attribute should be applied
-    fn no_body(self);
-
-    #[default_method_body_is_const]
-    fn correct_use(&self) {}
+    #[const_trait] //~ ERROR attribute should be applied
+    fn foo(self);
 }
 
-#[default_method_body_is_const] //~ ERROR attribute should be applied
+#[const_trait] //~ ERROR attribute should be applied
 fn main() {}
index fcb7e15b205e94535b1499b3d91dc25cccfe1857..b18f33218c2db68503e59fdc63c012ff7969f7bd 100644 (file)
@@ -1,32 +1,14 @@
-error: attribute should be applied to a trait method with body
-  --> $DIR/attr-misuse.rs:3:1
+error: attribute should be applied to a trait
+  --> $DIR/attr-misuse.rs:9:1
    |
-LL |   #[default_method_body_is_const]
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | / trait A {
-LL | |     #[default_method_body_is_const]
-LL | |     fn no_body(self);
-LL | |
-LL | |     #[default_method_body_is_const]
-LL | |     fn correct_use(&self) {}
-LL | | }
-   | |_- not a trait method or missing a body
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^
 
-error: attribute should be applied to a trait method with body
-  --> $DIR/attr-misuse.rs:12:1
-   |
-LL | #[default_method_body_is_const]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | fn main() {}
-   | ------------ not a trait method or missing a body
-
-error: attribute should be applied to a trait method with body
+error: attribute should be applied to a trait
   --> $DIR/attr-misuse.rs:5:5
    |
-LL |     #[default_method_body_is_const]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |     fn no_body(self);
-   |     ----------------- not a trait method or missing a body
+LL |     #[const_trait]
+   |     ^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
index 34934d1e01dbd430c097ad50bce6a212e4fdea86..e73082c11276fc4f8af6a8a0dc61f98b8348d9fe 100644 (file)
@@ -1,7 +1,7 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 pub trait MyTrait {
-    #[default_method_body_is_const]
     fn defaulted_func(&self) {}
     fn func(self);
 }
index dd5099317667307c38ebaac6edae56e645610fd4..f66d63da6931447c5d2956d54d95cba6d5dae028 100644 (file)
@@ -2,7 +2,7 @@
 
 pub struct Int(i32);
 
-impl const std::ops::Add for i32 { //~ ERROR type annotations needed
+impl const std::ops::Add for i32 {
     //~^ ERROR only traits defined in the current crate can be implemented for primitive types
     type Output = Self;
 
@@ -11,7 +11,7 @@ fn add(self, rhs: Self) -> Self {
     }
 }
 
-impl std::ops::Add for Int { //~ ERROR type annotations needed
+impl std::ops::Add for Int {
     type Output = Self;
 
     fn add(self, rhs: Self) -> Self {
@@ -19,7 +19,7 @@ fn add(self, rhs: Self) -> Self {
     }
 }
 
-impl const std::ops::Add for Int { //~ ERROR type annotations needed
+impl const std::ops::Add for Int {
     //~^ ERROR conflicting implementations of trait
     type Output = Self;
 
index 9fd82196e79c11836cdd70352ced3100d967f50b..f515ec198adaa5b529ecb57d562a4c90d3148f83 100644 (file)
@@ -19,50 +19,7 @@ LL | impl std::ops::Add for Int {
 LL | impl const std::ops::Add for Int {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int`
 
-error[E0283]: type annotations needed
-  --> $DIR/const-and-non-const-impl.rs:5:12
-   |
-LL | impl const std::ops::Add for i32 {
-   |            ^^^^^^^^^^^^^ cannot infer type for type `i32`
-   |
-note: multiple `impl`s satisfying `i32: Add` found
-  --> $DIR/const-and-non-const-impl.rs:5:1
-   |
-LL | impl const std::ops::Add for i32 {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: and another `impl` found in the `core` crate: `impl Add for i32;`
-
-error[E0283]: type annotations needed
-  --> $DIR/const-and-non-const-impl.rs:14:6
-   |
-LL | impl std::ops::Add for Int {
-   |      ^^^^^^^^^^^^^ cannot infer type for struct `Int`
-   |
-note: multiple `impl`s satisfying `Int: Add` found
-  --> $DIR/const-and-non-const-impl.rs:14:1
-   |
-LL | impl std::ops::Add for Int {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | impl const std::ops::Add for Int {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0283]: type annotations needed
-  --> $DIR/const-and-non-const-impl.rs:22:12
-   |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^ cannot infer type for struct `Int`
-   |
-note: multiple `impl`s satisfying `Int: Add` found
-  --> $DIR/const-and-non-const-impl.rs:14:1
-   |
-LL | impl std::ops::Add for Int {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | impl const std::ops::Add for Int {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0117, E0119, E0283.
+Some errors have detailed explanations: E0117, E0119.
 For more information about an error, try `rustc --explain E0117`.
index 3c82fe1ad6c77f589fa5304c53a6f93d592a065d..0b981d1621ecaf06f80bf1da905d932455bdc1da 100644 (file)
@@ -1,9 +1,9 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait ConstDefaultFn: Sized {
     fn b(self);
 
-    #[default_method_body_is_const]
     fn a(self) {
         self.b();
     }
index c0f90c116e459d09a77afcbe9ab24f0e90790982..bde8bf20f46c5d1942ca195bfd56e9094f0126d1 100644 (file)
@@ -1,4 +1,4 @@
-// This tests that `default_method_body_is_const` methods can
+// This tests that `const_trait` default methods can
 // be called from a const context when used across crates.
 //
 // check-pass
index 17c88e442961eca6f310c61461181ee428dc5fbe..d27291231fbd74dc72881ac8ab72cb26cfe6c480 100644 (file)
@@ -5,8 +5,8 @@ impl Tr for () {}
 
 const fn foo<T>() where T: ~const Tr {}
 
+#[const_trait]
 pub trait Foo {
-    #[default_method_body_is_const]
     fn foo() {
         foo::<()>();
         //~^ ERROR the trait bound `(): ~const Tr` is not satisfied
index be2f3f6d6231e74c26c727104185f0bf7243c982..d798516ff70fd05608449ff0b7e0c44c39d624e7 100644 (file)
@@ -1,10 +1,9 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 pub trait Tr {
-    #[default_method_body_is_const]
     fn a(&self) {}
 
-    #[default_method_body_is_const]
     fn b(&self) {
         ().a()
         //~^ ERROR the trait bound
index cf357971951df5aeef4d4276a4f19ec31927f513..8bb7f0141033de1ab601b90c0c39fb0857e25c6c 100644 (file)
@@ -1,17 +1,17 @@
 error[E0277]: the trait bound `(): ~const Tr` is not satisfied
-  --> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
+  --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
    |
 LL |         ().a()
    |            ^^^ the trait `~const Tr` is not implemented for `()`
    |
 note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
-  --> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
+  --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
    |
 LL |         ().a()
    |            ^^^
 
 error[E0015]: cannot call non-const fn `<() as Tr>::a` in constant functions
-  --> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
+  --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
    |
 LL |         ().a()
    |            ^^^
index 7f6d86d337582fc6c860435eac518717c48336dc..1b45cd9aab9da51f4583c3c64c2d2a5e92e8e008 100644 (file)
@@ -9,8 +9,8 @@
 #![feature(const_trait_impl)]
 #![stable(since = "1", feature = "foo")]
 
+#[const_trait]
 trait Tr {
-    #[default_method_body_is_const]
     fn a() {}
 }
 
index eba8b665ceb0ec10299f7a9791dcfb84af1173d1..6df9696f2cbd79a6a9c30e55ffdcc5affd90fffb 100644 (file)
@@ -1,32 +1,17 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Tr {
     fn req(&self);
 
-    fn prov(&self) {
-        println!("lul");
-        self.req();
-    }
-
-    #[default_method_body_is_const]
     fn default() {}
 }
 
 struct S;
 
-impl const Tr for S {
-    fn req(&self) {}
-} //~^^ ERROR const trait implementations may not use non-const default functions
-
 impl const Tr for u16 {
-    fn prov(&self) {}
     fn default() {}
-} //~^^^ ERROR not all trait items implemented
+} //~^^ ERROR not all trait items implemented
 
 
-impl const Tr for u32 {
-    fn req(&self) {}
-    fn default() {}
-} //~^^^ ERROR const trait implementations may not use non-const default functions
-
 fn main() {}
index 4ec6f929ffcd9a1bd99e6f6d479789bc395afc3e..6c6ca9f5db8201802534089ad0d554a6074e67e2 100644 (file)
@@ -1,26 +1,5 @@
-error: const trait implementations may not use non-const default functions
-  --> $DIR/impl-with-default-fn-fail.rs:17:1
-   |
-LL | / impl const Tr for S {
-LL | |     fn req(&self) {}
-LL | | }
-   | |_^
-   |
-   = note: `prov` not implemented
-
-error: const trait implementations may not use non-const default functions
-  --> $DIR/impl-with-default-fn-fail.rs:27:1
-   |
-LL | / impl const Tr for u32 {
-LL | |     fn req(&self) {}
-LL | |     fn default() {}
-LL | | }
-   | |_^
-   |
-   = note: `prov` not implemented
-
 error[E0046]: not all trait items implemented, missing: `req`
-  --> $DIR/impl-with-default-fn-fail.rs:21:1
+  --> $DIR/impl-with-default-fn-fail.rs:12:1
    |
 LL |     fn req(&self);
    |     -------------- `req` from trait
@@ -28,6 +7,6 @@ LL |     fn req(&self);
 LL | impl const Tr for u16 {
    | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0046`.
index 2e4664714a70ab8e74f9c6595488cba1ec276c37..ae81421e9e1918b4456ac91a210d352b71d46a19 100644 (file)
@@ -2,28 +2,21 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Tr {
     fn req(&self);
 
-    fn prov(&self) {
-        println!("lul");
-        self.req();
-    }
-
-    #[default_method_body_is_const]
     fn default() {}
 }
 
 impl const Tr for u8 {
     fn req(&self) {}
-    fn prov(&self) {}
 }
 
 macro_rules! impl_tr {
     ($ty: ty) => {
         impl const Tr for $ty {
             fn req(&self) {}
-            fn prov(&self) {}
         }
     }
 }
index f4a5d0133ce89666af369f11b9ec9fe4f9d781db..334fc4cb8473d179b557b680b047cfe12055a925 100644 (file)
@@ -37,8 +37,8 @@ fn from_residual(t: T) -> T {
 }
 
 #[stable(feature = "foo", since = "1.0")]
+#[const_trait]
 pub trait Tr {
-    #[default_method_body_is_const]
     #[stable(feature = "foo", since = "1.0")]
     fn bar() -> T {
         T?
index e47c5c7bd6665b1168d5a9aab997d3791f7926f5..b7cf9a13b796564a4fba3a0c3a88a37e5b78f347 100644 (file)
@@ -6,8 +6,8 @@ trait Bar {
     fn bar() -> u8;
 }
 
+#[const_trait]
 trait Foo {
-    #[default_method_body_is_const]
     fn foo() -> u8 where Self: ~const Bar {
         <Self as Bar>::bar() * 6
     }