Skip to content

Commit a9e9575

Browse files
committed
Port #[const_trait] to the new attribute system
1 parent f0b67dd commit a9e9575

File tree

8 files changed

+49
-33
lines changed

8 files changed

+49
-33
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ pub enum AttributeKind {
236236
/// Represents `#[rustc_const_stable_indirect]`.
237237
ConstStabilityIndirect,
238238

239+
/// Represents `#[const_trait]`.
240+
ConstTrait(Span),
241+
239242
/// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
240243
Deprecation { deprecation: Deprecation, span: Span },
241244

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ impl AttributeKind {
2323
ConstContinue(..) => No,
2424
ConstStability { .. } => Yes,
2525
ConstStabilityIndirect => No,
26+
ConstTrait(..) => No,
2627
Deprecation { .. } => Yes,
2728
DocComment { .. } => Yes,
2829
ExportName { .. } => Yes,

compiler/rustc_attr_parsing/src/attributes/traits.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ use core::mem;
22

33
use rustc_attr_data_structures::AttributeKind;
44
use rustc_feature::{AttributeTemplate, template};
5-
use rustc_span::{Symbol, sym};
5+
use rustc_span::{Span, Symbol, sym};
66

7-
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
7+
use crate::attributes::{
8+
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
9+
};
810
use crate::context::{AcceptContext, Stage};
911
use crate::parser::ArgParser;
1012

@@ -52,3 +54,10 @@ impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
5254
Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span })
5355
}
5456
}
57+
58+
pub(crate) struct ConstTraitParser;
59+
impl<S: Stage> NoArgsAttributeParser<S> for ConstTraitParser {
60+
const PATH: &[Symbol] = &[sym::const_trait];
61+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
62+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait;
63+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::attributes::semantics::MayDangleParser;
3737
use crate::attributes::stability::{
3838
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
3939
};
40-
use crate::attributes::traits::SkipDuringMethodDispatchParser;
40+
use crate::attributes::traits::{ConstTraitParser, SkipDuringMethodDispatchParser};
4141
use crate::attributes::transparency::TransparencyParser;
4242
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
4343
use crate::parser::{ArgParser, MetaItemParser, PathParser};
@@ -141,6 +141,7 @@ attribute_parsers!(
141141
Single<WithoutArgs<ColdParser>>,
142142
Single<WithoutArgs<ConstContinueParser>>,
143143
Single<WithoutArgs<ConstStabilityIndirectParser>>,
144+
Single<WithoutArgs<ConstTraitParser>>,
144145
Single<WithoutArgs<LoopMatchParser>>,
145146
Single<WithoutArgs<MayDangleParser>>,
146147
Single<WithoutArgs<NoImplicitPreludeParser>>,

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -852,39 +852,42 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
852852
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
853853
};
854854

855+
let attrs = tcx.get_all_attrs(def_id);
855856
// Only regular traits can be const.
856-
let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) {
857+
let constness = if !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) {
857858
hir::Constness::Const
858859
} else {
859860
hir::Constness::NotConst
860861
};
861862

862-
let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
863+
let paren_sugar = attrs.iter().any(|attr| attr.has_name(sym::rustc_paren_sugar));
863864
if paren_sugar && !tcx.features().unboxed_closures() {
864865
tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span });
865866
}
866867

867868
// Only regular traits can be marker.
868-
let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker);
869+
let is_marker = !is_alias && attrs.iter().any(|attr| attr.has_name(sym::marker));
869870

870-
let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive);
871-
let is_fundamental = tcx.has_attr(def_id, sym::fundamental);
871+
let rustc_coinductive = attrs.iter().any(|attr| attr.has_name(sym::rustc_coinductive));
872+
let is_fundamental = attrs.iter().any(|attr| attr.has_name(sym::fundamental));
872873

873874
let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!(
874-
tcx.get_all_attrs(def_id),
875-
AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice]
875+
attrs,
876+
AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: _ } => [*array, *boxed_slice]
876877
)
877878
.unwrap_or([false; 2]);
878879

879-
let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
880-
ty::trait_def::TraitSpecializationKind::Marker
881-
} else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
882-
ty::trait_def::TraitSpecializationKind::AlwaysApplicable
883-
} else {
884-
ty::trait_def::TraitSpecializationKind::None
885-
};
886-
let must_implement_one_of = tcx
887-
.get_attr(def_id, sym::rustc_must_implement_one_of)
880+
let specialization_kind =
881+
if attrs.iter().any(|attr| attr.has_name(sym::rustc_unsafe_specialization_marker)) {
882+
ty::trait_def::TraitSpecializationKind::Marker
883+
} else if attrs.iter().any(|attr| attr.has_name(sym::rustc_specialization_trait)) {
884+
ty::trait_def::TraitSpecializationKind::AlwaysApplicable
885+
} else {
886+
ty::trait_def::TraitSpecializationKind::None
887+
};
888+
let must_implement_one_of = attrs
889+
.iter()
890+
.find(|attr| attr.has_name(sym::rustc_must_implement_one_of))
888891
// Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]`
889892
// and that they are all identifiers
890893
.and_then(|attr| match attr.meta_item_list() {
@@ -958,8 +961,9 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
958961
no_dups.then_some(list)
959962
});
960963

961-
let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl);
962-
let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
964+
let deny_explicit_impl = attrs.iter().any(|attr| attr.has_name(sym::rustc_deny_explicit_impl));
965+
let implement_via_object =
966+
!attrs.iter().any(|attr| attr.has_name(sym::rustc_do_not_implement_via_object));
963967

964968
ty::TraitDef {
965969
def_id: def_id.to_def_id(),

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,21 +1785,18 @@ impl<'tcx> TyCtxt<'tcx> {
17851785
did: impl Into<DefId>,
17861786
attr: Symbol,
17871787
) -> impl Iterator<Item = &'tcx hir::Attribute> {
1788-
self.get_all_attrs(did).filter(move |a: &&hir::Attribute| a.has_name(attr))
1788+
self.get_all_attrs(did).iter().filter(move |a: &&hir::Attribute| a.has_name(attr))
17891789
}
17901790

17911791
/// Gets all attributes.
17921792
///
17931793
/// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching.
1794-
pub fn get_all_attrs(
1795-
self,
1796-
did: impl Into<DefId>,
1797-
) -> impl Iterator<Item = &'tcx hir::Attribute> {
1794+
pub fn get_all_attrs(self, did: impl Into<DefId>) -> &'tcx [hir::Attribute] {
17981795
let did: DefId = did.into();
17991796
if let Some(did) = did.as_local() {
1800-
self.hir_attrs(self.local_def_id_to_hir_id(did)).iter()
1797+
self.hir_attrs(self.local_def_id_to_hir_id(did))
18011798
} else {
1802-
self.attrs_for_def(did).iter()
1799+
self.attrs_for_def(did)
18031800
}
18041801
}
18051802

compiler/rustc_parse/src/validate_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ fn emit_malformed_attribute(
294294
| sym::rustc_confusables
295295
| sym::rustc_skip_during_method_dispatch
296296
| sym::rustc_pass_by_value
297+
| sym::const_trait
297298
| sym::repr
298299
| sym::align
299300
| sym::deprecated

compiler/rustc_passes/src/check_attr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
120120
for attr in attrs {
121121
let mut style = None;
122122
match attr {
123-
Attribute::Parsed(AttributeKind::SkipDuringMethodDispatch {
124-
span: attr_span,
125-
..
126-
}) => {
123+
Attribute::Parsed(
124+
AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. }
125+
| AttributeKind::ConstTrait(attr_span),
126+
) => {
127127
self.check_must_be_applied_to_trait(*attr_span, span, target);
128128
}
129129
Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
@@ -285,7 +285,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
285285
| [sym::rustc_must_implement_one_of, ..]
286286
| [sym::rustc_deny_explicit_impl, ..]
287287
| [sym::rustc_do_not_implement_via_object, ..]
288-
| [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target),
288+
=> self.check_must_be_applied_to_trait(attr.span(), span, target),
289289
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
290290
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
291291
[sym::rustc_allow_incoherent_impl, ..] => {

0 commit comments

Comments
 (0)