Skip to content

Commit 8db16f0

Browse files
committed
Auto merge of #155115 - JonathanBrouwer:rollup-RePrRPQ, r=<try>
Rollup of 6 pull requests try-job: dist-various-1 try-job: test-various try-job: x86_64-gnu-aux try-job: x86_64-gnu-llvm-21-3 try-job: x86_64-msvc-1 try-job: aarch64-apple try-job: x86_64-mingw-1
2 parents 8317fef + eb8e4f9 commit 8db16f0

File tree

58 files changed

+1018
-133
lines changed

Some content is hidden

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

58 files changed

+1018
-133
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3505,6 +3505,7 @@ dependencies = [
35053505
"rand_xoshiro",
35063506
"rustc_data_structures",
35073507
"rustc_error_messages",
3508+
"rustc_errors",
35083509
"rustc_hashes",
35093510
"rustc_index",
35103511
"rustc_macros",
@@ -3909,7 +3910,6 @@ dependencies = [
39093910
"anstream",
39103911
"anstyle",
39113912
"derive_setters",
3912-
"rustc_abi",
39133913
"rustc_ast",
39143914
"rustc_data_structures",
39153915
"rustc_error_codes",

compiler/rustc_abi/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ rand = { version = "0.9.0", default-features = false, optional = true }
1010
rand_xoshiro = { version = "0.7.0", optional = true }
1111
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
1212
rustc_error_messages = { path = "../rustc_error_messages", optional = true }
13+
rustc_errors = { path = "../rustc_errors", optional = true }
1314
rustc_hashes = { path = "../rustc_hashes" }
1415
rustc_index = { path = "../rustc_index", default-features = false }
1516
rustc_macros = { path = "../rustc_macros", optional = true }
@@ -21,11 +22,12 @@ tracing = "0.1"
2122
[features]
2223
# tidy-alphabetical-start
2324
default = ["nightly", "randomize"]
24-
# rust-analyzer depends on this crate and we therefore require it to built on a stable toolchain
25-
# without depending on rustc_data_structures, rustc_macros and rustc_serialize
25+
# rust-analyzer depends on this crate and we therefore require it to build on a stable toolchain
26+
# without depending on the rustc_* crates in the following list.
2627
nightly = [
2728
"dep:rustc_data_structures",
2829
"dep:rustc_error_messages",
30+
"dep:rustc_errors",
2931
"dep:rustc_macros",
3032
"dep:rustc_serialize",
3133
"dep:rustc_span",

compiler/rustc_abi/src/lib.rs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ use std::str::FromStr;
4646
use bitflags::bitflags;
4747
#[cfg(feature = "nightly")]
4848
use rustc_data_structures::stable_hasher::StableOrd;
49+
#[cfg(feature = "nightly")]
50+
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg};
4951
use rustc_hashes::Hash64;
5052
use rustc_index::{Idx, IndexSlice, IndexVec};
5153
#[cfg(feature = "nightly")]
@@ -332,7 +334,7 @@ impl Default for TargetDataLayout {
332334
}
333335
}
334336

335-
pub enum TargetDataLayoutErrors<'a> {
337+
pub enum TargetDataLayoutError<'a> {
336338
InvalidAddressSpace { addr_space: &'a str, cause: &'a str, err: ParseIntError },
337339
InvalidBits { kind: &'a str, bit: &'a str, cause: &'a str, err: ParseIntError },
338340
MissingAlignment { cause: &'a str },
@@ -343,6 +345,51 @@ pub enum TargetDataLayoutErrors<'a> {
343345
UnknownPointerSpecification { err: String },
344346
}
345347

348+
#[cfg(feature = "nightly")]
349+
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutError<'_> {
350+
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
351+
match self {
352+
TargetDataLayoutError::InvalidAddressSpace { addr_space, err, cause } => {
353+
Diag::new(dcx, level, msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
354+
.with_arg("addr_space", addr_space)
355+
.with_arg("cause", cause)
356+
.with_arg("err", err)
357+
}
358+
TargetDataLayoutError::InvalidBits { kind, bit, cause, err } => {
359+
Diag::new(dcx, level, msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
360+
.with_arg("kind", kind)
361+
.with_arg("bit", bit)
362+
.with_arg("cause", cause)
363+
.with_arg("err", err)
364+
}
365+
TargetDataLayoutError::MissingAlignment { cause } => {
366+
Diag::new(dcx, level, msg!("missing alignment for `{$cause}` in \"data-layout\""))
367+
.with_arg("cause", cause)
368+
}
369+
TargetDataLayoutError::InvalidAlignment { cause, err } => {
370+
Diag::new(dcx, level, msg!("invalid alignment for `{$cause}` in \"data-layout\": {$err}"))
371+
.with_arg("cause", cause)
372+
.with_arg("err", err.to_string())
373+
}
374+
TargetDataLayoutError::InconsistentTargetArchitecture { dl, target } => {
375+
Diag::new(dcx, level, msg!("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))
376+
.with_arg("dl", dl).with_arg("target", target)
377+
}
378+
TargetDataLayoutError::InconsistentTargetPointerWidth { pointer_size, target } => {
379+
Diag::new(dcx, level, msg!("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))
380+
.with_arg("pointer_size", pointer_size).with_arg("target", target)
381+
}
382+
TargetDataLayoutError::InvalidBitsSize { err } => {
383+
Diag::new(dcx, level, msg!("{$err}")).with_arg("err", err)
384+
}
385+
TargetDataLayoutError::UnknownPointerSpecification { err } => {
386+
Diag::new(dcx, level, msg!("unknown pointer specification `{$err}` in datalayout string"))
387+
.with_arg("err", err)
388+
}
389+
}
390+
}
391+
}
392+
346393
impl TargetDataLayout {
347394
/// Parse data layout from an
348395
/// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
@@ -352,17 +399,17 @@ impl TargetDataLayout {
352399
pub fn parse_from_llvm_datalayout_string<'a>(
353400
input: &'a str,
354401
default_address_space: AddressSpace,
355-
) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
402+
) -> Result<TargetDataLayout, TargetDataLayoutError<'a>> {
356403
// Parse an address space index from a string.
357404
let parse_address_space = |s: &'a str, cause: &'a str| {
358405
s.parse::<u32>().map(AddressSpace).map_err(|err| {
359-
TargetDataLayoutErrors::InvalidAddressSpace { addr_space: s, cause, err }
406+
TargetDataLayoutError::InvalidAddressSpace { addr_space: s, cause, err }
360407
})
361408
};
362409

363410
// Parse a bit count from a string.
364411
let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
365-
s.parse::<u64>().map_err(|err| TargetDataLayoutErrors::InvalidBits {
412+
s.parse::<u64>().map_err(|err| TargetDataLayoutError::InvalidBits {
366413
kind,
367414
bit: s,
368415
cause,
@@ -378,7 +425,7 @@ impl TargetDataLayout {
378425
let parse_align_str = |s: &'a str, cause: &'a str| {
379426
let align_from_bits = |bits| {
380427
Align::from_bits(bits)
381-
.map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
428+
.map_err(|err| TargetDataLayoutError::InvalidAlignment { cause, err })
382429
};
383430
let abi = parse_bits(s, "alignment", cause)?;
384431
Ok(align_from_bits(abi)?)
@@ -388,7 +435,7 @@ impl TargetDataLayout {
388435
// ignoring the secondary alignment specifications.
389436
let parse_align_seq = |s: &[&'a str], cause: &'a str| {
390437
if s.is_empty() {
391-
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
438+
return Err(TargetDataLayoutError::MissingAlignment { cause });
392439
}
393440
parse_align_str(s[0], cause)
394441
};
@@ -426,7 +473,7 @@ impl TargetDataLayout {
426473
// However, we currently don't take into account further specifications:
427474
// an error is emitted instead.
428475
if p.starts_with(char::is_alphabetic) {
429-
return Err(TargetDataLayoutErrors::UnknownPointerSpecification {
476+
return Err(TargetDataLayoutError::UnknownPointerSpecification {
430477
err: p.to_string(),
431478
});
432479
}
@@ -471,7 +518,7 @@ impl TargetDataLayout {
471518
// However, we currently don't take into account further specifications:
472519
// an error is emitted instead.
473520
if p.starts_with(char::is_alphabetic) {
474-
return Err(TargetDataLayoutErrors::UnknownPointerSpecification {
521+
return Err(TargetDataLayoutError::UnknownPointerSpecification {
475522
err: p.to_string(),
476523
});
477524
}

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
649649
AttributeParser::parse_limited(
650650
sess,
651651
&krate.attrs,
652-
sym::feature,
652+
&[sym::feature],
653653
DUMMY_SP,
654654
krate.id,
655655
Some(&features),

compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub(crate) mod do_not_recommend;
2424
pub(crate) mod on_const;
2525
pub(crate) mod on_move;
2626
pub(crate) mod on_unimplemented;
27+
pub(crate) mod on_unknown;
2728

2829
#[derive(Copy, Clone)]
2930
pub(crate) enum Mode {
@@ -35,6 +36,8 @@ pub(crate) enum Mode {
3536
DiagnosticOnConst,
3637
/// `#[diagnostic::on_move]`
3738
DiagnosticOnMove,
39+
/// `#[diagnostic::on_unknown]`
40+
DiagnosticOnUnknown,
3841
}
3942

4043
fn merge_directives<S: Stage>(
@@ -122,6 +125,13 @@ fn parse_directive_items<'p, S: Stage>(
122125
span,
123126
);
124127
}
128+
Mode::DiagnosticOnUnknown => {
129+
cx.emit_lint(
130+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
131+
AttributeLintKind::MalformedOnUnknownAttr { span },
132+
span,
133+
);
134+
}
125135
}
126136
continue;
127137
}}
@@ -140,7 +150,7 @@ fn parse_directive_items<'p, S: Stage>(
140150
Mode::RustcOnUnimplemented => {
141151
cx.emit_err(NoValueInOnUnimplemented { span: item.span() });
142152
}
143-
Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst | Mode::DiagnosticOnMove => {
153+
Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst | Mode::DiagnosticOnMove | Mode::DiagnosticOnUnknown => {
144154
cx.emit_lint(
145155
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
146156
AttributeLintKind::IgnoredDiagnosticOption {
@@ -176,7 +186,8 @@ fn parse_directive_items<'p, S: Stage>(
176186
Ok((f, warnings)) => {
177187
for warning in warnings {
178188
let (FormatWarning::InvalidSpecifier { span, .. }
179-
| FormatWarning::PositionalArgument { span, .. }) = warning;
189+
| FormatWarning::PositionalArgument { span, .. }
190+
| FormatWarning::DisallowedPlaceholder { span }) = warning;
180191
cx.emit_lint(
181192
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
182193
AttributeLintKind::MalformedDiagnosticFormat { warning },
@@ -326,6 +337,10 @@ fn parse_arg(
326337
is_source_literal: bool,
327338
) -> FormatArg {
328339
let span = slice_span(input_span, arg.position_span.clone(), is_source_literal);
340+
if matches!(mode, Mode::DiagnosticOnUnknown) {
341+
warnings.push(FormatWarning::DisallowedPlaceholder { span });
342+
return FormatArg::AsIs(sym::empty_braces);
343+
}
329344

330345
match arg.position {
331346
// Something like "hello {name}"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use rustc_hir::attrs::diagnostic::Directive;
2+
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
3+
4+
use crate::attributes::diagnostic::*;
5+
use crate::attributes::prelude::*;
6+
7+
#[derive(Default)]
8+
pub(crate) struct OnUnknownParser {
9+
span: Option<Span>,
10+
directive: Option<(Span, Directive)>,
11+
}
12+
13+
impl OnUnknownParser {
14+
fn parse<'sess, S: Stage>(
15+
&mut self,
16+
cx: &mut AcceptContext<'_, 'sess, S>,
17+
args: &ArgParser,
18+
mode: Mode,
19+
) {
20+
if !cx.features().diagnostic_on_unknown() {
21+
return;
22+
}
23+
let span = cx.attr_span;
24+
self.span = Some(span);
25+
26+
let items = match args {
27+
ArgParser::List(items) if !items.is_empty() => items,
28+
ArgParser::NoArgs | ArgParser::List(_) => {
29+
cx.emit_lint(
30+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
31+
AttributeLintKind::MissingOptionsForOnUnknown,
32+
span,
33+
);
34+
return;
35+
}
36+
ArgParser::NameValue(_) => {
37+
cx.emit_lint(
38+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
39+
AttributeLintKind::MalformedOnUnknownAttr { span },
40+
span,
41+
);
42+
return;
43+
}
44+
};
45+
46+
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
47+
merge_directives(cx, &mut self.directive, (span, directive));
48+
};
49+
}
50+
}
51+
52+
impl<S: Stage> AttributeParser<S> for OnUnknownParser {
53+
const ATTRIBUTES: AcceptMapping<Self, S> = &[(
54+
&[sym::diagnostic, sym::on_unknown],
55+
template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
56+
|this, cx, args| {
57+
this.parse(cx, args, Mode::DiagnosticOnUnknown);
58+
},
59+
)];
60+
//FIXME attribute is not parsed for non-use statements but diagnostics are issued in `check_attr.rs`
61+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
62+
63+
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
64+
if let Some(span) = self.span {
65+
Some(AttributeKind::OnUnknown {
66+
span,
67+
directive: self.directive.map(|d| Box::new(d.1)),
68+
})
69+
} else {
70+
None
71+
}
72+
}
73+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::sync::LazyLock;
77

88
use private::Sealed;
99
use rustc_ast::{AttrStyle, MetaItemLit, NodeId};
10-
use rustc_errors::{Diag, Diagnostic, Level};
10+
use rustc_errors::{Diag, Diagnostic, Level, MultiSpan};
1111
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
1212
use rustc_hir::attrs::AttributeKind;
1313
use rustc_hir::lints::AttributeLintKind;
@@ -32,6 +32,7 @@ use crate::attributes::diagnostic::do_not_recommend::*;
3232
use crate::attributes::diagnostic::on_const::*;
3333
use crate::attributes::diagnostic::on_move::*;
3434
use crate::attributes::diagnostic::on_unimplemented::*;
35+
use crate::attributes::diagnostic::on_unknown::*;
3536
use crate::attributes::doc::*;
3637
use crate::attributes::dummy::*;
3738
use crate::attributes::inline::*;
@@ -154,6 +155,7 @@ attribute_parsers!(
154155
OnConstParser,
155156
OnMoveParser,
156157
OnUnimplementedParser,
158+
OnUnknownParser,
157159
RustcAlignParser,
158160
RustcAlignStaticParser,
159161
RustcCguTestAttributeParser,
@@ -455,14 +457,19 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
455457
/// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
456458
/// must be delayed until after HIR is built. This method will take care of the details of
457459
/// that.
458-
pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) {
460+
pub(crate) fn emit_lint<M: Into<MultiSpan>>(
461+
&mut self,
462+
lint: &'static Lint,
463+
kind: AttributeLintKind,
464+
span: M,
465+
) {
459466
if !matches!(
460467
self.stage.should_emit(),
461468
ShouldEmit::ErrorsAndLints { .. } | ShouldEmit::EarlyFatal { also_emit_lints: true }
462469
) {
463470
return;
464471
}
465-
(self.emit_lint)(LintId::of(lint), span, kind);
472+
(self.emit_lint)(LintId::of(lint), span.into(), kind);
466473
}
467474

468475
pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
@@ -528,7 +535,7 @@ pub struct SharedContext<'p, 'sess, S: Stage> {
528535

529536
/// The second argument of the closure is a [`NodeId`] if `S` is `Early` and a [`HirId`] if `S`
530537
/// is `Late` and is the ID of the syntactical component this attribute was applied to.
531-
pub(crate) emit_lint: &'p mut dyn FnMut(LintId, Span, AttributeLintKind),
538+
pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, AttributeLintKind),
532539
}
533540

534541
/// Context given to every attribute parser during finalization.

0 commit comments

Comments
 (0)