Skip to content

Commit 2022cce

Browse files
Edvin BryntessonBryntet
authored andcommitted
Port #[rustc_legacy_const_generics] to use attribute parser
Signed-off-by: Edvin Bryntesson <edvin@brynte.me>
1 parent 430d829 commit 2022cce

File tree

13 files changed

+207
-138
lines changed

13 files changed

+207
-138
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
114114
}
115115
ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
116116
ExprKind::Call(f, args) => {
117-
if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
117+
if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f, self.tcx)
118+
{
118119
self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args)
119120
} else {
120121
let f = self.lower_expr(f);

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,14 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4747
use rustc_data_structures::sync::spawn;
4848
use rustc_data_structures::tagged_ptr::TaggedRef;
4949
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};
50+
use rustc_hir::attrs::AttributeKind;
5051
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5152
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
5253
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
5354
use rustc_hir::lints::DelayedLint;
5455
use rustc_hir::{
5556
self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
56-
LifetimeSyntax, ParamName, Target, TraitCandidate,
57+
LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,
5758
};
5859
use rustc_index::{Idx, IndexSlice, IndexVec};
5960
use rustc_macros::extension;
@@ -236,29 +237,28 @@ impl SpanLowerer {
236237

237238
#[extension(trait ResolverAstLoweringExt)]
238239
impl ResolverAstLowering {
239-
fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
240-
if let ExprKind::Path(None, path) = &expr.kind {
241-
// Don't perform legacy const generics rewriting if the path already
242-
// has generic arguments.
243-
if path.segments.last().unwrap().args.is_some() {
244-
return None;
245-
}
246-
247-
if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? {
248-
// We only support cross-crate argument rewriting. Uses
249-
// within the same crate should be updated to use the new
250-
// const generics style.
251-
if def_id.is_local() {
252-
return None;
253-
}
240+
fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'_>) -> Option<Vec<usize>> {
241+
let ExprKind::Path(None, path) = &expr.kind else {
242+
return None;
243+
};
254244

255-
if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
256-
return v.clone();
257-
}
258-
}
245+
// Don't perform legacy const generics rewriting if the path already
246+
// has generic arguments.
247+
if path.segments.last().unwrap().args.is_some() {
248+
return None;
259249
}
260250

261-
None
251+
let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;
252+
253+
// We only support cross-crate argument rewriting. Uses
254+
// within the same crate should be updated to use the new
255+
// const generics style.
256+
if def_id.is_local() {
257+
return None;
258+
}
259+
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes)
260+
.map(|fn_indexes|fn_indexes.iter().map(|(num,_)| *num as usize)
261+
.collect())
262262
}
263263

264264
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
2+
13
use super::prelude::*;
24
use super::util::parse_single_integer;
35

@@ -76,3 +78,52 @@ impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser
7678
Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?))
7779
}
7880
}
81+
82+
pub(crate) struct RustcLegacyConstGenericsParser;
83+
84+
impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {
85+
const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics];
86+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
87+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
88+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
89+
const TEMPLATE: AttributeTemplate = template!(List: &["N"]);
90+
91+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
92+
let meta_items = match args {
93+
ArgParser::List(meta_items) => meta_items,
94+
ArgParser::NoArgs => {
95+
cx.expected_at_least_one_argument(cx.attr_span);
96+
return None;
97+
}
98+
ArgParser::NameValue(_) => {
99+
cx.expected_list(args.span()?);
100+
return None;
101+
}
102+
};
103+
104+
let mut parsed_indexes = ThinVec::new();
105+
106+
for possible_index in meta_items.mixed() {
107+
if let MetaItemOrLitParser::Lit(MetaItemLit {
108+
kind: LitKind::Int(index, LitIntType::Unsuffixed),
109+
..
110+
}) = possible_index
111+
{
112+
parsed_indexes.push((index.0, possible_index.span()));
113+
} else {
114+
cx.expected_integer_literal(possible_index.span());
115+
return None;
116+
}
117+
}
118+
119+
if parsed_indexes.is_empty() {
120+
cx.expected_at_least_one_argument(args.span()?);
121+
return None;
122+
}
123+
124+
Some(AttributeKind::RustcLegacyConstGenerics {
125+
fn_indexes: parsed_indexes,
126+
attr_span: cx.attr_span,
127+
})
128+
}
129+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ use crate::attributes::proc_macro_attrs::{
5959
use crate::attributes::prototype::CustomMirParser;
6060
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
6161
use crate::attributes::rustc_internal::{
62-
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser,
63-
RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
62+
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
63+
RustcLegacyConstGenericsParser, RustcMainParser, RustcObjectLifetimeDefaultParser,
64+
RustcSimdMonomorphizeLaneLimitParser,
6465
};
6566
use crate::attributes::semantics::MayDangleParser;
6667
use crate::attributes::stability::{
@@ -208,6 +209,7 @@ attribute_parsers!(
208209
Single<RustcForceInlineParser>,
209210
Single<RustcLayoutScalarValidRangeEndParser>,
210211
Single<RustcLayoutScalarValidRangeStartParser>,
212+
Single<RustcLegacyConstGenericsParser>,
211213
Single<RustcObjectLifetimeDefaultParser>,
212214
Single<RustcSimdMonomorphizeLaneLimitParser>,
213215
Single<SanitizeParser>,

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,8 @@ pub enum AttributeKind {
842842

843843
/// Represents `#[rustc_layout_scalar_valid_range_start]`.
844844
RustcLayoutScalarValidRangeStart(Box<u128>, Span),
845+
/// Represents `#[rustc_legacy_const_generics]`
846+
RustcLegacyConstGenerics { fn_indexes: ThinVec<(u128, Span)>, attr_span: Span },
845847

846848
/// Represents `#[rustc_main]`.
847849
RustcMain,

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ impl AttributeKind {
8989
RustcCoherenceIsCore(..) => No,
9090
RustcLayoutScalarValidRangeEnd(..) => Yes,
9191
RustcLayoutScalarValidRangeStart(..) => Yes,
92+
RustcLegacyConstGenerics { .. } => Yes,
9293
RustcMain => No,
9394
RustcObjectLifetimeDefault => No,
9495
RustcPassIndirectlyInNonRusticAbis(..) => No,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc_ast::AttrVec;
2929
use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree};
3030
use rustc_ast::node_id::NodeMap;
3131
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
32-
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
32+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
3333
use rustc_data_structures::intern::Interned;
3434
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3535
use rustc_data_structures::steal::Steal;
@@ -194,8 +194,6 @@ pub struct ResolverGlobalCtxt {
194194
/// This struct is meant to be consumed by lowering.
195195
#[derive(Debug)]
196196
pub struct ResolverAstLowering {
197-
pub legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
198-
199197
/// Resolutions for nodes that have a single resolution.
200198
pub partial_res_map: NodeMap<hir::def::PartialRes>,
201199
/// Resolutions for import nodes, which have multiple resolutions in different namespaces.

compiler/rustc_passes/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,6 @@ passes_rustc_legacy_const_generics_index_exceed =
451451
*[other] arguments
452452
}
453453
454-
passes_rustc_legacy_const_generics_index_negative =
455-
arguments should be non-negative integers
456-
457454
passes_rustc_legacy_const_generics_only =
458455
#[rustc_legacy_const_generics] functions must only have const generics
459456
.label = non-const generic parameter

compiler/rustc_passes/src/check_attr.rs

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use std::collections::hash_map::Entry;
1010
use std::slice;
1111

1212
use rustc_abi::{Align, ExternAbi, Size};
13-
use rustc_ast::{AttrStyle, LitKind, MetaItemKind, ast};
13+
use rustc_ast::{AttrStyle, MetaItemKind, ast};
1414
use rustc_attr_parsing::{AttributeParser, Late};
1515
use rustc_data_structures::fx::FxHashMap;
16+
use rustc_data_structures::thin_vec::ThinVec;
1617
use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
1718
use rustc_feature::{
1819
ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP,
@@ -211,6 +212,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
211212
Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => {
212213
self.check_macro_export(hir_id, *span, target)
213214
},
215+
Attribute::Parsed(AttributeKind::RustcLegacyConstGenerics{attr_span, fn_indexes}) => {
216+
self.check_rustc_legacy_const_generics(hir_id, span, target, item, *attr_span, fn_indexes)
217+
},
214218
Attribute::Parsed(AttributeKind::Doc(attr)) => self.check_doc_attrs(attr, hir_id, target),
215219
Attribute::Parsed(
216220
AttributeKind::BodyStability { .. }
@@ -300,9 +304,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
300304
[sym::rustc_never_returns_null_ptr, ..] => {
301305
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
302306
}
303-
[sym::rustc_legacy_const_generics, ..] => {
304-
self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)
305-
}
306307
[sym::rustc_lint_query_instability, ..] => {
307308
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
308309
}
@@ -1178,26 +1179,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
11781179
fn check_rustc_legacy_const_generics(
11791180
&self,
11801181
hir_id: HirId,
1181-
attr: &Attribute,
11821182
span: Span,
11831183
target: Target,
11841184
item: Option<ItemLike<'_>>,
1185+
attr_span: Span,
1186+
index_list: &ThinVec<(u128, Span)>,
11851187
) {
11861188
let is_function = matches!(target, Target::Fn);
11871189
if !is_function {
11881190
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
1189-
attr_span: attr.span(),
1191+
attr_span,
11901192
defn_span: span,
11911193
on_crate: hir_id == CRATE_HIR_ID,
11921194
});
11931195
return;
11941196
}
11951197

1196-
let Some(list) = attr.meta_item_list() else {
1197-
// The attribute form is validated on AST.
1198-
return;
1199-
};
1200-
12011198
let Some(ItemLike::Item(Item {
12021199
kind: ItemKind::Fn { sig: FnSig { decl, .. }, generics, .. },
12031200
..
@@ -1211,42 +1208,32 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
12111208
hir::GenericParamKind::Const { .. } => {}
12121209
_ => {
12131210
self.dcx().emit_err(errors::RustcLegacyConstGenericsOnly {
1214-
attr_span: attr.span(),
1211+
attr_span,
12151212
param_span: param.span,
12161213
});
12171214
return;
12181215
}
12191216
}
12201217
}
12211218

1222-
if list.len() != generics.params.len() {
1219+
if index_list.len() != generics.params.len() {
12231220
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndex {
1224-
attr_span: attr.span(),
1221+
attr_span,
12251222
generics_span: generics.span,
12261223
});
12271224
return;
12281225
}
12291226

12301227
let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
1231-
let mut invalid_args = vec![];
1232-
for meta in list {
1233-
if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) {
1234-
if *val >= arg_count {
1235-
let span = meta.span();
1236-
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed {
1237-
span,
1238-
arg_count: arg_count as usize,
1239-
});
1240-
return;
1241-
}
1242-
} else {
1243-
invalid_args.push(meta.span());
1228+
for (index, span) in index_list {
1229+
if *index >= arg_count {
1230+
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed {
1231+
span: *span,
1232+
arg_count: arg_count as usize,
1233+
});
1234+
return;
12441235
}
12451236
}
1246-
1247-
if !invalid_args.is_empty() {
1248-
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexNegative { invalid_args });
1249-
}
12501237
}
12511238

12521239
/// Helper function for checking that the provided attribute is only applied to a function or

compiler/rustc_passes/src/errors.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,6 @@ pub(crate) struct RustcLegacyConstGenericsIndexExceed {
290290
pub arg_count: usize,
291291
}
292292

293-
#[derive(Diagnostic)]
294-
#[diag(passes_rustc_legacy_const_generics_index_negative)]
295-
pub(crate) struct RustcLegacyConstGenericsIndexNegative {
296-
#[primary_span]
297-
pub invalid_args: Vec<Span>,
298-
}
299-
300293
#[derive(Diagnostic)]
301294
#[diag(passes_rustc_dirty_clean)]
302295
pub(crate) struct RustcDirtyClean {

0 commit comments

Comments
 (0)