Skip to content

Commit 913e4be

Browse files
committed
Auto merge of #155655 - JonathanBrouwer:rollup-KFUw3UR, r=JonathanBrouwer
Rollup of 10 pull requests Successful merges: - #154794 (Add on_unmatch_args) - #155133 (Document precision considerations of `Duration`-float methods) - #154283 (Remove `nodes_in_current_session` field and related assertions) - #155374 (rustdoc: fix a few spots where emit isn't respected) - #155587 (Immediately feed visibility on DefId creation) - #155622 (c-variadic: `va_arg` fixes ) - #155629 (rustc_public: Add `constness` & `asyncness` in `FnDef`) - #155632 (Some metadata cleanups) - #155639 (BinOpAssign always returns unit) - #155647 (rustc-dev-guide subtree update)
2 parents f676c20 + e94e3cc commit 913e4be

84 files changed

Lines changed: 1539 additions & 594 deletions

File tree

Some content is hidden

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

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub(crate) mod on_const;
2525
pub(crate) mod on_move;
2626
pub(crate) mod on_unimplemented;
2727
pub(crate) mod on_unknown;
28+
pub(crate) mod on_unmatch_args;
2829

2930
#[derive(Copy, Clone)]
3031
pub(crate) enum Mode {
@@ -38,6 +39,8 @@ pub(crate) enum Mode {
3839
DiagnosticOnMove,
3940
/// `#[diagnostic::on_unknown]`
4041
DiagnosticOnUnknown,
42+
/// `#[diagnostic::on_unmatch_args]`
43+
DiagnosticOnUnmatchArgs,
4144
}
4245

4346
impl Mode {
@@ -48,6 +51,7 @@ impl Mode {
4851
Self::DiagnosticOnConst => "diagnostic::on_const",
4952
Self::DiagnosticOnMove => "diagnostic::on_move",
5053
Self::DiagnosticOnUnknown => "diagnostic::on_unknown",
54+
Self::DiagnosticOnUnmatchArgs => "diagnostic::on_unmatch_args",
5155
}
5256
}
5357

@@ -62,6 +66,7 @@ impl Mode {
6266
Self::DiagnosticOnConst => DEFAULT,
6367
Self::DiagnosticOnMove => DEFAULT,
6468
Self::DiagnosticOnUnknown => DEFAULT,
69+
Self::DiagnosticOnUnmatchArgs => DEFAULT,
6570
}
6671
}
6772

@@ -75,6 +80,7 @@ impl Mode {
7580
Self::DiagnosticOnConst => DEFAULT,
7681
Self::DiagnosticOnMove => DEFAULT,
7782
Self::DiagnosticOnUnknown => DEFAULT,
83+
Self::DiagnosticOnUnmatchArgs => DEFAULT,
7884
}
7985
}
8086
}
@@ -398,7 +404,9 @@ fn parse_arg(
398404
Position::ArgumentNamed(name) => match (mode, Symbol::intern(name)) {
399405
// Only `#[rustc_on_unimplemented]` can use these
400406
(Mode::RustcOnUnimplemented { .. }, sym::ItemContext) => FormatArg::ItemContext,
401-
(Mode::RustcOnUnimplemented { .. }, sym::This) => FormatArg::This,
407+
(Mode::RustcOnUnimplemented { .. } | Mode::DiagnosticOnUnmatchArgs, sym::This) => {
408+
FormatArg::This
409+
}
402410
(Mode::RustcOnUnimplemented { .. }, sym::Trait) => FormatArg::Trait,
403411
// Any attribute can use these
404412
(_, kw::SelfUpper) => FormatArg::SelfUpper,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use rustc_errors::Diagnostic;
2+
use rustc_hir::attrs::diagnostic::Directive;
3+
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
4+
5+
use crate::attributes::diagnostic::*;
6+
use crate::attributes::prelude::*;
7+
use crate::errors::DiagnosticOnUnmatchArgsOnlyForMacros;
8+
9+
#[derive(Default)]
10+
pub(crate) struct OnUnmatchArgsParser {
11+
span: Option<Span>,
12+
directive: Option<(Span, Directive)>,
13+
}
14+
15+
impl<S: Stage> AttributeParser<S> for OnUnmatchArgsParser {
16+
const ATTRIBUTES: AcceptMapping<Self, S> = &[(
17+
&[sym::diagnostic, sym::on_unmatch_args],
18+
template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
19+
|this, cx, args| {
20+
if !cx.features().diagnostic_on_unmatch_args() {
21+
return;
22+
}
23+
24+
let span = cx.attr_span;
25+
this.span = Some(span);
26+
27+
if !matches!(cx.target, Target::MacroDef) {
28+
cx.emit_dyn_lint(
29+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
30+
move |dcx, level| DiagnosticOnUnmatchArgsOnlyForMacros.into_diag(dcx, level),
31+
span,
32+
);
33+
return;
34+
}
35+
36+
let mode = Mode::DiagnosticOnUnmatchArgs;
37+
let Some(items) = parse_list(cx, args, mode) else { return };
38+
39+
let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) else {
40+
return;
41+
};
42+
merge_directives(cx, &mut this.directive, (span, directive));
43+
},
44+
)];
45+
46+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
47+
48+
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
49+
if let Some(span) = self.span {
50+
Some(AttributeKind::OnUnmatchArgs {
51+
span,
52+
directive: self.directive.map(|d| Box::new(d.1)),
53+
})
54+
} else {
55+
None
56+
}
57+
}
58+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::attributes::diagnostic::on_const::*;
3333
use crate::attributes::diagnostic::on_move::*;
3434
use crate::attributes::diagnostic::on_unimplemented::*;
3535
use crate::attributes::diagnostic::on_unknown::*;
36+
use crate::attributes::diagnostic::on_unmatch_args::*;
3637
use crate::attributes::doc::*;
3738
use crate::attributes::dummy::*;
3839
use crate::attributes::inline::*;
@@ -159,6 +160,7 @@ attribute_parsers!(
159160
OnMoveParser,
160161
OnUnimplementedParser,
161162
OnUnknownParser,
163+
OnUnmatchArgsParser,
162164
RustcAlignParser,
163165
RustcAlignStaticParser,
164166
RustcCguTestAttributeParser,

compiler/rustc_attr_parsing/src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ pub(crate) struct DiagnosticOnUnknownOnlyForImports {
315315
pub target_span: Span,
316316
}
317317

318+
#[derive(Diagnostic)]
319+
#[diag("`#[diagnostic::on_unmatch_args]` can only be applied to macro definitions")]
320+
pub(crate) struct DiagnosticOnUnmatchArgsOnlyForMacros;
321+
318322
#[derive(Diagnostic)]
319323
#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")]
320324
pub(crate) struct IncorrectDoNotRecommendLocation {

compiler/rustc_codegen_llvm/src/va_arg.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
1111
use rustc_target::spec::{Arch, Env, LlvmAbi, RustcAbi};
1212

1313
use crate::builder::Builder;
14-
use crate::llvm::{Type, Value};
14+
use crate::llvm::Value;
1515
use crate::type_of::LayoutLlvmExt;
1616

1717
fn round_up_to_alignment<'ll>(
@@ -27,13 +27,14 @@ fn round_pointer_up_to_alignment<'ll>(
2727
bx: &mut Builder<'_, 'll, '_>,
2828
addr: &'ll Value,
2929
align: Align,
30-
ptr_ty: &'ll Type,
3130
) -> &'ll Value {
3231
let ptr = bx.inbounds_ptradd(addr, bx.const_i32(align.bytes() as i32 - 1));
32+
let pointer_width = bx.tcx().sess.target.pointer_width;
33+
let mask = align.bytes().wrapping_neg() & (u64::MAX >> (64 - pointer_width));
3334
bx.call_intrinsic(
3435
"llvm.ptrmask",
35-
&[ptr_ty, bx.type_i32()],
36-
&[ptr, bx.const_int(bx.isize_ty, -(align.bytes() as isize) as i64)],
36+
&[bx.type_ptr(), bx.type_isize()],
37+
&[ptr, bx.const_usize(mask)],
3738
)
3839
}
3940

@@ -53,7 +54,7 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
5354
let ptr = bx.load(va_list_ty, va_list_addr, ptr_align_abi);
5455

5556
let (addr, addr_align) = if allow_higher_align && align > slot_size {
56-
(round_pointer_up_to_alignment(bx, ptr, align, bx.type_ptr()), align)
57+
(round_pointer_up_to_alignment(bx, ptr, align), align)
5758
} else {
5859
(ptr, slot_size)
5960
};
@@ -69,7 +70,8 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
6970
{
7071
let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
7172
let adjusted = bx.inbounds_ptradd(addr, adjusted_size);
72-
(adjusted, addr_align)
73+
// We're in the middle of a slot now, so use the type's alignment, not the slot's.
74+
(adjusted, align)
7375
} else {
7476
(addr, addr_align)
7577
}
@@ -357,12 +359,8 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
357359

358360
// Round up address of argument to alignment
359361
if layout.layout.align.abi > overflow_area_align {
360-
overflow_area = round_pointer_up_to_alignment(
361-
bx,
362-
overflow_area,
363-
layout.layout.align.abi,
364-
bx.type_ptr(),
365-
);
362+
overflow_area =
363+
round_pointer_up_to_alignment(bx, overflow_area, layout.layout.align.abi);
366364
}
367365

368366
let mem_addr = overflow_area;
@@ -827,7 +825,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>(
827825
} else {
828826
Align::from_bytes(4).unwrap()
829827
};
830-
let aligned_current = round_pointer_up_to_alignment(bx, current_ptr, arg_align, bx.type_ptr());
828+
let aligned_current = round_pointer_up_to_alignment(bx, current_ptr, arg_align);
831829

832830
// Calculate next pointer position (following LLVM's logic)
833831
// Arguments <= 32 bits take 4 bytes, > 32 bits take 8 bytes
@@ -849,8 +847,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>(
849847
bx.switch_to_block(from_overflow);
850848

851849
// Align overflow pointer using the same alignment rules
852-
let aligned_overflow =
853-
round_pointer_up_to_alignment(bx, overflow_ptr, arg_align, bx.type_ptr());
850+
let aligned_overflow = round_pointer_up_to_alignment(bx, overflow_ptr, arg_align);
854851

855852
let overflow_value_addr = aligned_overflow;
856853
// Update overflow pointer - use the same size calculation
@@ -890,7 +887,7 @@ fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>(
890887
let aligned_ptr = if ty_align.bytes() > 4 {
891888
// Ensure alignment is a power of 2
892889
debug_assert!(ty_align.bytes().is_power_of_two(), "Alignment is not power of 2!");
893-
round_pointer_up_to_alignment(bx, current_ptr, ty_align, bx.type_ptr())
890+
round_pointer_up_to_alignment(bx, current_ptr, ty_align)
894891
} else {
895892
current_ptr
896893
};

compiler/rustc_expand/src/mbe/diagnostics.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::borrow::Cow;
33
use rustc_ast::token::{self, Token};
44
use rustc_ast::tokenstream::TokenStream;
55
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
6+
use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs};
67
use rustc_macros::Subdiagnostic;
78
use rustc_parse::parser::{Parser, Recovery, token_descr};
89
use rustc_session::parse::ParseSess;
@@ -32,6 +33,7 @@ pub(super) fn failed_to_match_macro(
3233
args: FailedMacro<'_>,
3334
body: &TokenStream,
3435
rules: &[MacroRule],
36+
on_unmatch_args: Option<&Directive>,
3537
) -> (Span, ErrorGuaranteed) {
3638
debug!("failed to match macro");
3739
let def_head_span = if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
@@ -72,9 +74,30 @@ pub(super) fn failed_to_match_macro(
7274
};
7375

7476
let span = token.span.substitute_dummy(sp);
77+
let CustomDiagnostic {
78+
message: custom_message, label: custom_label, notes: custom_notes, ..
79+
} = {
80+
let macro_name = name.to_string();
81+
on_unmatch_args
82+
.map(|directive| {
83+
directive.eval(
84+
None,
85+
&FormatArgs {
86+
this: macro_name.clone(),
87+
this_sugared: macro_name,
88+
item_context: "macro invocation",
89+
generic_args: Vec::new(),
90+
},
91+
)
92+
})
93+
.unwrap_or_default()
94+
};
7595

76-
let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None));
77-
err.span_label(span, label);
96+
let mut err = match custom_message {
97+
Some(message) => psess.dcx().struct_span_err(span, message),
98+
None => psess.dcx().struct_span_err(span, parse_failure_msg(&token, None)),
99+
};
100+
err.span_label(span, custom_label.unwrap_or_else(|| label.to_string()));
78101
if !def_head_span.is_dummy() {
79102
err.span_label(def_head_span, "when calling this macro");
80103
}
@@ -86,6 +109,9 @@ pub(super) fn failed_to_match_macro(
86109
} else {
87110
err.note(format!("while trying to match {remaining_matcher}"));
88111
}
112+
for note in custom_notes {
113+
err.note(note);
114+
}
89115

90116
if let MatcherLoc::Token { token: expected_token } = &remaining_matcher
91117
&& (matches!(expected_token.kind, token::OpenInvisible(_))

0 commit comments

Comments
 (0)