Skip to content

Commit 0c3c8d2

Browse files
committed
add #[rustc_non_const_trait_method]
1 parent cd7ad97 commit 0c3c8d2

14 files changed

Lines changed: 104 additions & 6 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,15 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcHasIncoherentInherentImplsParse
320320
]);
321321
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls;
322322
}
323+
324+
pub(crate) struct RustcNonConstTraitMethodParser;
325+
326+
impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
327+
const PATH: &'static [Symbol] = &[sym::rustc_non_const_trait_method];
328+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
329+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
330+
Allow(Target::Method(MethodKind::Trait { body: true })),
331+
Allow(Target::Method(MethodKind::Trait { body: false })),
332+
]);
333+
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod;
334+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ use crate::attributes::rustc_internal::{
7474
RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser,
7575
RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser,
7676
RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
77-
RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
77+
RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser,
78+
RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
7879
RustcSimdMonomorphizeLaneLimitParser,
7980
};
8081
use crate::attributes::semantics::MayDangleParser;
@@ -286,6 +287,7 @@ attribute_parsers!(
286287
Single<WithoutArgs<RustcMainParser>>,
287288
Single<WithoutArgs<RustcNeverReturnsNullPointerParser>>,
288289
Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,
290+
Single<WithoutArgs<RustcNonConstTraitMethodParser>>,
289291
Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,
290292
Single<WithoutArgs<RustcShouldNotBeCalledOnConstItems>>,
291293
Single<WithoutArgs<SpecializationTraitParser>>,

compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,12 +778,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
778778
// than usual.
779779

780780
trace!("attempting to call a trait method");
781-
let trait_is_const = tcx.is_const_trait(trait_did);
781+
let is_const = tcx.constness(callee) == hir::Constness::Const;
782782

783783
// Only consider a trait to be const if the const conditions hold.
784784
// Otherwise, it's really misleading to call something "conditionally"
785785
// const when it's very obviously not conditionally const.
786-
if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
786+
if is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
787787
// Trait calls are always conditionally-const.
788788
self.check_op(ops::ConditionallyConstCall {
789789
callee,

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use rustc_hir::attrs::AttributeKind;
12
use rustc_hir::def_id::{DefId, LocalDefId};
3+
use rustc_hir::find_attr;
24
use rustc_hir::{
35
Constness, ExprKind, ForeignItemKind, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind,
46
Node, TraitItem, TraitItemKind, VariantData,
@@ -36,7 +38,13 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness {
3638
Constness::NotConst => tcx.constness(tcx.local_parent(def_id)),
3739
}
3840
}
39-
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(..), .. }) => tcx.trait_def(tcx.local_parent(def_id)).constness,
41+
Node::TraitItem(ti @ TraitItem { kind: TraitItemKind::Fn(..), .. }) => {
42+
if find_attr!(tcx.hir_attrs(ti.hir_id()), AttributeKind::RustcNonConstTraitMethod) {
43+
Constness::NotConst
44+
} else {
45+
tcx.trait_def(tcx.local_parent(def_id)).constness
46+
}
47+
}
4048
_ => {
4149
tcx.dcx().span_bug(
4250
tcx.def_span(def_id),

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
13351335
"`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \
13361336
the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`."
13371337
),
1338+
rustc_attr!(
1339+
rustc_non_const_trait_method, AttributeType::Normal, template!(Word),
1340+
ErrorFollowing, EncodeCrossCrate::No,
1341+
"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \
1342+
as non-const to allow large traits to easier transition to const"
1343+
),
13381344

13391345
BuiltinAttribute {
13401346
name: sym::rustc_diagnostic_item,

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,9 @@ pub enum AttributeKind {
963963
/// Represents `#[rustc_no_implicit_autorefs]`
964964
RustcNoImplicitAutorefs,
965965

966+
/// Represents `#[rustc_non_const_trait_method]`.
967+
RustcNonConstTraitMethod,
968+
966969
/// Represents `#[rustc_object_lifetime_default]`.
967970
RustcObjectLifetimeDefault,
968971

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ impl AttributeKind {
116116
RustcMustImplementOneOf { .. } => No,
117117
RustcNeverReturnsNullPointer => Yes,
118118
RustcNoImplicitAutorefs => Yes,
119+
RustcNonConstTraitMethod => No, // should be reported via other queries like `constness`
119120
RustcObjectLifetimeDefault => No,
120121
RustcPassIndirectlyInNonRusticAbis(..) => No,
121122
RustcScalableVector { .. } => Yes,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,8 +2180,11 @@ impl<'tcx> TyCtxt<'tcx> {
21802180
DefKind::Impl { of_trait: false } => {
21812181
self.constness(def_id) == hir::Constness::Const
21822182
}
2183-
DefKind::Impl { of_trait: true } | DefKind::Trait => {
2184-
self.is_conditionally_const(parent_def_id)
2183+
DefKind::Impl { of_trait: true } => {
2184+
self.constness(self.trait_item_of(def_id).unwrap()) == hir::Constness::Const && self.is_conditionally_const(parent_def_id)
2185+
}
2186+
DefKind::Trait => {
2187+
self.constness(def_id) == hir::Constness::Const && self.is_conditionally_const(parent_def_id)
21852188
}
21862189
_ => bug!("unexpected parent item of associated fn: {parent_def_id:?}"),
21872190
}

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
315315
| AttributeKind::RustcDumpPredicates
316316
| AttributeKind::RustcDumpDefParents
317317
| AttributeKind::RustcDumpVtable(..)
318+
| AttributeKind::RustcNonConstTraitMethod
318319
) => { /* do nothing */ }
319320
Attribute::Unparsed(attr_item) => {
320321
style = Some(attr_item.style);

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,7 @@ symbols! {
19901990
rustc_no_implicit_bounds,
19911991
rustc_no_mir_inline,
19921992
rustc_nonnull_optimization_guaranteed,
1993+
rustc_non_const_trait_method,
19931994
rustc_nounwind,
19941995
rustc_objc_class,
19951996
rustc_objc_selector,

0 commit comments

Comments
 (0)