Skip to content

Commit 33318ed

Browse files
authored
Rollup merge of #145819 - jdonszelmann:convert-limits, r=fmease
Port limit attributes to the new attribute parsing infrastructure Doesn't pass tests, to be rebased on #145792 which will solve that r? `@fmease`
2 parents 8e5f838 + 6087d89 commit 33318ed

File tree

50 files changed

+550
-441
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+550
-441
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4409,7 +4409,6 @@ dependencies = [
44094409
"rustc_middle",
44104410
"rustc_query_system",
44114411
"rustc_serialize",
4412-
"rustc_session",
44134412
"rustc_span",
44144413
"tracing",
44154414
]

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,7 @@ attr_parsing_raw_dylib_only_windows =
247247
248248
attr_parsing_whole_archive_needs_static =
249249
linking modifier `whole-archive` is only compatible with `static` linking kind
250+
251+
attr_parsing_limit_invalid =
252+
`limit` must be a non-negative integer
253+
.label = {$error_str}

compiler/rustc_attr_parsing/src/attributes/crate_level.rs

Lines changed: 145 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,40 @@
1-
use rustc_feature::AttributeType;
1+
use std::num::IntErrorKind;
2+
3+
use rustc_hir::limit::Limit;
24

35
use super::prelude::*;
6+
use crate::session_diagnostics::LimitInvalid;
7+
8+
impl<S: Stage> AcceptContext<'_, '_, S> {
9+
fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
10+
let Some(limit) = nv.value_as_str() else {
11+
self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
12+
return None;
13+
};
14+
15+
let error_str = match limit.as_str().parse() {
16+
Ok(i) => return Some(Limit::new(i)),
17+
Err(e) => match e.kind() {
18+
IntErrorKind::PosOverflow => "`limit` is too large",
19+
IntErrorKind::Empty => "`limit` must be a non-negative integer",
20+
IntErrorKind::InvalidDigit => "not a valid integer",
21+
IntErrorKind::NegOverflow => {
22+
panic!(
23+
"`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
24+
)
25+
}
26+
IntErrorKind::Zero => {
27+
panic!("zero is a valid `limit` so should have returned Ok() when parsing")
28+
}
29+
kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
30+
},
31+
};
32+
33+
self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
34+
35+
None
36+
}
37+
}
438

539
pub(crate) struct CrateNameParser;
640

@@ -11,8 +45,8 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
1145
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
1246
const TYPE: AttributeType = AttributeType::CrateLevel;
1347

14-
// FIXME: crate name is allowed on all targets and ignored,
15-
// even though it should only be valid on crates of course
48+
// because it's a crate-level attribute, we already warn about it.
49+
// Putting target limitations here would give duplicate warnings
1650
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
1751

1852
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
@@ -34,3 +68,111 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
3468
})
3569
}
3670
}
71+
72+
pub(crate) struct RecursionLimitParser;
73+
74+
impl<S: Stage> SingleAttributeParser<S> for RecursionLimitParser {
75+
const PATH: &[Symbol] = &[sym::recursion_limit];
76+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
77+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
78+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute");
79+
const TYPE: AttributeType = AttributeType::CrateLevel;
80+
81+
// because it's a crate-level attribute, we already warn about it.
82+
// Putting target limitations here would give duplicate warnings
83+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
84+
85+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
86+
let ArgParser::NameValue(nv) = args else {
87+
cx.expected_name_value(cx.attr_span, None);
88+
return None;
89+
};
90+
91+
Some(AttributeKind::RecursionLimit {
92+
limit: cx.parse_limit_int(nv)?,
93+
attr_span: cx.attr_span,
94+
limit_span: nv.value_span,
95+
})
96+
}
97+
}
98+
99+
pub(crate) struct MoveSizeLimitParser;
100+
101+
impl<S: Stage> SingleAttributeParser<S> for MoveSizeLimitParser {
102+
const PATH: &[Symbol] = &[sym::move_size_limit];
103+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
104+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
105+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
106+
const TYPE: AttributeType = AttributeType::CrateLevel;
107+
108+
// because it's a crate-level attribute, we already warn about it.
109+
// Putting target limitations here would give duplicate warnings
110+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
111+
112+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
113+
let ArgParser::NameValue(nv) = args else {
114+
cx.expected_name_value(cx.attr_span, None);
115+
return None;
116+
};
117+
118+
Some(AttributeKind::MoveSizeLimit {
119+
limit: cx.parse_limit_int(nv)?,
120+
attr_span: cx.attr_span,
121+
limit_span: nv.value_span,
122+
})
123+
}
124+
}
125+
126+
pub(crate) struct TypeLengthLimitParser;
127+
128+
impl<S: Stage> SingleAttributeParser<S> for TypeLengthLimitParser {
129+
const PATH: &[Symbol] = &[sym::type_length_limit];
130+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
131+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
132+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
133+
const TYPE: AttributeType = AttributeType::CrateLevel;
134+
135+
// because it's a crate-level attribute, we already warn about it.
136+
// Putting target limitations here would give duplicate warnings
137+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
138+
139+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
140+
let ArgParser::NameValue(nv) = args else {
141+
cx.expected_name_value(cx.attr_span, None);
142+
return None;
143+
};
144+
145+
Some(AttributeKind::TypeLengthLimit {
146+
limit: cx.parse_limit_int(nv)?,
147+
attr_span: cx.attr_span,
148+
limit_span: nv.value_span,
149+
})
150+
}
151+
}
152+
153+
pub(crate) struct PatternComplexityLimitParser;
154+
155+
impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
156+
const PATH: &[Symbol] = &[sym::pattern_complexity_limit];
157+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
158+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
159+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
160+
const TYPE: AttributeType = AttributeType::CrateLevel;
161+
162+
// because it's a crate-level attribute, we already warn about it.
163+
// Putting target limitations here would give duplicate warnings
164+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
165+
166+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
167+
let ArgParser::NameValue(nv) = args else {
168+
cx.expected_name_value(cx.attr_span, None);
169+
return None;
170+
};
171+
172+
Some(AttributeKind::PatternComplexityLimit {
173+
limit: cx.parse_limit_int(nv)?,
174+
attr_span: cx.attr_span,
175+
limit_span: nv.value_span,
176+
})
177+
}
178+
}

compiler/rustc_attr_parsing/src/attributes/prelude.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
// templates
2-
#[doc(hidden)]
3-
pub(super) use rustc_feature::{AttributeTemplate, template};
41
// data structures
52
#[doc(hidden)]
3+
pub(super) use rustc_feature::{AttributeTemplate, AttributeType, template};
4+
#[doc(hidden)]
65
pub(super) use rustc_hir::attrs::AttributeKind;
76
#[doc(hidden)]
87
pub(super) use rustc_hir::lints::AttributeLintKind;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ use crate::attributes::codegen_attrs::{
2424
UsedParser,
2525
};
2626
use crate::attributes::confusables::ConfusablesParser;
27-
use crate::attributes::crate_level::CrateNameParser;
27+
use crate::attributes::crate_level::{
28+
CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser,
29+
TypeLengthLimitParser,
30+
};
2831
use crate::attributes::deprecation::DeprecationParser;
2932
use crate::attributes::dummy::DummyParser;
3033
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
@@ -181,10 +184,13 @@ attribute_parsers!(
181184
Single<LinkOrdinalParser>,
182185
Single<LinkSectionParser>,
183186
Single<LinkageParser>,
187+
Single<MoveSizeLimitParser>,
184188
Single<MustUseParser>,
185189
Single<OptimizeParser>,
186190
Single<PathAttributeParser>,
191+
Single<PatternComplexityLimitParser>,
187192
Single<ProcMacroDeriveParser>,
193+
Single<RecursionLimitParser>,
188194
Single<RustcBuiltinMacroParser>,
189195
Single<RustcForceInlineParser>,
190196
Single<RustcLayoutScalarValidRangeEnd>,
@@ -194,6 +200,7 @@ attribute_parsers!(
194200
Single<ShouldPanicParser>,
195201
Single<SkipDuringMethodDispatchParser>,
196202
Single<TransparencyParser>,
203+
Single<TypeLengthLimitParser>,
197204
Single<WithoutArgs<AllowIncoherentImplParser>>,
198205
Single<WithoutArgs<AllowInternalUnsafeParser>>,
199206
Single<WithoutArgs<AsPtrParser>>,
@@ -346,7 +353,10 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
346353
/// must be delayed until after HIR is built. This method will take care of the details of
347354
/// that.
348355
pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
349-
if matches!(self.stage.should_emit(), ShouldEmit::Nothing) {
356+
if !matches!(
357+
self.stage.should_emit(),
358+
ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true }
359+
) {
350360
return;
351361
}
352362
let id = self.target_id;
@@ -670,20 +680,20 @@ pub enum ShouldEmit {
670680
///
671681
/// Only relevant when early parsing, in late parsing equivalent to `ErrorsAndLints`.
672682
/// Late parsing is never fatal, and instead tries to emit as many diagnostics as possible.
673-
EarlyFatal,
683+
EarlyFatal { also_emit_lints: bool },
674684
/// The operation will emit errors and lints.
675685
/// This is usually what you need.
676686
ErrorsAndLints,
677687
/// The operation will emit *not* errors and lints.
678-
/// Use this if you are *sure* that this operation will be called at a different time with `ShouldEmit::Emit`.
688+
/// Use this if you are *sure* that this operation will be called at a different time with `ShouldEmit::ErrorsAndLints`.
679689
Nothing,
680690
}
681691

682692
impl ShouldEmit {
683693
pub(crate) fn emit_err(&self, diag: Diag<'_>) -> ErrorGuaranteed {
684694
match self {
685-
ShouldEmit::EarlyFatal if diag.level() == Level::DelayedBug => diag.emit(),
686-
ShouldEmit::EarlyFatal => diag.upgrade_to_fatal().emit(),
695+
ShouldEmit::EarlyFatal { .. } if diag.level() == Level::DelayedBug => diag.emit(),
696+
ShouldEmit::EarlyFatal { .. } => diag.upgrade_to_fatal().emit(),
687697
ShouldEmit::ErrorsAndLints => diag.emit(),
688698
ShouldEmit::Nothing => diag.delay_as_bug(),
689699
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,3 +930,13 @@ pub(crate) struct ImportNameTypeRaw {
930930
#[primary_span]
931931
pub span: Span,
932932
}
933+
934+
#[derive(Diagnostic)]
935+
#[diag(attr_parsing_limit_invalid)]
936+
pub(crate) struct LimitInvalid<'a> {
937+
#[primary_span]
938+
pub span: Span,
939+
#[label]
940+
pub value_span: Span,
941+
pub error_str: &'a str,
942+
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use either::{Left, Right};
44
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
55
use rustc_errors::DiagCtxtHandle;
66
use rustc_hir::def_id::DefId;
7+
use rustc_hir::limit::Limit;
78
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
89
use rustc_middle::query::TyCtxtAt;
910
use rustc_middle::ty::layout::{
@@ -12,7 +13,6 @@ use rustc_middle::ty::layout::{
1213
};
1314
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
1415
use rustc_middle::{mir, span_bug};
15-
use rustc_session::Limit;
1616
use rustc_span::Span;
1717
use rustc_target::callconv::FnAbi;
1818
use tracing::{debug, trace};

compiler/rustc_expand/src/base.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ use rustc_feature::Features;
1818
use rustc_hir as hir;
1919
use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation};
2020
use rustc_hir::def::MacroKinds;
21+
use rustc_hir::limit::Limit;
2122
use rustc_hir::{Stability, find_attr};
2223
use rustc_lint_defs::RegisteredTools;
2324
use rustc_parse::MACRO_ARGUMENTS;
2425
use rustc_parse::parser::{ForceCollect, Parser};
26+
use rustc_session::Session;
2527
use rustc_session::config::CollapseMacroDebuginfo;
2628
use rustc_session::parse::ParseSess;
27-
use rustc_session::{Limit, Session};
2829
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
2930
use rustc_span::edition::Edition;
3031
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};

compiler/rustc_expand/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::borrow::Cow;
22

33
use rustc_ast::ast;
44
use rustc_errors::codes::*;
5+
use rustc_hir::limit::Limit;
56
use rustc_macros::{Diagnostic, Subdiagnostic};
6-
use rustc_session::Limit;
77
use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol};
88

99
#[derive(Diagnostic)]

compiler/rustc_expand/src/expand.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ use rustc_errors::PResult;
1919
use rustc_feature::Features;
2020
use rustc_hir::Target;
2121
use rustc_hir::def::MacroKinds;
22+
use rustc_hir::limit::Limit;
2223
use rustc_parse::parser::{
2324
AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma,
2425
token_descr,
2526
};
27+
use rustc_session::Session;
2628
use rustc_session::lint::BuiltinLintDiag;
2729
use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
2830
use rustc_session::parse::feature_err;
29-
use rustc_session::{Limit, Session};
3031
use rustc_span::hygiene::SyntaxContext;
3132
use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym};
3233
use smallvec::SmallVec;
@@ -2529,6 +2530,7 @@ impl ExpansionConfig<'_> {
25292530
ExpansionConfig {
25302531
crate_name,
25312532
features,
2533+
// FIXME should this limit be configurable?
25322534
recursion_limit: Limit::new(1024),
25332535
trace_mac: false,
25342536
should_test: false,

0 commit comments

Comments
 (0)