diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 0de0319c66763..e5da92bdebc94 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,17 +474,6 @@ 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() { // Generate: // &::none() @@ -510,31 +497,6 @@ fn expand_format_args<'hir>( )); 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) } else { // Generate: // &match (&arg0, &arg1, &…) { @@ -635,34 +597,6 @@ fn expand_format_args<'hir>( } } -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(()) - } - } - - MayContainYieldPoint.visit_expr(e).is_break() -} - fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) { for piece in template { let FormatArgsPiece::Placeholder(placeholder) = piece else { continue }; diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index a1df868cde051..e6630d259bf98 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -17,22 +17,27 @@ let mut _15: &[core::fmt::rt::Argument<'_>; 2]; let _16: &[core::fmt::rt::Argument<'_>; 2]; let _17: [core::fmt::rt::Argument<'_>; 2]; - let mut _18: core::fmt::rt::Argument<'_>; + let mut _18: (&std::boxed::Box, &u32); 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 _20: &u32; + let mut _22: core::fmt::rt::Argument<'_>; + let mut _23: &std::boxed::Box; + let mut _24: core::fmt::rt::Argument<'_>; + let mut _25: &u32; + let mut _27: &std::boxed::Box; + let mut _28: &u32; + let mut _29: bool; + let mut _30: isize; + let mut _31: isize; + let mut _32: isize; ++ let _33: std::result::Result, ::Err>; ++ let _34: u32; ++ let mut _37: &std::boxed::Box; ++ let mut _38: &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>) => _33; ++ debug ((foo: Foo).1: u32) => _34; let _5: std::result::Result, ::Err>; scope 2 { debug x => _5; @@ -42,17 +47,25 @@ scope 4 { debug x => _8; let _8: std::boxed::Box; - let mut _24: &[&str; 3]; + let _21: (&std::boxed::Box, &u32); + let mut _26: &[&str; 3]; ++ let _35: &std::boxed::Box; ++ let _36: &u32; + scope 5 { +- debug args => _21; ++ debug ((args: (&Box, &u32)).0: &std::boxed::Box) => _35; ++ debug ((args: (&Box, &u32)).1: &u32) => _36; + } } } } } bb0: { - _25 = const false; + _29 = const false; - StorageLive(_1); -+ StorageLive(_29); -+ StorageLive(_30); ++ StorageLive(_33); ++ StorageLive(_34); + nop; StorageLive(_2); StorageLive(_3); @@ -66,59 +79,85 @@ _2 = Result::, ::Err>::Ok(move _3); StorageDead(_3); - _1 = Foo:: { x: move _2, y: const 7_u32 }; -+ _29 = move _2; -+ _30 = const 7_u32; ++ _33 = move _2; ++ _34 = const 7_u32; + nop; StorageDead(_2); StorageLive(_5); - _25 = const true; + _29 = const true; - _5 = move (_1.0: std::result::Result, ::Err>); -+ _5 = move _29; ++ _5 = move _33; StorageLive(_6); - _6 = copy (_1.1: u32); -+ _6 = copy _30; ++ _6 = copy _34; _7 = discriminant(_5); switchInt(move _7) -> [0: bb2, otherwise: bb7]; } bb2: { StorageLive(_8); - _25 = const false; + _29 = const false; _8 = move ((_5 as Ok).0: std::boxed::Box); StorageLive(_9); StorageLive(_10); StorageLive(_11); StorageLive(_12); StorageLive(_13); - _24 = const foo::::promoted[0]; - _13 = &(*_24); + _26 = const foo::::promoted[0]; + _13 = &(*_26); _12 = &(*_13); StorageLive(_15); StorageLive(_16); StorageLive(_17); - StorageLive(_18); +- StorageLive(_18); ++ StorageLive(_37); ++ StorageLive(_38); ++ nop; StorageLive(_19); + _19 = &_8; StorageLive(_20); - _20 = &_8; - _19 = &(*_20); - _18 = core::fmt::rt::Argument::<'_>::new_display::>(move _19) -> [return: bb3, unwind unreachable]; - } - - bb3: { + _20 = &_6; +- _18 = (move _19, move _20); ++ _37 = move _19; ++ _38 = move _20; ++ nop; + StorageDead(_20); StorageDead(_19); - StorageLive(_21); +- StorageLive(_21); +- _21 = copy _18; ++ StorageLive(_35); ++ StorageLive(_36); ++ nop; ++ _35 = copy _37; ++ _36 = copy _38; ++ nop; StorageLive(_22); StorageLive(_23); - _23 = &_6; - _22 = &(*_23); - _21 = core::fmt::rt::Argument::<'_>::new_display::(move _22) -> [return: bb4, unwind unreachable]; +- _27 = deref_copy (_21.0: &std::boxed::Box); ++ _27 = deref_copy _35; + _23 = &(*_27); + _22 = core::fmt::rt::Argument::<'_>::new_display::>(move _23) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_23); + StorageLive(_24); + StorageLive(_25); +- _28 = deref_copy (_21.1: &u32); ++ _28 = deref_copy _36; + _25 = &(*_28); + _24 = core::fmt::rt::Argument::<'_>::new_display::(move _25) -> [return: bb4, unwind unreachable]; } bb4: { + StorageDead(_25); + _17 = [move _22, move _24]; + StorageDead(_24); StorageDead(_22); - _17 = [move _18, move _21]; - StorageDead(_21); - StorageDead(_18); +- StorageDead(_21); ++ StorageDead(_35); ++ StorageDead(_36); ++ nop; _16 = &_17; _15 = &(*_16); _11 = Arguments::<'_>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable]; @@ -132,8 +171,10 @@ bb6: { StorageDead(_11); - StorageDead(_23); - StorageDead(_20); +- StorageDead(_18); ++ StorageDead(_37); ++ StorageDead(_38); ++ nop; StorageDead(_17); StorageDead(_16); StorageDead(_13); @@ -156,22 +197,22 @@ bb9: { StorageDead(_6); - _26 = discriminant(_5); - switchInt(move _26) -> [0: bb11, otherwise: bb13]; + _30 = discriminant(_5); + switchInt(move _30) -> [0: bb11, otherwise: bb13]; } bb10: { - _25 = const false; + _29 = const false; StorageDead(_5); - StorageDead(_1); -+ StorageDead(_29); -+ StorageDead(_30); ++ StorageDead(_33); ++ StorageDead(_34); + nop; return; } bb11: { - switchInt(copy _25) -> [0: bb10, otherwise: bb12]; + switchInt(copy _29) -> [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/codegen/equal-pointers-unequal/as-cast/print3.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs deleted file mode 100644 index eda83e999a528..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs +++ /dev/null @@ -1,23 +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); - assert_ne!(a, b); - let c = a; - assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false"); - println!("{a} {b}"); - assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true"); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs deleted file mode 100644 index c7f46318aaef7..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs +++ /dev/null @@ -1,25 +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); - assert_ne!(a, b); - let c = a; - assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false"); - println!("{a} {b}"); - assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true"); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs deleted file mode 100644 index a02ff30918daf..0000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs +++ /dev/null @@ -1,25 +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); - assert_ne!(a, b); - let c = a; - assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false"); - println!("{a} {b}"); - assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true"); -} 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/sized/unsized-binding.rs b/tests/ui/sized/unsized-binding.rs index 3b99b0f6e9654..7d41071861204 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); + println!("{}", x); //~ ERROR E0277 + println!("{}", x); //~ ERROR E0277 } diff --git a/tests/ui/sized/unsized-binding.stderr b/tests/ui/sized/unsized-binding.stderr index 8de236cd0b6e0..45176bea1d113 100644 --- a/tests/ui/sized/unsized-binding.stderr +++ b/tests/ui/sized/unsized-binding.stderr @@ -13,6 +13,32 @@ LL - let x = *""; LL + let x = ""; | -error: aborting due to 1 previous error +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-binding.rs:3:20 + | +LL | println!("{}", x); + | -- ^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` +note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'_>::new_display` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL + = 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[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-binding.rs:4:20 + | +LL | println!("{}", x); + | -- ^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` +note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'_>::new_display` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL + = 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 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unpretty/flattened-format-args.stdout b/tests/ui/unpretty/flattened-format-args.stdout index 2de1cdd96b5b7..2436266b4ab33 100644 --- a/tests/ui/unpretty/flattened-format-args.stdout +++ b/tests/ui/unpretty/flattened-format-args.stdout @@ -10,6 +10,8 @@ fn main() { // 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)])); + &match (&x,) { + args => [format_argument::new_display(args.0)], + })); }; }