Skip to content

Commit b3ed8b9

Browse files
Auto merge of #150000 - Bryntet:brynte/parse_legacy_const_generic_args, r=<try>
Port `#[rustc_legacy_const_generics]` to use attribute parser try-job: dist-x86_64-linux-alt
2 parents 95a27ad + 4bd0e65 commit b3ed8b9

File tree

14 files changed

+227
-189
lines changed

14 files changed

+227
-189
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -237,25 +237,27 @@ impl SpanLowerer {
237237
#[extension(trait ResolverAstLoweringExt)]
238238
impl ResolverAstLowering {
239239
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-
}
240+
let ExprKind::Path(None, path) = &expr.kind else {
241+
return None;
242+
};
246243

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-
}
244+
// Don't perform legacy const generics rewriting if the path already
245+
// has generic arguments.
246+
if path.segments.last().unwrap().args.is_some() {
247+
return None;
248+
}
254249

255-
if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
256-
return v.clone();
257-
}
258-
}
250+
let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;
251+
252+
// We only support cross-crate argument rewriting. Uses
253+
// within the same crate should be updated to use the new
254+
// const generics style.
255+
if def_id.is_local() {
256+
return None;
257+
}
258+
259+
if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
260+
return v.clone();
259261
}
260262

261263
None

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 46 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
use crate::session_diagnostics::RustcScalableVectorCountOutOfRange;
@@ -41,6 +43,50 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEndParser
4143
}
4244
}
4345

46+
pub(crate) struct RustcLegacyConstGenericsParser;
47+
48+
impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {
49+
const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics];
50+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
51+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
52+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
53+
const TEMPLATE: AttributeTemplate = template!(List: &["N"]);
54+
55+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
56+
let ArgParser::List(meta_items) = args else {
57+
cx.expected_list(cx.attr_span, args);
58+
return None;
59+
};
60+
61+
let mut parsed_indexes = ThinVec::new();
62+
let mut errored = false;
63+
64+
for possible_index in meta_items.mixed() {
65+
if let MetaItemOrLitParser::Lit(MetaItemLit {
66+
kind: LitKind::Int(index, LitIntType::Unsuffixed),
67+
..
68+
}) = possible_index
69+
{
70+
parsed_indexes.push((index.0 as usize, possible_index.span()));
71+
} else {
72+
cx.expected_integer_literal(possible_index.span());
73+
errored = true;
74+
}
75+
}
76+
if errored {
77+
return None;
78+
} else if parsed_indexes.is_empty() {
79+
cx.expected_at_least_one_argument(args.span()?);
80+
return None;
81+
}
82+
83+
Some(AttributeKind::RustcLegacyConstGenerics {
84+
fn_indexes: parsed_indexes,
85+
attr_span: cx.attr_span,
86+
})
87+
}
88+
}
89+
4490
pub(crate) struct RustcObjectLifetimeDefaultParser;
4591

4692
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +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, RustcScalableVectorParser,
64-
RustcSimdMonomorphizeLaneLimitParser,
62+
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
63+
RustcLegacyConstGenericsParser, RustcMainParser, RustcObjectLifetimeDefaultParser,
64+
RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser,
6565
};
6666
use crate::attributes::semantics::MayDangleParser;
6767
use crate::attributes::stability::{
@@ -209,6 +209,7 @@ attribute_parsers!(
209209
Single<RustcForceInlineParser>,
210210
Single<RustcLayoutScalarValidRangeEndParser>,
211211
Single<RustcLayoutScalarValidRangeStartParser>,
212+
Single<RustcLegacyConstGenericsParser>,
212213
Single<RustcObjectLifetimeDefaultParser>,
213214
Single<RustcScalableVectorParser>,
214215
Single<RustcSimdMonomorphizeLaneLimitParser>,

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,9 @@ pub enum AttributeKind {
869869
/// Represents `#[rustc_layout_scalar_valid_range_start]`.
870870
RustcLayoutScalarValidRangeStart(Box<u128>, Span),
871871

872+
/// Represents `#[rustc_legacy_const_generics]`
873+
RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span },
874+
872875
/// Represents `#[rustc_main]`.
873876
RustcMain,
874877

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ impl AttributeKind {
9292
RustcCoherenceIsCore(..) => No,
9393
RustcLayoutScalarValidRangeEnd(..) => Yes,
9494
RustcLayoutScalarValidRangeStart(..) => Yes,
95+
RustcLegacyConstGenerics { .. } => Yes,
9596
RustcMain => No,
9697
RustcObjectLifetimeDefault => No,
9798
RustcPassIndirectlyInNonRusticAbis(..) => No,

compiler/rustc_hir/src/attrs/pretty_printing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ macro_rules! print_tup {
169169

170170
print_tup!(A B C D E F G H);
171171
print_skip!(Span, (), ErrorGuaranteed);
172-
print_disp!(u16, u128, bool, NonZero<u32>, Limit);
172+
print_disp!(u16, u128, usize, bool, NonZero<u32>, Limit);
173173
print_debug!(
174174
Symbol,
175175
Ident,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ pub struct ResolverGlobalCtxt {
197197
#[derive(Debug)]
198198
pub struct ResolverAstLowering {
199199
pub legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
200-
201200
/// Resolutions for nodes that have a single resolution.
202201
pub partial_res_map: NodeMap<hir::def::PartialRes>,
203202
/// 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
@@ -478,9 +478,6 @@ passes_rustc_legacy_const_generics_index_exceed =
478478
*[other] arguments
479479
}
480480
481-
passes_rustc_legacy_const_generics_index_negative =
482-
arguments should be non-negative integers
483-
484481
passes_rustc_legacy_const_generics_only =
485482
#[rustc_legacy_const_generics] functions must only have const generics
486483
.label = non-const generic parameter

compiler/rustc_passes/src/check_attr.rs

Lines changed: 19 additions & 45 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(item, *attr_span, fn_indexes)
217+
},
214218
Attribute::Parsed(AttributeKind::Doc(attr)) => self.check_doc_attrs(attr, hir_id, target),
215219
Attribute::Parsed(AttributeKind::EiiImpls(impls)) => {
216220
self.check_eii_impl(impls, target)
@@ -306,9 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
306310
[sym::rustc_never_returns_null_ptr, ..] => {
307311
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
308312
}
309-
[sym::rustc_legacy_const_generics, ..] => {
310-
self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)
311-
}
312313
[sym::rustc_lint_query_instability, ..] => {
313314
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
314315
}
@@ -1218,76 +1219,49 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
12181219
/// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
12191220
fn check_rustc_legacy_const_generics(
12201221
&self,
1221-
hir_id: HirId,
1222-
attr: &Attribute,
1223-
span: Span,
1224-
target: Target,
12251222
item: Option<ItemLike<'_>>,
1223+
attr_span: Span,
1224+
index_list: &ThinVec<(usize, Span)>,
12261225
) {
1227-
let is_function = matches!(target, Target::Fn);
1228-
if !is_function {
1229-
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
1230-
attr_span: attr.span(),
1231-
defn_span: span,
1232-
on_crate: hir_id == CRATE_HIR_ID,
1233-
});
1234-
return;
1235-
}
1236-
1237-
let Some(list) = attr.meta_item_list() else {
1238-
// The attribute form is validated on AST.
1239-
return;
1240-
};
1241-
12421226
let Some(ItemLike::Item(Item {
12431227
kind: ItemKind::Fn { sig: FnSig { decl, .. }, generics, .. },
12441228
..
12451229
})) = item
12461230
else {
1247-
bug!("should be a function item");
1231+
// No error here, since it's already given by the parser
1232+
return;
12481233
};
12491234

12501235
for param in generics.params {
12511236
match param.kind {
12521237
hir::GenericParamKind::Const { .. } => {}
12531238
_ => {
12541239
self.dcx().emit_err(errors::RustcLegacyConstGenericsOnly {
1255-
attr_span: attr.span(),
1240+
attr_span,
12561241
param_span: param.span,
12571242
});
12581243
return;
12591244
}
12601245
}
12611246
}
12621247

1263-
if list.len() != generics.params.len() {
1248+
if index_list.len() != generics.params.len() {
12641249
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndex {
1265-
attr_span: attr.span(),
1250+
attr_span,
12661251
generics_span: generics.span,
12671252
});
12681253
return;
12691254
}
12701255

1271-
let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
1272-
let mut invalid_args = vec![];
1273-
for meta in list {
1274-
if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) {
1275-
if *val >= arg_count {
1276-
let span = meta.span();
1277-
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed {
1278-
span,
1279-
arg_count: arg_count as usize,
1280-
});
1281-
return;
1282-
}
1283-
} else {
1284-
invalid_args.push(meta.span());
1256+
let arg_count = decl.inputs.len() + generics.params.len();
1257+
for (index, span) in index_list {
1258+
if *index >= arg_count {
1259+
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed {
1260+
span: *span,
1261+
arg_count,
1262+
});
12851263
}
12861264
}
1287-
1288-
if !invalid_args.is_empty() {
1289-
self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexNegative { invalid_args });
1290-
}
12911265
}
12921266

12931267
/// 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)