Skip to content

Commit c461e50

Browse files
authored
Merge pull request #4409 from rust-lang/rustup-2025-06-20
Automatic Rustup
2 parents 9eee9ee + fd7fb5e commit c461e50

File tree

180 files changed

+4047
-1388
lines changed

Some content is hidden

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

180 files changed

+4047
-1388
lines changed

Cargo.lock

Lines changed: 124 additions & 116 deletions
Large diffs are not rendered by default.

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,12 +2289,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
22892289
span: Span,
22902290
elements: &'hir [hir::Expr<'hir>],
22912291
) -> hir::Expr<'hir> {
2292-
let addrof = hir::ExprKind::AddrOf(
2293-
hir::BorrowKind::Ref,
2294-
hir::Mutability::Not,
2295-
self.arena.alloc(self.expr(span, hir::ExprKind::Array(elements))),
2296-
);
2297-
self.expr(span, addrof)
2292+
let array = self.arena.alloc(self.expr(span, hir::ExprKind::Array(elements)));
2293+
self.expr_ref(span, array)
2294+
}
2295+
2296+
pub(super) fn expr_ref(&mut self, span: Span, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
2297+
self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr))
22982298
}
22992299

23002300
pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> {

compiler/rustc_ast_lowering/src/format.rs

Lines changed: 77 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use core::ops::ControlFlow;
21
use std::borrow::Cow;
32

4-
use rustc_ast::visit::Visitor;
53
use rustc_ast::*;
64
use rustc_data_structures::fx::FxIndexMap;
75
use rustc_hir as hir;
@@ -476,77 +474,52 @@ fn expand_format_args<'hir>(
476474
return hir::ExprKind::Call(new, new_args);
477475
}
478476

479-
// If the args array contains exactly all the original arguments once,
480-
// in order, we can use a simple array instead of a `match` construction.
481-
// However, if there's a yield point in any argument except the first one,
482-
// we don't do this, because an Argument cannot be kept across yield points.
483-
//
484-
// This is an optimization, speeding up compilation about 1-2% in some cases.
485-
// See https://github.com/rust-lang/rust/pull/106770#issuecomment-1380790609
486-
let use_simple_array = argmap.len() == arguments.len()
487-
&& argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
488-
&& arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr));
489-
490-
let args = if arguments.is_empty() {
477+
let (let_statements, args) = if arguments.is_empty() {
491478
// Generate:
492-
// &<core::fmt::Argument>::none()
479+
// []
480+
(vec![], ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(&[]))))
481+
} else if argmap.len() == 1 && arguments.len() == 1 {
482+
// Only one argument, so we don't need to make the `args` tuple.
493483
//
494-
// Note:
495-
// `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime.
496-
//
497-
// This makes sure that this still fails to compile, even when the argument is inlined:
498-
//
499-
// ```
500-
// let f = format_args!("{}", "a");
501-
// println!("{f}"); // error E0716
502-
// ```
503-
//
504-
// Cases where keeping the object around is allowed, such as `format_args!("a")`,
505-
// are handled above by the `allow_const` case.
506-
let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
507-
macsp,
508-
hir::LangItem::FormatArgument,
509-
sym::none,
510-
));
511-
let none = ctx.expr_call(macsp, none_fn, &[]);
512-
ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none))
513-
} else if use_simple_array {
514484
// Generate:
515-
// &[
516-
// <core::fmt::Argument>::new_display(&arg0),
517-
// <core::fmt::Argument>::new_lower_hex(&arg1),
518-
// <core::fmt::Argument>::new_debug(&arg2),
519-
// …
520-
// ]
521-
let elements = ctx.arena.alloc_from_iter(arguments.iter().zip(argmap).map(
522-
|(arg, ((_, ty), placeholder_span))| {
485+
// super let args = [<core::fmt::Argument>::new_display(&arg)];
486+
let args = ctx.arena.alloc_from_iter(argmap.iter().map(
487+
|(&(arg_index, ty), &placeholder_span)| {
488+
let arg = &arguments[arg_index];
523489
let placeholder_span =
524490
placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt());
525-
let arg_span = match arg.kind {
526-
FormatArgumentKind::Captured(_) => placeholder_span,
527-
_ => arg.expr.span.with_ctxt(macsp.ctxt()),
528-
};
529491
let arg = ctx.lower_expr(&arg.expr);
530-
let ref_arg = ctx.arena.alloc(ctx.expr(
531-
arg_span,
532-
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg),
533-
));
492+
let ref_arg = ctx.arena.alloc(ctx.expr_ref(arg.span.with_ctxt(macsp.ctxt()), arg));
534493
make_argument(ctx, placeholder_span, ref_arg, ty)
535494
},
536495
));
537-
ctx.expr_array_ref(macsp, elements)
496+
let args = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args)));
497+
let args_ident = Ident::new(sym::args, macsp);
498+
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
499+
let let_statement = ctx.stmt_super_let_pat(macsp, args_pat, Some(args));
500+
(vec![let_statement], ctx.arena.alloc(ctx.expr_ident_mut(macsp, args_ident, args_hir_id)))
538501
} else {
539502
// Generate:
540-
// &match (&arg0, &arg1, &…) {
541-
// args => [
542-
// <core::fmt::Argument>::new_display(args.0),
543-
// <core::fmt::Argument>::new_lower_hex(args.1),
544-
// <core::fmt::Argument>::new_debug(args.0),
545-
// …
546-
// ]
547-
// }
503+
// super let args = (&arg0, &arg1, &…);
548504
let args_ident = Ident::new(sym::args, macsp);
549505
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
506+
let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| {
507+
let arg_expr = ctx.lower_expr(&arg.expr);
508+
ctx.expr(
509+
arg.expr.span.with_ctxt(macsp.ctxt()),
510+
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr),
511+
)
512+
}));
513+
let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements)));
514+
let let_statement_1 = ctx.stmt_super_let_pat(macsp, args_pat, Some(args_tuple));
515+
516+
// Generate:
517+
// super let args = [
518+
// <core::fmt::Argument>::new_display(args.0),
519+
// <core::fmt::Argument>::new_lower_hex(args.1),
520+
// <core::fmt::Argument>::new_debug(args.0),
521+
// …
522+
// ];
550523
let args = ctx.arena.alloc_from_iter(argmap.iter().map(
551524
|(&(arg_index, ty), &placeholder_span)| {
552525
let arg = &arguments[arg_index];
@@ -567,58 +540,47 @@ fn expand_format_args<'hir>(
567540
make_argument(ctx, placeholder_span, arg, ty)
568541
},
569542
));
570-
let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| {
571-
let arg_expr = ctx.lower_expr(&arg.expr);
572-
ctx.expr(
573-
arg.expr.span.with_ctxt(macsp.ctxt()),
574-
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr),
575-
)
576-
}));
577-
let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements)));
578-
let array = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args)));
579-
let match_arms = ctx.arena.alloc_from_iter([ctx.arm(args_pat, array)]);
580-
let match_expr = ctx.arena.alloc(ctx.expr_match(
581-
macsp,
582-
args_tuple,
583-
match_arms,
584-
hir::MatchSource::FormatArgs,
585-
));
586-
ctx.expr(
587-
macsp,
588-
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, match_expr),
543+
let args = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args)));
544+
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
545+
let let_statement_2 = ctx.stmt_super_let_pat(macsp, args_pat, Some(args));
546+
(
547+
vec![let_statement_1, let_statement_2],
548+
ctx.arena.alloc(ctx.expr_ident_mut(macsp, args_ident, args_hir_id)),
589549
)
590550
};
591551

592-
if let Some(format_options) = format_options {
552+
// Generate:
553+
// &args
554+
let args = ctx.expr_ref(macsp, args);
555+
556+
let call = if let Some(format_options) = format_options {
593557
// Generate:
594-
// <core::fmt::Arguments>::new_v1_formatted(
595-
// lit_pieces,
596-
// args,
597-
// format_options,
598-
// unsafe { ::core::fmt::UnsafeArg::new() }
599-
// )
558+
// unsafe {
559+
// <core::fmt::Arguments>::new_v1_formatted(
560+
// lit_pieces,
561+
// args,
562+
// format_options,
563+
// )
564+
// }
600565
let new_v1_formatted = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
601566
macsp,
602567
hir::LangItem::FormatArguments,
603568
sym::new_v1_formatted,
604569
));
605-
let unsafe_arg_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
606-
macsp,
607-
hir::LangItem::FormatUnsafeArg,
608-
sym::new,
609-
));
610-
let unsafe_arg_new_call = ctx.expr_call(macsp, unsafe_arg_new, &[]);
570+
let args = ctx.arena.alloc_from_iter([lit_pieces, args, format_options]);
571+
let call = ctx.expr_call(macsp, new_v1_formatted, args);
611572
let hir_id = ctx.next_id();
612-
let unsafe_arg = ctx.expr_block(ctx.arena.alloc(hir::Block {
613-
stmts: &[],
614-
expr: Some(unsafe_arg_new_call),
615-
hir_id,
616-
rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated),
617-
span: macsp,
618-
targeted_by_break: false,
619-
}));
620-
let args = ctx.arena.alloc_from_iter([lit_pieces, args, format_options, unsafe_arg]);
621-
hir::ExprKind::Call(new_v1_formatted, args)
573+
hir::ExprKind::Block(
574+
ctx.arena.alloc(hir::Block {
575+
stmts: &[],
576+
expr: Some(call),
577+
hir_id,
578+
rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated),
579+
span: macsp,
580+
targeted_by_break: false,
581+
}),
582+
None,
583+
)
622584
} else {
623585
// Generate:
624586
// <core::fmt::Arguments>::new_v1(
@@ -632,35 +594,21 @@ fn expand_format_args<'hir>(
632594
));
633595
let new_args = ctx.arena.alloc_from_iter([lit_pieces, args]);
634596
hir::ExprKind::Call(new_v1, new_args)
635-
}
636-
}
637-
638-
fn may_contain_yield_point(e: &ast::Expr) -> bool {
639-
struct MayContainYieldPoint;
640-
641-
impl Visitor<'_> for MayContainYieldPoint {
642-
type Result = ControlFlow<()>;
643-
644-
fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> {
645-
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
646-
ControlFlow::Break(())
647-
} else {
648-
visit::walk_expr(self, e)
649-
}
650-
}
651-
652-
fn visit_mac_call(&mut self, _: &ast::MacCall) -> ControlFlow<()> {
653-
// Macros should be expanded at this point.
654-
unreachable!("unexpanded macro in ast lowering");
655-
}
597+
};
656598

657-
fn visit_item(&mut self, _: &ast::Item) -> ControlFlow<()> {
658-
// Do not recurse into nested items.
659-
ControlFlow::Continue(())
660-
}
599+
if !let_statements.is_empty() {
600+
// Generate:
601+
// {
602+
// super let …
603+
// super let …
604+
// <core::fmt::Arguments>::new_…(…)
605+
// }
606+
let call = ctx.arena.alloc(ctx.expr(macsp, call));
607+
let block = ctx.block_all(macsp, ctx.arena.alloc_from_iter(let_statements), Some(call));
608+
hir::ExprKind::Block(block, None)
609+
} else {
610+
call
661611
}
662-
663-
MayContainYieldPoint.visit_expr(e).is_break()
664612
}
665613

666614
fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) {

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,6 +2292,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22922292
self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
22932293
}
22942294

2295+
fn stmt_super_let_pat(
2296+
&mut self,
2297+
span: Span,
2298+
pat: &'hir hir::Pat<'hir>,
2299+
init: Option<&'hir hir::Expr<'hir>>,
2300+
) -> hir::Stmt<'hir> {
2301+
let hir_id = self.next_id();
2302+
let local = hir::LetStmt {
2303+
super_: Some(span),
2304+
hir_id,
2305+
init,
2306+
pat,
2307+
els: None,
2308+
source: hir::LocalSource::Normal,
2309+
span: self.lower_span(span),
2310+
ty: None,
2311+
};
2312+
self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2313+
}
2314+
22952315
fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
22962316
self.block_all(expr.span, &[], Some(expr))
22972317
}

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ impl Deprecation {
182182
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
183183
pub enum AttributeKind {
184184
// tidy-alphabetical-start
185+
/// Represents `#[align(N)]`.
186+
Align { align: Align, span: Span },
187+
185188
/// Represents `#[rustc_allow_const_fn_unstable]`.
186189
AllowConstFnUnstable(ThinVec<Symbol>),
187190

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ attr_parsing_incorrect_repr_format_packed_expect_integer =
4444
attr_parsing_incorrect_repr_format_packed_one_or_zero_arg =
4545
incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
4646
47+
attr_parsing_invalid_alignment_value =
48+
invalid alignment value: {$error_part}
49+
4750
attr_parsing_invalid_issue_string =
4851
`issue` must be a non-zero numeric string or "none"
4952
.must_not_be_zero = `issue` must not be "0", use "none" instead

compiler/rustc_attr_parsing/src/attributes/repr.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_attr_data_structures::{AttributeKind, IntType, ReprAttr};
44
use rustc_feature::{AttributeTemplate, template};
55
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
66

7-
use super::{CombineAttributeParser, ConvertFn};
7+
use super::{AcceptMapping, AttributeParser, CombineAttributeParser, ConvertFn, FinalizeContext};
88
use crate::context::{AcceptContext, Stage};
99
use crate::parser::{ArgParser, MetaItemListParser, MetaItemParser};
1010
use crate::session_diagnostics;
@@ -203,7 +203,7 @@ fn parse_repr_align<S: Stage>(
203203
});
204204
}
205205
Align => {
206-
cx.dcx().emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
206+
cx.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
207207
span: param_span,
208208
});
209209
}
@@ -266,3 +266,57 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
266266
Err("not an unsuffixed integer")
267267
}
268268
}
269+
270+
/// Parse #[align(N)].
271+
#[derive(Default)]
272+
pub(crate) struct AlignParser(Option<(Align, Span)>);
273+
274+
impl AlignParser {
275+
const PATH: &'static [Symbol] = &[sym::align];
276+
const TEMPLATE: AttributeTemplate = template!(Word, List: "<alignment in bytes>");
277+
278+
fn parse<'c, S: Stage>(
279+
&mut self,
280+
cx: &'c mut AcceptContext<'_, '_, S>,
281+
args: &'c ArgParser<'_>,
282+
) {
283+
match args {
284+
ArgParser::NoArgs | ArgParser::NameValue(_) => {
285+
cx.expected_list(cx.attr_span);
286+
}
287+
ArgParser::List(list) => {
288+
let Some(align) = list.single() else {
289+
cx.expected_single_argument(list.span);
290+
return;
291+
};
292+
293+
let Some(lit) = align.lit() else {
294+
cx.emit_err(session_diagnostics::IncorrectReprFormatExpectInteger {
295+
span: align.span(),
296+
});
297+
298+
return;
299+
};
300+
301+
match parse_alignment(&lit.kind) {
302+
Ok(literal) => self.0 = Ord::max(self.0, Some((literal, cx.attr_span))),
303+
Err(message) => {
304+
cx.emit_err(session_diagnostics::InvalidAlignmentValue {
305+
span: lit.span,
306+
error_part: message,
307+
});
308+
}
309+
}
310+
}
311+
}
312+
}
313+
}
314+
315+
impl<S: Stage> AttributeParser<S> for AlignParser {
316+
const ATTRIBUTES: AcceptMapping<Self, S> = &[(Self::PATH, Self::TEMPLATE, Self::parse)];
317+
318+
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
319+
let (align, span) = self.0?;
320+
Some(AttributeKind::Align { align, span })
321+
}
322+
}

0 commit comments

Comments
 (0)