diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 9de5541bfe3..ac529bf152f 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -277,8 +277,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // 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 !ecx.tcx.is_const_default_method(def.did) { // 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) diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index eacb5978d99..d2b5ef8ea6f 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -9,6 +9,7 @@ Rust MIR: a lowered representation of Rust. #![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)] diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 2c669dd6d9a..eea6e2a47a9 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -711,8 +711,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } }; - let mut nonconst_call_permission = false; - // Attempting to call a trait method? if let Some(trait_id) = tcx.trait_of_item(callee) { trace!("attempting to call a trait method"); @@ -774,13 +772,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } } _ 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. + let mut nonconst_call_permission = false; + 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 `::f`. && tcx.types.self_param == substs.type_at(0) { @@ -874,16 +871,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let is_intrinsic = tcx.is_intrinsic(callee); 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) { - // 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. - nonconst_call_permission = true; - } - } - - if !nonconst_call_permission { + if !tcx.is_const_default_method(callee) { + // 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. self.check_op(ops::FnCallNonConst { caller, callee, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 0f79fe5513d..25b420bed17 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir; use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::{sym, Symbol}; +use rustc_span::Symbol; pub use self::qualifs::Qualif; @@ -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 tcx.is_const_default_method(def_id) { return false; } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index e021e9603f3..8155e65a6db 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -473,9 +473,10 @@ pub const BUILTIN_ATTRIBUTES: &[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!( diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index a639df01a78..68876e89c4b 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -92,6 +92,7 @@ pub enum DefKind { /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593 Ctor(CtorOf, CtorKind), /// Associated function: `impl MyStruct { fn associated() {} }` + /// or `trait Foo { fn associated() {} }` AssocFn, /// Associated constant: `trait MyTrait { const ASSOC: usize; }` AssocConst, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 5a40986307c..f67e1cab16d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -893,9 +893,9 @@ 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`. + // The function has a `const` modifier or is in a `#[const_trait]`. 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); + || tcx.is_const_default_method(def_id.to_def_id()); let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir; (is_const_fn, needs_inline || always_encode_mir) } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 9976b0e9862..97f429cfd3f 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -494,9 +494,7 @@ impl<'hir> Map<'hir> { 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 self.tcx.is_const_default_method(def_id.to_def_id()) => { ConstContext::ConstFn } BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 14e5dc0dd77..a493aaac276 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2303,6 +2303,11 @@ impl<'tcx> TyCtxt<'tcx> { matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..)) && self.impl_constness(def_id) == hir::Constness::Const } + + #[inline] + pub fn is_const_default_method(self, def_id: DefId) -> bool { + matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait)) + } } /// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition. diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3d38ff00eab..0fe6d58b86d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -122,9 +122,7 @@ impl CheckAttrVisitor<'_> { | 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), @@ -2097,23 +2095,14 @@ impl CheckAttrVisitor<'_> { } } - /// 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 } @@ -2207,6 +2196,8 @@ impl CheckAttrVisitor<'_> { "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 replaced with `#[const_trait]` on traits") } else { return; }; diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 04d6e9f205a..996ca66de0e 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -13,7 +13,6 @@ use rustc_hir as hir; 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::>() - .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 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { 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) { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e4c52f8d25a..16162f1cc89 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -505,6 +505,7 @@ symbols! { 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, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 8d04b8816ff..8056198b20c 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -5,7 +5,7 @@ use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{ self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, }; -use rustc_span::{sym, Span}; +use rustc_span::Span; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -153,7 +153,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) => + if tcx.is_const_default_method(def_id) => { hir::Constness::Const } diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 0444a9575d1..70f3fe853d9 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -107,6 +107,7 @@ use crate::marker::Destruct; #[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, diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 74328a3607d..f281e8429c6 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -214,6 +214,7 @@ use self::Ordering::*; append_const_msg, ) )] +#[cfg_attr(not(bootstrap), const_trait)] #[rustc_diagnostic_item = "PartialEq"] pub trait PartialEq { /// This method tests for `self` and `other` values to be equal, and is used @@ -226,7 +227,7 @@ pub trait PartialEq { #[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 @@ impl PartialOrd for Ordering { append_const_msg, ) )] +#[cfg_attr(not(bootstrap), const_trait)] #[rustc_diagnostic_item = "PartialOrd"] pub trait PartialOrd: PartialEq { /// This method returns an ordering between `self` and `other` values if one exists. @@ -1096,7 +1098,7 @@ pub trait PartialOrd: PartialEq { #[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 @@ pub trait PartialOrd: PartialEq { #[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 @@ pub trait PartialOrd: PartialEq { #[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 @@ pub trait PartialOrd: PartialEq { #[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)) } diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs index f9173feeeec..ec70a69ff10 100644 --- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs +++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs @@ -16,12 +16,12 @@ pub struct S(T); // @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 { // @!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() where Option: ~const Clone + ~const Destruct, diff --git a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs index be73ec09ceb..01ac74feff7 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs @@ -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() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr index fcb7e15b205..b18f33218c2 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr @@ -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 diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index 34934d1e01d..e73082c1127 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -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); } diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs index dd509931766..f66d63da693 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs @@ -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 @@ impl const std::ops::Add for i32 { //~ ERROR type annotations needed } } -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 @@ impl std::ops::Add for Int { //~ ERROR type annotations needed } } -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; diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 9fd82196e79..f515ec198ad 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -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: aborting due to 2 previous errors -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 - -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`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs index 3c82fe1ad6c..0b981d1621e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs @@ -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(); } diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs b/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs index c0f90c116e4..bde8bf20f46 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs @@ -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 diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs index 17c88e44296..d27291231fb 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs @@ -5,8 +5,8 @@ impl Tr for () {} const fn foo() 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 diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs index be2f3f6d623..d798516ff70 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs @@ -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 diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index cf357971951..8bb7f014103 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -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() | ^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs index 7f6d86d3375..1b45cd9aab9 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-with-staged-api.rs @@ -9,8 +9,8 @@ #![feature(const_trait_impl)] #![stable(since = "1", feature = "foo")] +#[const_trait] trait Tr { - #[default_method_body_is_const] fn a() {} } diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs index eba8b665ceb..6df9696f2cb 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs @@ -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() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 4ec6f929ffc..6c6ca9f5db8 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -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`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs index 2e4664714a7..ae81421e9e1 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs @@ -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) {} } } } diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs index f4a5d0133ce..334fc4cb847 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -37,8 +37,8 @@ impl const FromResidual for 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? diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs index e47c5c7bd66..b7cf9a13b79 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs @@ -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 { ::bar() * 6 }