From 6024960120caa23f03ab7a92f309045f2990ef3f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 30 Mar 2025 10:39:45 +0200 Subject: [PATCH 1/6] Use super let in format_args!(). This makes it posisble to do: let f = format_args!("Hello, {name}!"); --- compiler/rustc_ast_lowering/src/format.rs | 161 +++++------------- compiler/rustc_ast_lowering/src/lib.rs | 20 +++ library/core/src/fmt/mod.rs | 14 +- library/core/src/fmt/rt.rs | 12 +- library/coretests/tests/fmt/mod.rs | 16 ++ src/tools/tidy/src/issues.txt | 1 - tests/coverage/closure.cov-map | 34 ++-- tests/coverage/issue-84561.cov-map | 108 ++++++------ ...mes.foo.ScalarReplacementOfAggregates.diff | 159 ++++++++++------- tests/ui/borrowck/clone-on-ref.stderr | 4 +- .../issue-114374-invalid-help-fmt-args.rs | 16 -- .../issue-114374-invalid-help-fmt-args.stderr | 31 ---- .../ui/consts/recursive-const-in-impl.stderr | 5 +- tests/ui/fmt/send-sync.stderr | 12 +- .../precise-capturing/foreign-2021.stderr | 2 +- .../precise-capturing/migration-note.stderr | 10 +- ...745-avoid-expr-from-macro-expansion.stderr | 4 +- tests/ui/issues/issue-27592.rs | 2 +- tests/ui/issues/issue-27592.stderr | 12 +- .../format-args-temporaries-in-write.stderr | 2 - tests/ui/sized/unsized-binding.rs | 4 +- .../ui/unpretty/flattened-format-args.stdout | 7 +- 22 files changed, 299 insertions(+), 337 deletions(-) delete mode 100644 tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs delete mode 100644 tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 0de0319c66763..d04d9eb5b123f 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -1,7 +1,5 @@ -use core::ops::ControlFlow; use std::borrow::Cow; -use rustc_ast::visit::Visitor; use rustc_ast::*; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; @@ -476,77 +474,32 @@ fn expand_format_args<'hir>( return hir::ExprKind::Call(new, new_args); } - // If the args array contains exactly all the original arguments once, - // in order, we can use a simple array instead of a `match` construction. - // However, if there's a yield point in any argument except the first one, - // we don't do this, because an Argument cannot be kept across yield points. - // - // This is an optimization, speeding up compilation about 1-2% in some cases. - // See https://github.com/rust-lang/rust/pull/106770#issuecomment-1380790609 - let use_simple_array = argmap.len() == arguments.len() - && argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j) - && arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr)); - - let args = if arguments.is_empty() { + let (let_statements, args) = if arguments.is_empty() { // Generate: - // &::none() - // - // Note: - // `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime. - // - // This makes sure that this still fails to compile, even when the argument is inlined: - // - // ``` - // let f = format_args!("{}", "a"); - // println!("{f}"); // error E0716 - // ``` - // - // Cases where keeping the object around is allowed, such as `format_args!("a")`, - // are handled above by the `allow_const` case. - let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative( - macsp, - hir::LangItem::FormatArgument, - sym::none, - )); - let none = ctx.expr_call(macsp, none_fn, &[]); - ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none)) - } else if use_simple_array { - // Generate: - // &[ - // ::new_display(&arg0), - // ::new_lower_hex(&arg1), - // ::new_debug(&arg2), - // … - // ] - let elements = ctx.arena.alloc_from_iter(arguments.iter().zip(argmap).map( - |(arg, ((_, ty), placeholder_span))| { - let placeholder_span = - placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt()); - let arg_span = match arg.kind { - FormatArgumentKind::Captured(_) => placeholder_span, - _ => arg.expr.span.with_ctxt(macsp.ctxt()), - }; - let arg = ctx.lower_expr(&arg.expr); - let ref_arg = ctx.arena.alloc(ctx.expr( - arg_span, - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg), - )); - make_argument(ctx, placeholder_span, ref_arg, ty) - }, - )); - ctx.expr_array_ref(macsp, elements) + // [] + (None, ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(&[])))) } else { // Generate: - // &match (&arg0, &arg1, &…) { - // args => [ - // ::new_display(args.0), - // ::new_lower_hex(args.1), - // ::new_debug(args.0), - // … - // ] - // } + // super let args = (&arg0, &arg1, &…); let args_ident = Ident::new(sym::args, macsp); let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident); + let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| { + let arg_expr = ctx.lower_expr(&arg.expr); + ctx.expr( + arg.expr.span.with_ctxt(macsp.ctxt()), + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr), + ) + })); + let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements))); + let let_statement_1 = ctx.stmt_super_let_pat(macsp, args_pat, Some(args_tuple)); + + // Generate: + // super let args = [ + // ::new_display(args.0), + // ::new_lower_hex(args.1), + // ::new_debug(args.0), + // … + // ]; let args = ctx.arena.alloc_from_iter(argmap.iter().map( |(&(arg_index, ty), &placeholder_span)| { let arg = &arguments[arg_index]; @@ -567,29 +520,21 @@ fn expand_format_args<'hir>( make_argument(ctx, placeholder_span, arg, ty) }, )); - let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| { - let arg_expr = ctx.lower_expr(&arg.expr); - ctx.expr( - arg.expr.span.with_ctxt(macsp.ctxt()), - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr), - ) - })); - let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements))); - let array = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args))); - let match_arms = ctx.arena.alloc_from_iter([ctx.arm(args_pat, array)]); - let match_expr = ctx.arena.alloc(ctx.expr_match( - macsp, - args_tuple, - match_arms, - hir::MatchSource::FormatArgs, - )); - ctx.expr( - macsp, - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, match_expr), + let args = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args))); + let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident); + let let_statement_2 = ctx.stmt_super_let_pat(macsp, args_pat, Some(args)); + ( + Some([let_statement_1, let_statement_2]), + ctx.arena.alloc(ctx.expr_ident_mut(macsp, args_ident, args_hir_id)), ) }; - if let Some(format_options) = format_options { + // Generate: + // &args + let args = + ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, args)); + + let call = if let Some(format_options) = format_options { // Generate: // ::new_v1_formatted( // lit_pieces, @@ -632,35 +577,21 @@ fn expand_format_args<'hir>( )); let new_args = ctx.arena.alloc_from_iter([lit_pieces, args]); hir::ExprKind::Call(new_v1, new_args) - } -} - -fn may_contain_yield_point(e: &ast::Expr) -> bool { - struct MayContainYieldPoint; - - impl Visitor<'_> for MayContainYieldPoint { - type Result = ControlFlow<()>; - - fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> { - if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind { - ControlFlow::Break(()) - } else { - visit::walk_expr(self, e) - } - } - - fn visit_mac_call(&mut self, _: &ast::MacCall) -> ControlFlow<()> { - // Macros should be expanded at this point. - unreachable!("unexpanded macro in ast lowering"); - } + }; - fn visit_item(&mut self, _: &ast::Item) -> ControlFlow<()> { - // Do not recurse into nested items. - ControlFlow::Continue(()) - } + if let Some(let_statements) = let_statements { + // Generate: + // { + // super let … + // super let … + // ::new_…(…) + // } + let call = ctx.arena.alloc(ctx.expr(macsp, call)); + let block = ctx.block_all(macsp, ctx.arena.alloc_from_iter(let_statements), Some(call)); + hir::ExprKind::Block(block, None) + } else { + call } - - MayContainYieldPoint.visit_expr(e).is_break() } fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c40987541f4a5..5ce9d1105c76d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2230,6 +2230,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local))) } + fn stmt_super_let_pat( + &mut self, + span: Span, + pat: &'hir hir::Pat<'hir>, + init: Option<&'hir hir::Expr<'hir>>, + ) -> hir::Stmt<'hir> { + let hir_id = self.next_id(); + let local = hir::LetStmt { + super_: Some(span), + hir_id, + init, + pat, + els: None, + source: hir::LocalSource::Normal, + span: self.lower_span(span), + ty: None, + }; + self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local))) + } + fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> { self.block_all(expr.span, &[], Some(expr)) } diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 580f95eddce71..f88889dadf4f4 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -635,7 +635,7 @@ impl<'a> Arguments<'a> { /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. #[inline] - pub const fn new_v1( + pub fn new_v1( pieces: &'a [&'static str; P], args: &'a [rt::Argument<'a>; A], ) -> Arguments<'a> { @@ -651,6 +651,18 @@ impl<'a> Arguments<'a> { /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`. /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`. #[inline] + #[cfg(not(bootstrap))] + pub unsafe fn new_v1_formatted( + pieces: &'a [&'static str], + args: &'a [rt::Argument<'a>], + fmt: &'a [rt::Placeholder], + ) -> Arguments<'a> { + Arguments { pieces, fmt: Some(fmt), args } + } + + /// Bootstrap only. + #[cfg(bootstrap)] + #[inline] pub const fn new_v1_formatted( pieces: &'a [&'static str], args: &'a [rt::Argument<'a>], diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index adcfdd309b7e8..610a206fed39f 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -190,16 +190,8 @@ impl Argument<'_> { } } - /// Used by `format_args` when all arguments are gone after inlining, - /// when using `&[]` would incorrectly allow for a bigger lifetime. - /// - /// This fails without format argument inlining, and that shouldn't be different - /// when the argument is inlined: - /// - /// ```compile_fail,E0716 - /// let f = format_args!("{}", "a"); - /// println!("{f}"); - /// ``` + /// Bootstrap only. + #[cfg(bootstrap)] #[inline] pub const fn none() -> [Self; 0] { [] diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index d9060fe903d24..b49e80c78f709 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -2,6 +2,22 @@ mod builders; mod float; mod num; +#[test] +#[cfg(not(bootstrap))] +fn test_lifetime() { + // Trigger all different forms of expansion, + // and check that each of them can be stored as a variable. + let a = format_args!("hello"); + let a = format_args!("hello {a}"); + let a = format_args!("hello {a:1}"); + let a = format_args!("hello {a} {a:?}"); + assert_eq!(a.to_string(), "hello hello hello hello hello hello hello"); + + // Without arguments, it should also work in consts. + const A: std::fmt::Arguments<'static> = format_args!("hello"); + assert_eq!(A.to_string(), "hello"); +} + #[test] fn test_format_flags() { // No residual flags left by pointer formatting diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index f1ce3ccda0465..8616a5365597f 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -311,7 +311,6 @@ ui/borrowck/issue-104639-lifetime-order.rs ui/borrowck/issue-10876.rs ui/borrowck/issue-109271-pass-self-into-closure.rs ui/borrowck/issue-111554.rs -ui/borrowck/issue-114374-invalid-help-fmt-args.rs ui/borrowck/issue-11493.rs ui/borrowck/issue-115259-suggest-iter-mut.rs ui/borrowck/issue-119915-bad-clone-suggestion.rs diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index 2d784ba09b60a..5798e9f2703d2 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -83,58 +83,60 @@ Number of file 0 mappings: 1 Highest counter ID seen: (none) Function name: closure::main::{closure#14} -Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, b3, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33] +Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, b4, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 179, 13) to (start + 2, 27) -- Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 180, 17) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) Highest counter ID seen: c1 Function name: closure::main::{closure#15} -Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] +Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 01, 21, 01, 02, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 187, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21) -- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27) -- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 13) to (start + 1, 33) +- Code(Counter(0)) at (prev + 2, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) Highest counter ID seen: c1 Function name: closure::main::{closure#16} -Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, c5, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33] +Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, c6, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 197, 13) to (start + 2, 27) -- Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 198, 17) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) Highest counter ID seen: c1 Function name: closure::main::{closure#17} -Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] +Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 01, 21, 01, 02, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 205, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21) -- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27) -- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 13) to (start + 1, 33) +- Code(Counter(0)) at (prev + 2, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index 47e2922a805ac..713b8c21b82d1 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -59,80 +59,82 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: issue_84561::test3 -Raw bytes (279): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 33, 01, 08, 01, 03, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 09, 05, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 01, 0f, 0d, 02, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 02, 0f, 0d, 06, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 01, 0f, 0d, 05, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 02, 13, 21, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (289): 0x[01, 01, 0a, 01, 05, 01, 09, 01, 0d, 11, 15, 1d, 21, 19, 1d, 19, 1d, 19, 1d, 27, 25, 1d, 21, 35, 01, 08, 01, 03, 0f, 01, 04, 09, 01, 0f, 01, 02, 05, 04, 0f, 01, 05, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 09, 01, 0f, 01, 02, 05, 00, 0f, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 01, 01, 05, 03, 0f, 00, 03, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 01, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 01, 04, 09, 02, 0f, 01, 06, 05, 00, 0f, 01, 04, 05, 00, 0f, 01, 04, 09, 01, 0f, 01, 05, 08, 00, 0f, 05, 01, 09, 00, 13, 02, 05, 09, 00, 13, 01, 05, 08, 00, 0f, 09, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 01, 03, 05, 00, 0f, 01, 01, 0c, 00, 13, 0d, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 11, 04, 05, 02, 13, 15, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 19, 01, 0c, 00, 13, 1d, 01, 0d, 00, 17, 1d, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 21, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 25, 02, 05, 00, 0f, 25, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 10 -- expression 0 operands: lhs = Counter(3), rhs = Counter(4) -- expression 1 operands: lhs = Counter(3), rhs = Counter(5) -- expression 2 operands: lhs = Counter(3), rhs = Counter(6) -- expression 3 operands: lhs = Counter(7), rhs = Counter(8) -- expression 4 operands: lhs = Counter(10), rhs = Counter(11) -- expression 5 operands: lhs = Counter(9), rhs = Counter(10) -- expression 6 operands: lhs = Counter(9), rhs = Counter(10) -- expression 7 operands: lhs = Counter(9), rhs = Counter(10) -- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12) -- expression 9 operands: lhs = Counter(10), rhs = Counter(11) -Number of file 0 mappings: 51 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(0), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Counter(4), rhs = Counter(5) +- expression 4 operands: lhs = Counter(7), rhs = Counter(8) +- expression 5 operands: lhs = Counter(6), rhs = Counter(7) +- expression 6 operands: lhs = Counter(6), rhs = Counter(7) +- expression 7 operands: lhs = Counter(6), rhs = Counter(7) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(9) +- expression 9 operands: lhs = Counter(7), rhs = Counter(8) +Number of file 0 mappings: 53 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 15) -- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 15) -- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 15) -- Code(Counter(2)) at (prev + 5, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15) -- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 9) to (start + 1, 15) +- Code(Counter(0)) at (prev + 2, 5) to (start + 4, 15) +- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 15) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) - Code(Zero) at (prev + 0, 32) to (start + 0, 48) -- Code(Counter(3)) at (prev + 1, 5) to (start + 3, 15) -- Code(Zero) at (prev + 3, 32) to (start + 0, 48) +- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 15) +- Code(Zero) at (prev + 3, 32) to (start + 0, 36) +- Code(Zero) at (prev + 0, 41) to (start + 0, 48) - Code(Zero) at (prev + 0, 51) to (start + 0, 65) - Code(Zero) at (prev + 0, 75) to (start + 0, 90) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) -- Code(Zero) at (prev + 5, 9) to (start + 3, 16) -- Code(Zero) at (prev + 5, 13) to (start + 0, 27) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Zero) at (prev + 5, 9) to (start + 0, 13) +- Code(Zero) at (prev + 3, 9) to (start + 0, 16) +- Code(Zero) at (prev + 2, 13) to (start + 0, 27) - Code(Zero) at (prev + 2, 13) to (start + 0, 28) -- Code(Counter(3)) at (prev + 4, 9) to (start + 2, 15) -- Code(Counter(3)) at (prev + 6, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 9) to (start + 1, 15) -- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15) -- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19) +- Code(Counter(0)) at (prev + 4, 9) to (start + 2, 15) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 9) to (start + 1, 15) +- Code(Counter(0)) at (prev + 5, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19) - = (c3 - c4) -- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15) -- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 19) + = (c0 - c1) +- Code(Counter(0)) at (prev + 5, 8) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 19) - Code(Zero) at (prev + 3, 13) to (start + 0, 29) - Code(Expression(1, Sub)) at (prev + 3, 9) to (start + 0, 19) - = (c3 - c5) + = (c0 - c2) - Code(Zero) at (prev + 3, 13) to (start + 0, 29) -- Code(Counter(3)) at (prev + 3, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 19) -- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 19) +- Code(Counter(3)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c3 - c6) -- Code(Counter(7)) at (prev + 4, 5) to (start + 2, 19) -- Code(Counter(8)) at (prev + 3, 13) to (start + 0, 19) + = (c0 - c3) +- Code(Counter(4)) at (prev + 4, 5) to (start + 2, 19) +- Code(Counter(5)) at (prev + 3, 13) to (start + 0, 19) - Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c7 - c8) + = (c4 - c5) - Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15) - = (c10 + c11) -- Code(Counter(9)) at (prev + 1, 12) to (start + 0, 19) -- Code(Counter(10)) at (prev + 1, 13) to (start + 0, 23) -- Code(Counter(10)) at (prev + 4, 13) to (start + 0, 19) + = (c7 + c8) +- Code(Counter(6)) at (prev + 1, 12) to (start + 0, 19) +- Code(Counter(7)) at (prev + 1, 13) to (start + 0, 23) +- Code(Counter(7)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(7, Sub)) at (prev + 2, 13) to (start + 0, 23) - = (c9 - c10) + = (c6 - c7) - Code(Expression(7, Sub)) at (prev + 1, 20) to (start + 0, 27) - = (c9 - c10) + = (c6 - c7) - Code(Zero) at (prev + 1, 21) to (start + 0, 27) - Code(Expression(7, Sub)) at (prev + 2, 21) to (start + 0, 27) - = (c9 - c10) -- Code(Counter(11)) at (prev + 4, 13) to (start + 0, 19) + = (c6 - c7) +- Code(Counter(8)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 25) - = ((c10 + c11) - c12) -- Code(Counter(12)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(12)) at (prev + 3, 9) to (start + 0, 34) + = ((c7 + c8) - c9) +- Code(Counter(9)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(9)) at (prev + 3, 9) to (start + 0, 34) - Code(Zero) at (prev + 2, 5) to (start + 0, 15) - Code(Zero) at (prev + 3, 9) to (start + 0, 44) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c12 +Highest counter ID seen: c9 diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index a1df868cde051..66ed8c5355fc2 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -11,28 +11,29 @@ let _9: (); let _10: (); let mut _11: std::fmt::Arguments<'_>; - let mut _12: &[&str; 3]; - let _13: &[&str; 3]; - let _14: [&str; 3]; - let mut _15: &[core::fmt::rt::Argument<'_>; 2]; - let _16: &[core::fmt::rt::Argument<'_>; 2]; - let _17: [core::fmt::rt::Argument<'_>; 2]; + let mut _13: &std::boxed::Box; + let mut _14: &u32; + let mut _16: core::fmt::rt::Argument<'_>; + let mut _17: &std::boxed::Box; let mut _18: core::fmt::rt::Argument<'_>; - let mut _19: &std::boxed::Box; - let _20: &std::boxed::Box; - let mut _21: core::fmt::rt::Argument<'_>; - let mut _22: &u32; - let _23: &u32; - let mut _25: bool; - let mut _26: isize; - let mut _27: isize; - let mut _28: isize; -+ let _29: std::result::Result, ::Err>; -+ let _30: u32; + let mut _19: &u32; + let mut _20: &[&str; 3]; + let _21: &[&str; 3]; + let _22: [&str; 3]; + let mut _23: &[core::fmt::rt::Argument<'_>; 2]; + let _24: &[core::fmt::rt::Argument<'_>; 2]; + let mut _26: &std::boxed::Box; + let mut _27: &u32; + let mut _28: bool; + let mut _29: isize; + let mut _30: isize; + let mut _31: isize; ++ let _32: std::result::Result, ::Err>; ++ let _33: u32; scope 1 { - debug foo => _1; -+ debug ((foo: Foo).0: std::result::Result, ::Err>) => _29; -+ debug ((foo: Foo).1: u32) => _30; ++ debug ((foo: Foo).0: std::result::Result, ::Err>) => _32; ++ debug ((foo: Foo).1: u32) => _33; let _5: std::result::Result, ::Err>; scope 2 { debug x => _5; @@ -42,17 +43,29 @@ scope 4 { debug x => _8; let _8: std::boxed::Box; - let mut _24: &[&str; 3]; + let _12: (&std::boxed::Box, &u32); ++ let _34: &std::boxed::Box; ++ let _35: &u32; + scope 5 { +- debug args => _12; ++ debug ((args: (&Box, &u32)).0: &std::boxed::Box) => _34; ++ debug ((args: (&Box, &u32)).1: &u32) => _35; + let _15: [core::fmt::rt::Argument<'_>; 2]; + scope 6 { + debug args => _15; + let mut _25: &[&str; 3]; + } + } } } } } bb0: { - _25 = const false; + _28 = const false; - StorageLive(_1); -+ StorageLive(_29); -+ StorageLive(_30); ++ StorageLive(_32); ++ StorageLive(_33); + nop; StorageLive(_2); StorageLive(_3); @@ -66,77 +79,93 @@ _2 = Result::, ::Err>::Ok(move _3); StorageDead(_3); - _1 = Foo:: { x: move _2, y: const 7_u32 }; -+ _29 = move _2; -+ _30 = const 7_u32; ++ _32 = move _2; ++ _33 = const 7_u32; + nop; StorageDead(_2); StorageLive(_5); - _25 = const true; + _28 = const true; - _5 = move (_1.0: std::result::Result, ::Err>); -+ _5 = move _29; ++ _5 = move _32; StorageLive(_6); - _6 = copy (_1.1: u32); -+ _6 = copy _30; ++ _6 = copy _33; _7 = discriminant(_5); switchInt(move _7) -> [0: bb2, otherwise: bb7]; } bb2: { StorageLive(_8); - _25 = const false; + _28 = const false; _8 = move ((_5 as Ok).0: std::boxed::Box); StorageLive(_9); StorageLive(_10); StorageLive(_11); - StorageLive(_12); +- StorageLive(_12); ++ StorageLive(_34); ++ StorageLive(_35); ++ nop; StorageLive(_13); - _24 = const foo::::promoted[0]; - _13 = &(*_24); - _12 = &(*_13); + _13 = &_8; + StorageLive(_14); + _14 = &_6; +- _12 = (move _13, move _14); ++ _34 = move _13; ++ _35 = move _14; ++ nop; + StorageDead(_14); + StorageDead(_13); StorageLive(_15); StorageLive(_16); StorageLive(_17); - StorageLive(_18); - StorageLive(_19); - StorageLive(_20); - _20 = &_8; - _19 = &(*_20); - _18 = core::fmt::rt::Argument::<'_>::new_display::>(move _19) -> [return: bb3, unwind unreachable]; +- _26 = deref_copy (_12.0: &std::boxed::Box); ++ _26 = deref_copy _34; + _17 = &(*_26); + _16 = core::fmt::rt::Argument::<'_>::new_display::>(move _17) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_19); - StorageLive(_21); - StorageLive(_22); - StorageLive(_23); - _23 = &_6; - _22 = &(*_23); - _21 = core::fmt::rt::Argument::<'_>::new_display::(move _22) -> [return: bb4, unwind unreachable]; + StorageDead(_17); + StorageLive(_18); + StorageLive(_19); +- _27 = deref_copy (_12.1: &u32); ++ _27 = deref_copy _35; + _19 = &(*_27); + _18 = core::fmt::rt::Argument::<'_>::new_display::(move _19) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_22); - _17 = [move _18, move _21]; - StorageDead(_21); + StorageDead(_19); + _15 = [move _16, move _18]; StorageDead(_18); - _16 = &_17; - _15 = &(*_16); - _11 = Arguments::<'_>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable]; + StorageDead(_16); + StorageLive(_20); + StorageLive(_21); + _25 = const foo::::promoted[0]; + _21 = &(*_25); + _20 = &(*_21); + StorageLive(_23); + StorageLive(_24); + _24 = &_15; + _23 = &(*_24); + _11 = Arguments::<'_>::new_v1::<3, 2>(move _20, move _23) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_15); - StorageDead(_12); + StorageDead(_24); + StorageDead(_23); + StorageDead(_21); + StorageDead(_20); _10 = _eprint(move _11) -> [return: bb6, unwind unreachable]; } bb6: { StorageDead(_11); - StorageDead(_23); - StorageDead(_20); - StorageDead(_17); - StorageDead(_16); - StorageDead(_13); + StorageDead(_15); +- StorageDead(_12); ++ StorageDead(_34); ++ StorageDead(_35); ++ nop; StorageDead(_10); _9 = const (); StorageDead(_9); @@ -156,22 +185,22 @@ bb9: { StorageDead(_6); - _26 = discriminant(_5); - switchInt(move _26) -> [0: bb11, otherwise: bb13]; + _29 = discriminant(_5); + switchInt(move _29) -> [0: bb11, otherwise: bb13]; } bb10: { - _25 = const false; + _28 = const false; StorageDead(_5); - StorageDead(_1); -+ StorageDead(_29); -+ StorageDead(_30); ++ StorageDead(_32); ++ StorageDead(_33); + nop; return; } bb11: { - switchInt(copy _25) -> [0: bb10, otherwise: bb12]; + switchInt(copy _28) -> [0: bb10, otherwise: bb12]; } bb12: { diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr index 911c136086cfc..72580e7464b72 100644 --- a/tests/ui/borrowck/clone-on-ref.stderr +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -30,7 +30,7 @@ LL | drop(x); | ^ move out of `x` occurs here LL | LL | println!("{b}"); - | --- borrow later used here + | - borrow later used here | help: if `T` implemented `Clone`, you could clone the value --> $DIR/clone-on-ref.rs:11:8 @@ -57,7 +57,7 @@ LL | drop(x); | ^ move out of `x` occurs here LL | LL | println!("{b:?}"); - | ----- borrow later used here + | - borrow later used here | note: if `A` implemented `Clone`, you could clone the value --> $DIR/clone-on-ref.rs:19:1 diff --git a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs deleted file mode 100644 index 4a6c2f9ed0653..0000000000000 --- a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow(dead_code)] - -fn bar<'a>(_: std::fmt::Arguments<'a>) {} -fn main() { - let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3); - //~^ ERROR temporary value dropped while borrowed - - bar(x); - - let foo = format_args!("{}", "hi"); - //~^ ERROR temporary value dropped while borrowed - bar(foo); - - let foo = format_args!("hi"); // no placeholder in arguments, so no error - bar(foo); -} diff --git a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr deleted file mode 100644 index 30f292f71a280..0000000000000 --- a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-114374-invalid-help-fmt-args.rs:5:13 - | -LL | let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement - | | - | creates a temporary value which is freed while still in use -... -LL | bar(x); - | - borrow later used here - | - = note: the result of `format_args!` can only be assigned directly if no placeholders in its arguments are used - = note: to learn more, visit - -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-114374-invalid-help-fmt-args.rs:10:15 - | -LL | let foo = format_args!("{}", "hi"); - | ^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement - | | - | creates a temporary value which is freed while still in use -LL | -LL | bar(foo); - | --- borrow later used here - | - = note: the result of `format_args!` can only be assigned directly if no placeholders in its arguments are used - = note: to learn more, visit - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/recursive-const-in-impl.stderr b/tests/ui/consts/recursive-const-in-impl.stderr index 6175112c8cc0d..035d9c2f21c5a 100644 --- a/tests/ui/consts/recursive-const-in-impl.stderr +++ b/tests/ui/consts/recursive-const-in-impl.stderr @@ -1,11 +1,12 @@ error: queries overflow the depth limit! - --> $DIR/recursive-const-in-impl.rs:11:14 + --> $DIR/recursive-const-in-impl.rs:11:20 | LL | println!("{}", Thing::::X); - | ^^^^ + | ^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "14"]` attribute to your crate (`recursive_const_in_impl`) = note: query depth increased by 9 when simplifying constant for the type system `main::promoted[1]` + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr index dff9b23ba677c..d85416c8bafff 100644 --- a/tests/ui/fmt/send-sync.stderr +++ b/tests/ui/fmt/send-sync.stderr @@ -2,8 +2,10 @@ error[E0277]: `Arguments<'_>` cannot be sent between threads safely --> $DIR/send-sync.rs:8:10 | LL | send(format_args!("{:?}", c)); - | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be sent between threads safely - | | + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | `Arguments<'_>` cannot be sent between threads safely + | | this tail expression is of type `Arguments<'_>` | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `Arguments<'_>` @@ -17,8 +19,10 @@ error[E0277]: `Arguments<'_>` cannot be shared between threads safely --> $DIR/send-sync.rs:9:10 | LL | sync(format_args!("{:?}", c)); - | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be shared between threads safely - | | + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | `Arguments<'_>` cannot be shared between threads safely + | | this tail expression is of type `Arguments<'_>` | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `Arguments<'_>` diff --git a/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr b/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr index cd9ed0fb8851c..1dcd800cfc515 100644 --- a/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr +++ b/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr @@ -8,7 +8,7 @@ LL | x.push(0); | ^^^^^^^^^ mutable borrow occurs here ... LL | println!("{h}"); - | --- immutable borrow later used here + | - immutable borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/foreign-2021.rs:7:13 diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index 676b6c12f52a3..aa0f640009158 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -23,7 +23,7 @@ LL | x.push(1); | ^^^^^^^^^ mutable borrow occurs here ... LL | println!("{a}"); - | --- immutable borrow later used here + | - immutable borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:16:13 @@ -99,7 +99,7 @@ LL | x.push(1); | ^ second mutable borrow occurs here ... LL | println!("{a}"); - | --- first borrow later used here + | - first borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:63:13 @@ -175,7 +175,7 @@ LL | s.f = 1; | ^^^^^^^ `s.f` is assigned to here but it was already borrowed ... LL | println!("{a}"); - | --- borrow later used here + | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:112:13 @@ -197,7 +197,7 @@ LL | s.f = 1; | ^^^^^^^ `s.f` is assigned to here but it was already borrowed ... LL | println!("{a}"); - | --- borrow later used here + | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:128:13 @@ -219,7 +219,7 @@ LL | s.f; | ^^^ use of borrowed `s.f` ... LL | println!("{a}"); - | --- borrow later used here + | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:140:13 diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr index 3de317d2af6d1..d49cddea62482 100644 --- a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr +++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/issue-107745-avoid-expr-from-macro-expansion.rs:17:22 + --> $DIR/issue-107745-avoid-expr-from-macro-expansion.rs:17:5 | LL | println!("{:?}", []); - | ^^ cannot infer type + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/issues/issue-27592.rs b/tests/ui/issues/issue-27592.rs index 88f70f584022d..69c414e27aa96 100644 --- a/tests/ui/issues/issue-27592.rs +++ b/tests/ui/issues/issue-27592.rs @@ -15,5 +15,5 @@ impl ::std::fmt::Write for Stream { fn main() { write(|| format_args!("{}", String::from("Hello world"))); //~^ ERROR cannot return value referencing temporary value - //~| ERROR cannot return reference to temporary value + //~| ERROR cannot return reference } diff --git a/tests/ui/issues/issue-27592.stderr b/tests/ui/issues/issue-27592.stderr index c8649d82d7451..3d212a71d5987 100644 --- a/tests/ui/issues/issue-27592.stderr +++ b/tests/ui/issues/issue-27592.stderr @@ -1,3 +1,9 @@ +error[E0515]: cannot return reference to local variable `args` + --> $DIR/issue-27592.rs:16:14 + | +LL | write(|| format_args!("{}", String::from("Hello world"))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function + error[E0515]: cannot return value referencing temporary value --> $DIR/issue-27592.rs:16:14 | @@ -7,12 +13,6 @@ LL | write(|| format_args!("{}", String::from("Hello world"))); | | temporary value created here | returns a value referencing data owned by the current function -error[E0515]: cannot return reference to temporary value - --> $DIR/issue-27592.rs:16:14 - | -LL | write(|| format_args!("{}", String::from("Hello world"))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function - error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/macros/format-args-temporaries-in-write.stderr b/tests/ui/macros/format-args-temporaries-in-write.stderr index e05246cfbe38a..489987899cd73 100644 --- a/tests/ui/macros/format-args-temporaries-in-write.stderr +++ b/tests/ui/macros/format-args-temporaries-in-write.stderr @@ -13,7 +13,6 @@ LL | }; | -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard` | | | `mutex` dropped here while still borrowed - | error[E0597]: `mutex` does not live long enough --> $DIR/format-args-temporaries-in-write.rs:47:29 @@ -30,7 +29,6 @@ LL | }; | -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard` | | | `mutex` dropped here while still borrowed - | error: aborting due to 2 previous errors diff --git a/tests/ui/sized/unsized-binding.rs b/tests/ui/sized/unsized-binding.rs index 3b99b0f6e9654..ce6c15273764b 100644 --- a/tests/ui/sized/unsized-binding.rs +++ b/tests/ui/sized/unsized-binding.rs @@ -1,5 +1,5 @@ fn main() { let x = *""; //~ ERROR E0277 - println!("{}", x); - println!("{}", x); + drop(x); + drop(x); } diff --git a/tests/ui/unpretty/flattened-format-args.stdout b/tests/ui/unpretty/flattened-format-args.stdout index a5d943281ad8d..d695f513cd851 100644 --- a/tests/ui/unpretty/flattened-format-args.stdout +++ b/tests/ui/unpretty/flattened-format-args.stdout @@ -10,7 +10,10 @@ fn main() { let x = 1; // Should flatten to println!("a 123 b {x} xyz\n"): { - ::std::io::_print(format_arguments::new_v1(&["a 123 b ", " xyz\n"], - &[format_argument::new_display(&x)])); + ::std::io::_print({ + super let args = (&x,); + super let args = [format_argument::new_display(args.0)]; + format_arguments::new_v1(&["a 123 b ", " xyz\n"], &args) + }); }; } From ae1fbc5f3b27cf5344a1bd66cc645db849613d84 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 30 Mar 2025 14:41:32 +0200 Subject: [PATCH 2/6] Remove core::fmt::rt::UnsafeArg. We can now just make new_v1_formatted an unsafe fn. --- compiler/rustc_ast_lowering/src/format.rs | 42 +++++++++++------------ compiler/rustc_hir/src/lang_items.rs | 1 - compiler/rustc_span/src/symbol.rs | 1 - library/core/src/fmt/mod.rs | 3 +- library/core/src/fmt/rt.rs | 9 +++-- 5 files changed, 25 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index d04d9eb5b123f..3bfd88090d14b 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -536,34 +536,32 @@ fn expand_format_args<'hir>( let call = if let Some(format_options) = format_options { // Generate: - // ::new_v1_formatted( - // lit_pieces, - // args, - // format_options, - // unsafe { ::core::fmt::UnsafeArg::new() } - // ) + // unsafe { + // ::new_v1_formatted( + // lit_pieces, + // args, + // format_options, + // ) + // } let new_v1_formatted = ctx.arena.alloc(ctx.expr_lang_item_type_relative( macsp, hir::LangItem::FormatArguments, sym::new_v1_formatted, )); - let unsafe_arg_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative( - macsp, - hir::LangItem::FormatUnsafeArg, - sym::new, - )); - let unsafe_arg_new_call = ctx.expr_call(macsp, unsafe_arg_new, &[]); + let args = ctx.arena.alloc_from_iter([lit_pieces, args, format_options]); + let call = ctx.expr_call(macsp, new_v1_formatted, args); let hir_id = ctx.next_id(); - let unsafe_arg = ctx.expr_block(ctx.arena.alloc(hir::Block { - stmts: &[], - expr: Some(unsafe_arg_new_call), - hir_id, - rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated), - span: macsp, - targeted_by_break: false, - })); - let args = ctx.arena.alloc_from_iter([lit_pieces, args, format_options, unsafe_arg]); - hir::ExprKind::Call(new_v1_formatted, args) + hir::ExprKind::Block( + ctx.arena.alloc(hir::Block { + stmts: &[], + expr: Some(call), + hir_id, + rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated), + span: macsp, + targeted_by_break: false, + }), + None, + ) } else { // Generate: // ::new_v1( diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b9f4a8cd165d8..bc8a939883388 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -329,7 +329,6 @@ language_item_table! { FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None; FormatCount, sym::format_count, format_count, Target::Enum, GenericRequirement::None; FormatPlaceholder, sym::format_placeholder, format_placeholder, Target::Struct, GenericRequirement::None; - FormatUnsafeArg, sym::format_unsafe_arg, format_unsafe_arg, Target::Struct, GenericRequirement::None; ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None; DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 32a5aff0cb327..7d32b7a268ca4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1038,7 +1038,6 @@ symbols! { format_count, format_macro, format_placeholder, - format_unsafe_arg, freeze, freeze_impls, freg, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index f88889dadf4f4..45147284b3594 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -645,8 +645,7 @@ impl<'a> Arguments<'a> { /// Specifies nonstandard formatting parameters. /// - /// An `rt::UnsafeArg` is required because the following invariants must be held - /// in order for this function to be safe: + /// Safety: /// 1. The `pieces` slice must be at least as long as `fmt`. /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`. /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`. diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 610a206fed39f..4b55e3d32d526 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -198,17 +198,16 @@ impl Argument<'_> { } } -/// This struct represents the unsafety of constructing an `Arguments`. -/// It exists, rather than an unsafe function, in order to simplify the expansion -/// of `format_args!(..)` and reduce the scope of the `unsafe` block. +/// Bootstrap only. +#[cfg(bootstrap)] #[lang = "format_unsafe_arg"] pub struct UnsafeArg { _private: (), } +#[cfg(bootstrap)] impl UnsafeArg { - /// See documentation where `UnsafeArg` is required to know when it is safe to - /// create and use `UnsafeArg`. + /// Bootstrap only. #[inline] pub const unsafe fn new() -> Self { Self { _private: () } From 3d92ac492d7d98d603f82a7876f13b3802c8386a Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 31 Mar 2025 16:43:40 +0200 Subject: [PATCH 3/6] Bless clippy tests. --- .../tests/ui/author/macro_in_closure.stdout | 61 ++++++++++++------- .../tests/ui/author/macro_in_loop.stdout | 57 +++++++++++------ .../clippy/tests/ui/manual_inspect.fixed | 1 - src/tools/clippy/tests/ui/manual_inspect.rs | 1 - .../clippy/tests/ui/manual_inspect.stderr | 21 +------ 5 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/tools/clippy/tests/ui/author/macro_in_closure.stdout b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout index 3186d0cbc276c..6efb654c582fe 100644 --- a/src/tools/clippy/tests/ui/author/macro_in_closure.stdout +++ b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout @@ -10,32 +10,51 @@ if let StmtKind::Let(local) = stmt.kind && let ExprKind::Path(ref qpath) = func.kind && match_qpath(qpath, &["$crate", "io", "_print"]) && args.len() == 1 - && let ExprKind::Call(func1, args1) = args[0].kind - && let ExprKind::Path(ref qpath1) = func1.kind - && match_qpath(qpath1, &["format_arguments", "new_v1"]) - && args1.len() == 2 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind - && let ExprKind::Array(elements) = inner.kind - && elements.len() == 2 - && let ExprKind::Lit(ref lit) = elements[0].kind + && let ExprKind::Block(block1, None) = args[0].kind + && block1.stmts.len() == 2 + && let StmtKind::Let(local1) = block1.stmts[0].kind + && let Some(init1) = local1.init + && let ExprKind::Tup(elements) = init1.kind + && elements.len() == 1 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = elements[0].kind + && let ExprKind::Path(ref qpath1) = inner.kind + && match_qpath(qpath1, &["x"]) + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind + && name.as_str() == "args" + && let StmtKind::Let(local2) = block1.stmts[1].kind + && let Some(init2) = local2.init + && let ExprKind::Array(elements1) = init2.kind + && elements1.len() == 1 + && let ExprKind::Call(func1, args1) = elements1[0].kind + && let ExprKind::Path(ref qpath2) = func1.kind + && match_qpath(qpath2, &["format_argument", "new_display"]) + && args1.len() == 1 + && let ExprKind::Field(object, field_name) = args1[0].kind + && field_name.as_str() == "0" + && let ExprKind::Path(ref qpath3) = object.kind + && match_qpath(qpath3, &["args"]) + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local2.pat.kind + && name1.as_str() == "args" + && let Some(trailing_expr) = block1.expr + && let ExprKind::Call(func2, args2) = trailing_expr.kind + && let ExprKind::Path(ref qpath4) = func2.kind + && match_qpath(qpath4, &["format_arguments", "new_v1"]) + && args2.len() == 2 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind + && let ExprKind::Array(elements2) = inner1.kind + && elements2.len() == 2 + && let ExprKind::Lit(ref lit) = elements2[0].kind && let LitKind::Str(s, _) = lit.node && s.as_str() == "" - && let ExprKind::Lit(ref lit1) = elements[1].kind + && let ExprKind::Lit(ref lit1) = elements2[1].kind && let LitKind::Str(s1, _) = lit1.node && s1.as_str() == "\n" - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind - && let ExprKind::Array(elements1) = inner1.kind - && elements1.len() == 1 - && let ExprKind::Call(func2, args2) = elements1[0].kind - && let ExprKind::Path(ref qpath2) = func2.kind - && match_qpath(qpath2, &["format_argument", "new_display"]) - && args2.len() == 1 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind - && let ExprKind::Path(ref qpath3) = inner2.kind - && match_qpath(qpath3, &["x"]) + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind + && let ExprKind::Path(ref qpath5) = inner2.kind + && match_qpath(qpath5, &["args"]) && block.expr.is_none() - && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind - && name.as_str() == "print_text" + && let PatKind::Binding(BindingMode::NONE, _, name2, None) = local.pat.kind + && name2.as_str() == "print_text" { // report your lint here } diff --git a/src/tools/clippy/tests/ui/author/macro_in_loop.stdout b/src/tools/clippy/tests/ui/author/macro_in_loop.stdout index 3f9be297c33c5..5932148dc3fbd 100644 --- a/src/tools/clippy/tests/ui/author/macro_in_loop.stdout +++ b/src/tools/clippy/tests/ui/author/macro_in_loop.stdout @@ -20,29 +20,48 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo && let ExprKind::Path(ref qpath1) = func.kind && match_qpath(qpath1, &["$crate", "io", "_print"]) && args.len() == 1 - && let ExprKind::Call(func1, args1) = args[0].kind - && let ExprKind::Path(ref qpath2) = func1.kind - && match_qpath(qpath2, &["format_arguments", "new_v1"]) - && args1.len() == 2 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind - && let ExprKind::Array(elements) = inner.kind - && elements.len() == 2 - && let ExprKind::Lit(ref lit2) = elements[0].kind + && let ExprKind::Block(block2, None) = args[0].kind + && block2.stmts.len() == 2 + && let StmtKind::Let(local) = block2.stmts[0].kind + && let Some(init) = local.init + && let ExprKind::Tup(elements) = init.kind + && elements.len() == 1 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = elements[0].kind + && let ExprKind::Path(ref qpath2) = inner.kind + && match_qpath(qpath2, &["i"]) + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind + && name1.as_str() == "args" + && let StmtKind::Let(local1) = block2.stmts[1].kind + && let Some(init1) = local1.init + && let ExprKind::Array(elements1) = init1.kind + && elements1.len() == 1 + && let ExprKind::Call(func1, args1) = elements1[0].kind + && let ExprKind::Path(ref qpath3) = func1.kind + && match_qpath(qpath3, &["format_argument", "new_display"]) + && args1.len() == 1 + && let ExprKind::Field(object, field_name) = args1[0].kind + && field_name.as_str() == "0" + && let ExprKind::Path(ref qpath4) = object.kind + && match_qpath(qpath4, &["args"]) + && let PatKind::Binding(BindingMode::NONE, _, name2, None) = local1.pat.kind + && name2.as_str() == "args" + && let Some(trailing_expr) = block2.expr + && let ExprKind::Call(func2, args2) = trailing_expr.kind + && let ExprKind::Path(ref qpath5) = func2.kind + && match_qpath(qpath5, &["format_arguments", "new_v1"]) + && args2.len() == 2 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind + && let ExprKind::Array(elements2) = inner1.kind + && elements2.len() == 2 + && let ExprKind::Lit(ref lit2) = elements2[0].kind && let LitKind::Str(s, _) = lit2.node && s.as_str() == "" - && let ExprKind::Lit(ref lit3) = elements[1].kind + && let ExprKind::Lit(ref lit3) = elements2[1].kind && let LitKind::Str(s1, _) = lit3.node && s1.as_str() == "\n" - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind - && let ExprKind::Array(elements1) = inner1.kind - && elements1.len() == 1 - && let ExprKind::Call(func2, args2) = elements1[0].kind - && let ExprKind::Path(ref qpath3) = func2.kind - && match_qpath(qpath3, &["format_argument", "new_display"]) - && args2.len() == 1 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind - && let ExprKind::Path(ref qpath4) = inner2.kind - && match_qpath(qpath4, &["i"]) + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind + && let ExprKind::Path(ref qpath6) = inner2.kind + && match_qpath(qpath6, &["args"]) && block1.expr.is_none() && block.expr.is_none() { diff --git a/src/tools/clippy/tests/ui/manual_inspect.fixed b/src/tools/clippy/tests/ui/manual_inspect.fixed index 44f15d61f8563..76cf239b9cff3 100644 --- a/src/tools/clippy/tests/ui/manual_inspect.fixed +++ b/src/tools/clippy/tests/ui/manual_inspect.fixed @@ -154,7 +154,6 @@ fn main() { }); let _ = [0] - //~^ suspicious_map .into_iter() .inspect(|&x| { //~^ manual_inspect diff --git a/src/tools/clippy/tests/ui/manual_inspect.rs b/src/tools/clippy/tests/ui/manual_inspect.rs index d34f2abce6ae1..67ce49fef92db 100644 --- a/src/tools/clippy/tests/ui/manual_inspect.rs +++ b/src/tools/clippy/tests/ui/manual_inspect.rs @@ -165,7 +165,6 @@ fn main() { }); let _ = [0] - //~^ suspicious_map .into_iter() .map(|x| { //~^ manual_inspect diff --git a/src/tools/clippy/tests/ui/manual_inspect.stderr b/src/tools/clippy/tests/ui/manual_inspect.stderr index 510325d2baaa9..1d48939de77e4 100644 --- a/src/tools/clippy/tests/ui/manual_inspect.stderr +++ b/src/tools/clippy/tests/ui/manual_inspect.stderr @@ -157,25 +157,8 @@ LL | LL ~ println!("{}", x); | -error: this call to `map()` won't have an effect on the call to `count()` - --> tests/ui/manual_inspect.rs:167:13 - | -LL | let _ = [0] - | _____________^ -LL | | -LL | | .into_iter() -LL | | .map(|x| { -... | -LL | | }) -LL | | .count(); - | |________________^ - | - = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect` - = note: `-D clippy::suspicious-map` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]` - error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:170:10 + --> tests/ui/manual_inspect.rs:169:10 | LL | .map(|x| { | ^^^ @@ -187,5 +170,5 @@ LL | LL ~ println!("{}", x); | -error: aborting due to 13 previous errors +error: aborting due to 12 previous errors From 9565f193d6bf996085210c6ecfd55dea292a747e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 9 Apr 2025 17:43:58 +0200 Subject: [PATCH 4/6] Update tests. --- tests/coverage/issue-83601.cov-map | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map index f102310900894..85f03084be880 100644 --- a/tests/coverage/issue-83601.cov-map +++ b/tests/coverage/issue-83601.cov-map @@ -1,13 +1,11 @@ Function name: issue_83601::main -Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 0f, 05, 03, 09, 01, 0f, 02, 02, 05, 03, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 06, 01, 02, 0f, 01, 03, 09, 01, 0f, 01, 02, 05, 03, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 1 -- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 6, 1) to (start + 2, 15) -- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2) - = (c1 - c2) -Highest counter ID seen: c1 +- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 15) +- Code(Counter(0)) at (prev + 2, 5) to (start + 3, 2) +Highest counter ID seen: c0 From 3fbcdc092589048a8b53625ad54707ace45cfce5 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 9 Apr 2025 17:44:11 +0200 Subject: [PATCH 5/6] Remove some known-bug equal-pointers-unequal tests. These tests rely on internal implementation details of format_args!(), which have changed now. --- .../equal-pointers-unequal/as-cast/basic.rs | 21 ---------------- .../as-cast/function.rs | 22 ----------------- .../equal-pointers-unequal/as-cast/print.rs | 20 ---------------- .../exposed-provenance/basic.rs | 23 ------------------ .../exposed-provenance/function.rs | 24 ------------------- .../exposed-provenance/print.rs | 22 ----------------- .../strict-provenance/basic.rs | 23 ------------------ .../strict-provenance/function.rs | 24 ------------------- .../strict-provenance/print.rs | 22 ----------------- 9 files changed, 201 deletions(-) delete mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs deleted file mode 100644 index e2a00ce173d14..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -fn main() { - let a: usize = { - let v = 0u8; - &v as *const _ as usize - }; - let b: usize = { - let v = 0u8; - &v as *const _ as usize - }; - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs deleted file mode 100644 index 15434de50f76c..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 - -fn f() -> usize { - let v = 0; - &v as *const _ as usize -} - -fn main() { - let a = f(); - let b = f(); - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs deleted file mode 100644 index f33a9e511b61a..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 - -fn main() { - let a = { - let v = 0; - &v as *const _ as usize - }; - let b = { - let v = 0; - &v as *const _ as usize - }; - - assert_ne!(a, b); - println!("{a}"); // or b - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs deleted file mode 100644 index b2b4934aa5f18..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0u8; - ptr::from_ref(&v).expose_provenance() - }; - let b: usize = { - let v = 0u8; - ptr::from_ref(&v).expose_provenance() - }; - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs deleted file mode 100644 index bf130c9f75982..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 - -use std::ptr; - -fn f() -> usize { - let v = 0; - ptr::from_ref(&v).expose_provenance() -} - -fn main() { - let a = f(); - let b = f(); - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs deleted file mode 100644 index 0baf8886395e8..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0; - ptr::from_ref(&v).expose_provenance() - }; - let b: usize = { - let v = 0; - ptr::from_ref(&v).expose_provenance() - }; - - assert_ne!(a, b); - println!("{a}"); // or b - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs deleted file mode 100644 index 4602ec654d107..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0u8; - ptr::from_ref(&v).addr() - }; - let b: usize = { - let v = 0u8; - ptr::from_ref(&v).addr() - }; - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs deleted file mode 100644 index 789a78c15b4e2..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 - -use std::ptr; - -fn f() -> usize { - let v = 0; - ptr::from_ref(&v).addr() -} - -fn main() { - let a = f(); - let b = f(); - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs deleted file mode 100644 index b7165ce1e5ce3..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0; - ptr::from_ref(&v).addr() - }; - let b: usize = { - let v = 0; - ptr::from_ref(&v).addr() - }; - - assert_ne!(a, b); - println!("{a}"); // or b - assert_eq!(a, b); -} From b016d9c9a121a97a5a6890489743a01b4991731e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 22 Apr 2025 22:07:29 +0200 Subject: [PATCH 6/6] Make fmt::Arguments::new_* functions non-const. --- .../rustc_const_eval/src/check_consts/ops.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/fmt/mod.rs | 5 +++++ library/core/src/fmt/rt.rs | 21 +++++++++---------- tests/ui/consts/const-eval/format.stderr | 8 +++---- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 7756e51c4c5f2..1e5b98675c4f0 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -352,7 +352,7 @@ fn build_error_for_const_call<'tcx>( ); err } - _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentMethods) => { + _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => { ccx.dcx().create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind(), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7d32b7a268ca4..f60b903c7670d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -174,7 +174,6 @@ symbols! { Arc, ArcWeak, Argument, - ArgumentMethods, ArrayIntoIter, AsMut, AsRef, @@ -249,6 +248,7 @@ symbols! { Error, File, FileType, + FmtArgumentsNew, Fn, FnMut, FnOnce, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 45147284b3594..36922aeb2992e 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -625,6 +625,7 @@ pub struct Arguments<'a> { /// Used by the format_args!() macro to create a fmt::Arguments object. #[doc(hidden)] #[unstable(feature = "fmt_internals", issue = "none")] +#[rustc_diagnostic_item = "FmtArgumentsNew"] impl<'a> Arguments<'a> { #[inline] pub const fn new_const(pieces: &'a [&'static str; N]) -> Self { @@ -670,7 +671,11 @@ impl<'a> Arguments<'a> { ) -> Arguments<'a> { Arguments { pieces, fmt: Some(fmt), args } } +} +#[doc(hidden)] +#[unstable(feature = "fmt_internals", issue = "none")] +impl<'a> Arguments<'a> { /// Estimates the length of the formatted text. /// /// This is intended to be used for setting initial `String` capacity diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 4b55e3d32d526..e8202a30ba5d3 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -110,46 +110,45 @@ macro_rules! argument_new { }; } -#[rustc_diagnostic_item = "ArgumentMethods"] impl Argument<'_> { #[inline] - pub fn new_display(x: &T) -> Argument<'_> { + pub const fn new_display(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_debug(x: &T) -> Argument<'_> { + pub const fn new_debug(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_debug_noop(x: &T) -> Argument<'_> { + pub const fn new_debug_noop(x: &T) -> Argument<'_> { argument_new!(T, x, |_: &T, _| Ok(())) } #[inline] - pub fn new_octal(x: &T) -> Argument<'_> { + pub const fn new_octal(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_lower_hex(x: &T) -> Argument<'_> { + pub const fn new_lower_hex(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_upper_hex(x: &T) -> Argument<'_> { + pub const fn new_upper_hex(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_pointer(x: &T) -> Argument<'_> { + pub const fn new_pointer(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_binary(x: &T) -> Argument<'_> { + pub const fn new_binary(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_lower_exp(x: &T) -> Argument<'_> { + pub const fn new_lower_exp(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_upper_exp(x: &T) -> Argument<'_> { + pub const fn new_upper_exp(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index e8d7bbcea0917..0f617cac7bae9 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -1,16 +1,16 @@ error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:2:13 + --> $DIR/format.rs:2:5 | LL | panic!("{:?}", 0); - | ^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:7:15 + --> $DIR/format.rs:7:5 | LL | println!("{:?}", 0); - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)