Skip to content

Commit 9c4061c

Browse files
committed
Port #[const_trait] to the new attribute system
1 parent 0c4fa26 commit 9c4061c

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
@@ -36,7 +36,7 @@ use crate::attributes::semantics::MayDangleParser;
3636
use crate::attributes::stability::{
3737
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
3838
};
39-
use crate::attributes::traits::SkipDuringMethodDispatchParser;
39+
use crate::attributes::traits::{ConstTraitParser, SkipDuringMethodDispatchParser};
4040
use crate::attributes::transparency::TransparencyParser;
4141
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
4242
use crate::parser::{ArgParser, MetaItemParser, PathParser};
@@ -140,6 +140,7 @@ attribute_parsers!(
140140
Single<WithoutArgs<ColdParser>>,
141141
Single<WithoutArgs<ConstContinueParser>>,
142142
Single<WithoutArgs<ConstStabilityIndirectParser>>,
143+
Single<WithoutArgs<ConstTraitParser>>,
143144
Single<WithoutArgs<LoopMatchParser>>,
144145
Single<WithoutArgs<MayDangleParser>>,
145146
Single<WithoutArgs<NoImplicitPreludeParser>>,

compiler/rustc_hir_analysis/src/collect.rs

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

859+
let attrs = tcx.get_all_attrs(def_id);
859860
// Only regular traits can be const.
860-
let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) {
861+
let constness = if !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) {
861862
hir::Constness::Const
862863
} else {
863864
hir::Constness::NotConst
864865
};
865866

866-
let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
867+
let paren_sugar = attrs.iter().any(|attr| attr.has_name(sym::rustc_paren_sugar));
867868
if paren_sugar && !tcx.features().unboxed_closures() {
868869
tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span });
869870
}
870871

871872
// Only regular traits can be marker.
872-
let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker);
873+
let is_marker = !is_alias && attrs.iter().any(|attr| attr.has_name(sym::marker));
873874

874-
let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive);
875-
let is_fundamental = tcx.has_attr(def_id, sym::fundamental);
875+
let rustc_coinductive = attrs.iter().any(|attr| attr.has_name(sym::rustc_coinductive));
876+
let is_fundamental = attrs.iter().any(|attr| attr.has_name(sym::fundamental));
876877

877878
let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!(
878-
tcx.get_all_attrs(def_id),
879-
AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice]
879+
attrs,
880+
AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: _ } => [*array, *boxed_slice]
880881
)
881882
.unwrap_or([false; 2]);
882883

883-
let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
884-
ty::trait_def::TraitSpecializationKind::Marker
885-
} else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
886-
ty::trait_def::TraitSpecializationKind::AlwaysApplicable
887-
} else {
888-
ty::trait_def::TraitSpecializationKind::None
889-
};
890-
let must_implement_one_of = tcx
891-
.get_attr(def_id, sym::rustc_must_implement_one_of)
884+
let specialization_kind =
885+
if attrs.iter().any(|attr| attr.has_name(sym::rustc_unsafe_specialization_marker)) {
886+
ty::trait_def::TraitSpecializationKind::Marker
887+
} else if attrs.iter().any(|attr| attr.has_name(sym::rustc_specialization_trait)) {
888+
ty::trait_def::TraitSpecializationKind::AlwaysApplicable
889+
} else {
890+
ty::trait_def::TraitSpecializationKind::None
891+
};
892+
let must_implement_one_of = attrs
893+
.iter()
894+
.find(|attr| attr.has_name(sym::rustc_must_implement_one_of))
892895
// Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]`
893896
// and that they are all identifiers
894897
.and_then(|attr| match attr.meta_item_list() {
@@ -962,8 +965,9 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
962965
no_dups.then_some(list)
963966
});
964967

965-
let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl);
966-
let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
968+
let deny_explicit_impl = attrs.iter().any(|attr| attr.has_name(sym::rustc_deny_explicit_impl));
969+
let implement_via_object =
970+
!attrs.iter().any(|attr| attr.has_name(sym::rustc_do_not_implement_via_object));
967971

968972
ty::TraitDef {
969973
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, .. }) => {
@@ -283,7 +283,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
283283
| [sym::rustc_must_implement_one_of, ..]
284284
| [sym::rustc_deny_explicit_impl, ..]
285285
| [sym::rustc_do_not_implement_via_object, ..]
286-
| [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target),
286+
=> self.check_must_be_applied_to_trait(attr.span(), span, target),
287287
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
288288
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
289289
[sym::rustc_allow_incoherent_impl, ..] => {

0 commit comments

Comments
 (0)