Skip to content

Commit 257f065

Browse files
fee1-deadoli-obk
authored andcommitted
Remove #[default..] and add #[const_trait]
1 parent f558990 commit 257f065

30 files changed

+74
-250
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
277277
// sensitive check here. But we can at least rule out functions that are not const
278278
// at all.
279279
if !ecx.tcx.is_const_fn_raw(def.did) {
280-
// allow calling functions marked with #[default_method_body_is_const].
281-
if !ecx.tcx.has_attr(def.did, sym::default_method_body_is_const) {
280+
// allow calling functions inside a trait marked with #[const_trait].
281+
if !matches!(ecx.tcx.trait_of_item(def.did), Some(trait_id) if ecx.tcx.has_attr(trait_id, sym::const_trait))
282+
{
282283
// We certainly do *not* want to actually call the fn
283284
// though, so be sure we return here.
284285
throw_unsup_format!("calling non-const function `{}`", instance)

compiler/rustc_const_eval/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Rust MIR: a lowered representation of Rust.
99
#![feature(control_flow_enum)]
1010
#![feature(decl_macro)]
1111
#![feature(exact_size_is_empty)]
12+
#![feature(let_chains)]
1213
#![feature(let_else)]
1314
#![feature(map_try_insert)]
1415
#![feature(min_specialization)]

compiler/rustc_const_eval/src/transform/check_consts/check.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -774,13 +774,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
774774
}
775775
}
776776
_ if !tcx.is_const_fn_raw(callee) => {
777-
// At this point, it is only legal when the caller is marked with
778-
// #[default_method_body_is_const], and the callee is in the same
779-
// trait.
780-
let callee_trait = tcx.trait_of_item(callee);
781-
if callee_trait.is_some()
782-
&& tcx.has_attr(caller.to_def_id(), sym::default_method_body_is_const)
783-
&& callee_trait == tcx.trait_of_item(caller)
777+
// At this point, it is only legal when the caller is in a trait
778+
// marked with #[const_trait], and the callee is in the same trait.
779+
if let Some(callee_trait) = tcx.trait_of_item(callee)
780+
&& tcx.has_attr(callee_trait, sym::const_trait)
781+
&& Some(callee_trait) == tcx.trait_of_item(caller)
784782
// Can only call methods when it's `<Self as TheTrait>::f`.
785783
&& tcx.types.self_param == substs.type_at(0)
786784
{
@@ -875,7 +873,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
875873

876874
if !tcx.is_const_fn_raw(callee) {
877875
if tcx.trait_of_item(callee).is_some() {
878-
if tcx.has_attr(callee, sym::default_method_body_is_const) {
876+
if let Some(callee_trait) = tcx.trait_of_item(callee) && tcx.has_attr(callee_trait, sym::const_trait) {
879877
// To get to here we must have already found a const impl for the
880878
// trait, but for it to still be non-const can be that the impl is
881879
// using default method bodies.

compiler/rustc_const_eval/src/transform/check_consts/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ pub fn rustc_allow_const_fn_unstable(
8484
// functions are subject to more stringent restrictions than "const-unstable" functions: They
8585
// cannot use unstable features and can only call other "const-stable" functions.
8686
pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
87-
// A default body marked const is not const-stable because const
87+
// A default body in a `#[const_trait]` is not const-stable because const
8888
// trait fns currently cannot be const-stable. We shouldn't
8989
// restrict default bodies to only call const-stable functions.
90-
if tcx.has_attr(def_id, sym::default_method_body_is_const) {
90+
if let Some(trait_id) = tcx.trait_of_item(def_id) && tcx.has_attr(trait_id, sym::const_trait) {
9191
return false;
9292
}
9393

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
473473
),
474474
// RFC 2632
475475
gated!(
476-
default_method_body_is_const, Normal, template!(Word), WarnFollowing, const_trait_impl,
477-
"`default_method_body_is_const` is a temporary placeholder for declaring default bodies \
478-
as `const`, which may be removed or renamed in the future."
476+
const_trait, Normal, template!(Word), WarnFollowing, const_trait_impl,
477+
"`const` is a temporary placeholder for marking a trait that is suitable for `const` \
478+
`impls` and all default bodies as `const`, which may be removed or renamed in the \
479+
future."
479480
),
480481
// lang-team MCP 147
481482
gated!(

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -891,9 +891,11 @@ fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) {
891891
let needs_inline = (generics.requires_monomorphization(tcx)
892892
|| tcx.codegen_fn_attrs(def_id).requests_inline())
893893
&& tcx.sess.opts.output_types.should_codegen();
894-
// The function has a `const` modifier or is annotated with `default_method_body_is_const`.
895-
let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id())
896-
|| tcx.has_attr(def_id.to_def_id(), sym::default_method_body_is_const);
894+
// The function has a `const` modifier or is in a `#[const_trait]`.
895+
let mut is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id());
896+
if let Some(trait_) = tcx.trait_of_item(def_id.to_def_id()) {
897+
is_const_fn = is_const_fn || tcx.has_attr(trait_, sym::const_trait);
898+
}
897899
let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
898900
(is_const_fn, needs_inline || always_encode_mir)
899901
}

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,7 @@ impl<'hir> Map<'hir> {
494494
BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
495495
ConstContext::ConstFn
496496
}
497-
BodyOwnerKind::Fn
498-
if self.tcx.has_attr(def_id.to_def_id(), sym::default_method_body_is_const) =>
499-
{
497+
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)) => {
500498
ConstContext::ConstFn
501499
}
502500
BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ impl CheckAttrVisitor<'_> {
121121
| sym::rustc_if_this_changed
122122
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
123123
sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
124-
sym::default_method_body_is_const => {
125-
self.check_default_method_body_is_const(attr, span, target)
126-
}
124+
sym::const_trait => self.check_const_trait(attr, span, target),
127125
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
128126
sym::must_use => self.check_must_use(hir_id, &attr, span, target),
129127
sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target),
@@ -2081,23 +2079,14 @@ impl CheckAttrVisitor<'_> {
20812079
}
20822080
}
20832081

2084-
/// default_method_body_is_const should only be applied to trait methods with default bodies.
2085-
fn check_default_method_body_is_const(
2086-
&self,
2087-
attr: &Attribute,
2088-
span: Span,
2089-
target: Target,
2090-
) -> bool {
2082+
/// `#[const_trait]` only applies to traits.
2083+
fn check_const_trait(&self, attr: &Attribute, _span: Span, target: Target) -> bool {
20912084
match target {
2092-
Target::Method(MethodKind::Trait { body: true }) => true,
2085+
Target::Trait => true,
20932086
_ => {
20942087
self.tcx
20952088
.sess
2096-
.struct_span_err(
2097-
attr.span,
2098-
"attribute should be applied to a trait method with body",
2099-
)
2100-
.span_label(span, "not a trait method or missing a body")
2089+
.struct_span_err(attr.span, "attribute should be applied to a trait")
21012090
.emit();
21022091
false
21032092
}
@@ -2191,6 +2180,8 @@ impl CheckAttrVisitor<'_> {
21912180
"attribute `{}` without any lints has no effect",
21922181
attr.name_or_empty()
21932182
)
2183+
} else if attr.name_or_empty() == sym::default_method_body_is_const {
2184+
format!("`default_method_body_is_const` has been removed")
21942185
} else {
21952186
return;
21962187
};

compiler/rustc_passes/src/check_const.rs

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_hir as hir;
1313
use rustc_hir::def_id::LocalDefId;
1414
use rustc_hir::intravisit::{self, Visitor};
1515
use rustc_middle::hir::nested_filter;
16-
use rustc_middle::ty;
1716
use rustc_middle::ty::query::Providers;
1817
use rustc_middle::ty::TyCtxt;
1918
use rustc_session::parse::feature_err;
@@ -64,66 +63,6 @@ pub(crate) fn provide(providers: &mut Providers) {
6463
*providers = Providers { check_mod_const_bodies, ..*providers };
6564
}
6665

67-
fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
68-
let _: Option<_> = try {
69-
if let hir::ItemKind::Impl(ref imp) = item.kind && let hir::Constness::Const = imp.constness {
70-
let trait_def_id = imp.of_trait.as_ref()?.trait_def_id()?;
71-
let ancestors = tcx
72-
.trait_def(trait_def_id)
73-
.ancestors(tcx, item.def_id.to_def_id())
74-
.ok()?;
75-
let mut to_implement = Vec::new();
76-
77-
for trait_item in tcx.associated_items(trait_def_id).in_definition_order()
78-
{
79-
if let ty::AssocItem {
80-
kind: ty::AssocKind::Fn,
81-
defaultness,
82-
def_id: trait_item_id,
83-
..
84-
} = *trait_item
85-
{
86-
// we can ignore functions that do not have default bodies:
87-
// if those are unimplemented it will be caught by typeck.
88-
if !defaultness.has_value()
89-
|| tcx
90-
.has_attr(trait_item_id, sym::default_method_body_is_const)
91-
{
92-
continue;
93-
}
94-
95-
let is_implemented = ancestors
96-
.leaf_def(tcx, trait_item_id)
97-
.map(|node_item| !node_item.defining_node.is_from_trait())
98-
.unwrap_or(false);
99-
100-
if !is_implemented {
101-
to_implement.push(trait_item_id);
102-
}
103-
}
104-
}
105-
106-
// all nonconst trait functions (not marked with #[default_method_body_is_const])
107-
// must be implemented
108-
if !to_implement.is_empty() {
109-
let not_implemented = to_implement
110-
.into_iter()
111-
.map(|did| tcx.item_name(did).to_string())
112-
.collect::<Vec<_>>()
113-
.join("`, `");
114-
tcx
115-
.sess
116-
.struct_span_err(
117-
item.span,
118-
"const trait implementations may not use non-const default functions",
119-
)
120-
.note(&format!("`{}` not implemented", not_implemented))
121-
.emit();
122-
}
123-
}
124-
};
125-
}
126-
12766
#[derive(Copy, Clone)]
12867
struct CheckConstVisitor<'tcx> {
12968
tcx: TyCtxt<'tcx>,
@@ -254,7 +193,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
254193

255194
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
256195
intravisit::walk_item(self, item);
257-
check_item(self.tcx, item);
258196
}
259197

260198
fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ symbols! {
504504
const_raw_ptr_deref,
505505
const_raw_ptr_to_usize_cast,
506506
const_refs_to_cell,
507+
const_trait,
507508
const_trait_bound_opt_out,
508509
const_trait_impl,
509510
const_transmute,

compiler/rustc_ty_utils/src/ty.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
152152

153153
let constness = match hir_id {
154154
Some(hir_id) => match tcx.hir().get(hir_id) {
155-
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
156-
if tcx.has_attr(def_id, sym::default_method_body_is_const) =>
157-
{
155+
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)) => {
158156
hir::Constness::Const
159157
}
160158

library/core/src/clone.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ use crate::marker::Destruct;
107107
#[lang = "clone"]
108108
#[rustc_diagnostic_item = "Clone"]
109109
#[rustc_trivial_field_reads]
110+
#[cfg_attr(not(bootstrap), const_trait)]
110111
pub trait Clone: Sized {
111112
/// Returns a copy of the value.
112113
///
@@ -129,7 +130,7 @@ pub trait Clone: Sized {
129130
/// allocations.
130131
#[inline]
131132
#[stable(feature = "rust1", since = "1.0.0")]
132-
#[default_method_body_is_const]
133+
#[cfg_attr(bootstrap, default_method_body_is_const)]
133134
fn clone_from(&mut self, source: &Self)
134135
where
135136
Self: ~const Destruct,

library/core/src/cmp.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ use self::Ordering::*;
214214
append_const_msg,
215215
)
216216
)]
217+
#[cfg_attr(not(bootstrap), const_trait)]
217218
#[rustc_diagnostic_item = "PartialEq"]
218219
pub trait PartialEq<Rhs: ?Sized = Self> {
219220
/// This method tests for `self` and `other` values to be equal, and is used
@@ -226,7 +227,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
226227
#[inline]
227228
#[must_use]
228229
#[stable(feature = "rust1", since = "1.0.0")]
229-
#[default_method_body_is_const]
230+
#[cfg_attr(bootstrap, default_method_body_is_const)]
230231
fn ne(&self, other: &Rhs) -> bool {
231232
!self.eq(other)
232233
}
@@ -1053,6 +1054,7 @@ impl PartialOrd for Ordering {
10531054
append_const_msg,
10541055
)
10551056
)]
1057+
#[cfg_attr(not(bootstrap), const_trait)]
10561058
#[rustc_diagnostic_item = "PartialOrd"]
10571059
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
10581060
/// 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> {
10961098
#[inline]
10971099
#[must_use]
10981100
#[stable(feature = "rust1", since = "1.0.0")]
1099-
#[default_method_body_is_const]
1101+
#[cfg_attr(bootstrap, default_method_body_is_const)]
11001102
fn lt(&self, other: &Rhs) -> bool {
11011103
matches!(self.partial_cmp(other), Some(Less))
11021104
}
@@ -1116,7 +1118,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
11161118
#[inline]
11171119
#[must_use]
11181120
#[stable(feature = "rust1", since = "1.0.0")]
1119-
#[default_method_body_is_const]
1121+
#[cfg_attr(bootstrap, default_method_body_is_const)]
11201122
fn le(&self, other: &Rhs) -> bool {
11211123
// Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
11221124
// FIXME: The root cause was fixed upstream in LLVM with:
@@ -1139,7 +1141,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
11391141
#[inline]
11401142
#[must_use]
11411143
#[stable(feature = "rust1", since = "1.0.0")]
1142-
#[default_method_body_is_const]
1144+
#[cfg_attr(bootstrap, default_method_body_is_const)]
11431145
fn gt(&self, other: &Rhs) -> bool {
11441146
matches!(self.partial_cmp(other), Some(Greater))
11451147
}
@@ -1159,7 +1161,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
11591161
#[inline]
11601162
#[must_use]
11611163
#[stable(feature = "rust1", since = "1.0.0")]
1162-
#[default_method_body_is_const]
1164+
#[cfg_attr(bootstrap, default_method_body_is_const)]
11631165
fn ge(&self, other: &Rhs) -> bool {
11641166
matches!(self.partial_cmp(other), Some(Greater | Equal))
11651167
}

src/test/rustdoc/rfc-2632-const-trait-impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ pub struct S<T>(T);
1616
// @has - '//pre[@class="rust trait"]/code/a[@class="trait"]' 'Clone'
1717
// @!has - '//pre[@class="rust trait"]/code/span[@class="where"]' '~const'
1818
// @has - '//pre[@class="rust trait"]/code/span[@class="where"]' ': Clone'
19+
#[const_trait]
1920
pub trait Tr<T> {
2021
// @!has - '//div[@id="method.a"]/h4[@class="code-header"]' '~const'
2122
// @has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
2223
// @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
2324
// @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
24-
#[default_method_body_is_const]
2525
fn a<A: ~const Clone + ~const Destruct>()
2626
where
2727
Option<A>: ~const Clone + ~const Destruct,
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
#![feature(const_trait_impl)]
22

3-
#[default_method_body_is_const] //~ ERROR attribute should be applied
3+
#[const_trait]
44
trait A {
5-
#[default_method_body_is_const] //~ ERROR attribute should be applied
6-
fn no_body(self);
7-
8-
#[default_method_body_is_const]
9-
fn correct_use(&self) {}
5+
#[const_trait] //~ ERROR attribute should be applied
6+
fn foo(self);
107
}
118

12-
#[default_method_body_is_const] //~ ERROR attribute should be applied
9+
#[const_trait] //~ ERROR attribute should be applied
1310
fn main() {}

0 commit comments

Comments
 (0)