From 2a8513d221cfeb76c284a47e972961d22bdf65ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 01/10] Replace visitor with a loop over blocks and statements --- .../src/cleanup_post_borrowck.rs | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 3378923c22c..c33d72179ad 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -19,21 +19,24 @@ //! [`Nop`]: rustc_middle::mir::StatementKind::Nop use crate::MirPass; -use rustc_middle::mir::visit::MutVisitor; -use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue}; -use rustc_middle::mir::{Statement, StatementKind}; +use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind}; use rustc_middle::ty::TyCtxt; pub struct CleanupNonCodegenStatements; -pub struct DeleteNonCodegenStatements<'tcx> { - tcx: TyCtxt<'tcx>, -} - impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut delete = DeleteNonCodegenStatements { tcx }; - delete.visit_body_preserves_cfg(body); + fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + for basic_block in body.basic_blocks.as_mut_preserves_cfg() { + for statement in basic_block.statements.iter_mut() { + match statement.kind { + StatementKind::AscribeUserType(..) + | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) + | StatementKind::FakeRead(..) => statement.make_nop(), + _ => (), + } + } + } + body.user_type_annotations.raw.clear(); for decl in &mut body.local_decls { @@ -41,19 +44,3 @@ impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { } } } - -impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { - match statement.kind { - StatementKind::AscribeUserType(..) - | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) - | StatementKind::FakeRead(..) => statement.make_nop(), - _ => (), - } - self.super_statement(statement, location); - } -} From 4c3efc7f1b2dc4a815d3690c6995bed5a8c63ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 02/10] Rename CleanupNonCodegenStatements to CleanupPostBorrowck --- compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs | 4 ++-- compiler/rustc_mir_transform/src/lib.rs | 2 +- src/test/mir-opt/remove_fake_borrows.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index c33d72179ad..fe5295aface 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -22,9 +22,9 @@ use crate::MirPass; use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind}; use rustc_middle::ty::TyCtxt; -pub struct CleanupNonCodegenStatements; +pub struct CleanupPostBorrowck; -impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { +impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { for basic_block in body.basic_blocks.as_mut_preserves_cfg() { for statement in basic_block.statements.iter_mut() { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 93200b28830..e28406ce67e 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -497,7 +497,7 @@ fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &remove_false_edges::RemoveFalseEdges, &simplify_branches::SimplifyConstCondition::new("initial"), &remove_noop_landing_pads::RemoveNoopLandingPads, - &cleanup_post_borrowck::CleanupNonCodegenStatements, + &cleanup_post_borrowck::CleanupPostBorrowck, &simplify::SimplifyCfg::new("early-opt"), &deref_separator::Derefer, ]; diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs index a980f386b69..d26c6f5d7e5 100644 --- a/src/test/mir-opt/remove_fake_borrows.rs +++ b/src/test/mir-opt/remove_fake_borrows.rs @@ -2,7 +2,7 @@ // ignore-wasm32-bare compiled with panic=abort by default -// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +// EMIT_MIR remove_fake_borrows.match_guard.CleanupPostBorrowck.diff fn match_guard(x: Option<&&i32>, c: bool) -> i32 { match x { Some(0) if c => 0, From 62f9084dfa58cfb395606128bc5d33ef483d1c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 03/10] Remove false edges in CleanupPostBorrowck --- .../src/cleanup_post_borrowck.rs | 28 +++++++++--------- compiler/rustc_mir_transform/src/lib.rs | 5 +--- .../src/remove_false_edges.rs | 29 ------------------- 3 files changed, 16 insertions(+), 46 deletions(-) delete mode 100644 compiler/rustc_mir_transform/src/remove_false_edges.rs diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index fe5295aface..d435d3ee69b 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -1,32 +1,26 @@ -//! This module provides a pass to replacing the following statements with -//! [`Nop`]s +//! This module provides a pass that removes parts of MIR that are no longer relevant after +//! analysis phase and borrowck. In particular, it removes false edges, user type annotations and +//! replaces following statements with [`Nop`]s: //! //! - [`AscribeUserType`] //! - [`FakeRead`] //! - [`Assign`] statements with a [`Shallow`] borrow //! -//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two -//! traversals (aka visits) of the input MIR. The first traversal, -//! `DeleteAndRecordFakeReads`, deletes the fake reads and finds the -//! temporaries read by [`ForMatchGuard`] reads, and `DeleteFakeBorrows` -//! deletes the initialization of those temporaries. -//! //! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType -//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow -//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead //! [`Assign`]: rustc_middle::mir::StatementKind::Assign -//! [`ForMatchGuard`]: rustc_middle::mir::FakeReadCause::ForMatchGuard +//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead //! [`Nop`]: rustc_middle::mir::StatementKind::Nop +//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow use crate::MirPass; -use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind}; +use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind}; use rustc_middle::ty::TyCtxt; pub struct CleanupPostBorrowck; impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - for basic_block in body.basic_blocks.as_mut_preserves_cfg() { + for basic_block in body.basic_blocks.as_mut() { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) @@ -35,6 +29,14 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { _ => (), } } + let terminator = basic_block.terminator_mut(); + match terminator.kind { + TerminatorKind::FalseEdge { real_target, .. } + | TerminatorKind::FalseUnwind { real_target, .. } => { + terminator.kind = TerminatorKind::Goto { target: real_target }; + } + _ => {} + } } body.user_type_annotations.raw.clear(); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e28406ce67e..aba5a8580f1 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -77,8 +77,6 @@ mod match_branches; mod multiple_return_terminators; mod normalize_array_len; mod nrvo; -// This pass is public to allow external drivers to perform MIR cleanup -pub mod remove_false_edges; mod remove_noop_landing_pads; mod remove_storage_markers; mod remove_uninit_drops; @@ -494,10 +492,9 @@ fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx> /// After this series of passes, no lifetime analysis based on borrowing can be done. fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let passes: &[&dyn MirPass<'tcx>] = &[ - &remove_false_edges::RemoveFalseEdges, + &cleanup_post_borrowck::CleanupPostBorrowck, &simplify_branches::SimplifyConstCondition::new("initial"), &remove_noop_landing_pads::RemoveNoopLandingPads, - &cleanup_post_borrowck::CleanupPostBorrowck, &simplify::SimplifyCfg::new("early-opt"), &deref_separator::Derefer, ]; diff --git a/compiler/rustc_mir_transform/src/remove_false_edges.rs b/compiler/rustc_mir_transform/src/remove_false_edges.rs deleted file mode 100644 index 71f5ccf7e24..00000000000 --- a/compiler/rustc_mir_transform/src/remove_false_edges.rs +++ /dev/null @@ -1,29 +0,0 @@ -use rustc_middle::mir::{Body, TerminatorKind}; -use rustc_middle::ty::TyCtxt; - -use crate::MirPass; - -/// Removes `FalseEdge` and `FalseUnwind` terminators from the MIR. -/// -/// These are only needed for borrow checking, and can be removed afterwards. -/// -/// FIXME: This should probably have its own MIR phase. -pub struct RemoveFalseEdges; - -impl<'tcx> MirPass<'tcx> for RemoveFalseEdges { - fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - for block in body.basic_blocks_mut() { - let terminator = block.terminator_mut(); - terminator.kind = match terminator.kind { - TerminatorKind::FalseEdge { real_target, .. } => { - TerminatorKind::Goto { target: real_target } - } - TerminatorKind::FalseUnwind { real_target, .. } => { - TerminatorKind::Goto { target: real_target } - } - - _ => continue, - } - } - } -} From acaa2c1235080aa1dc66133f840f7b5aa37dd016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 04/10] ./x.py test --bless --- ...e_borrows.match_guard.CleanupPostBorrowck.diff} | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) rename src/test/mir-opt/{remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff => remove_fake_borrows.match_guard.CleanupPostBorrowck.diff} (90%) diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff similarity index 90% rename from src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff rename to src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff index bb5920b28ca..0b3da98a5a1 100644 --- a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff @@ -1,5 +1,5 @@ -- // MIR for `match_guard` before CleanupNonCodegenStatements -+ // MIR for `match_guard` after CleanupNonCodegenStatements +- // MIR for `match_guard` before CleanupPostBorrowck ++ // MIR for `match_guard` after CleanupPostBorrowck fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 { debug x => _1; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17 @@ -29,7 +29,8 @@ } bb3: { - goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 +- falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 ++ goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 } bb4: { @@ -62,15 +63,12 @@ bb6: { StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 - goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 } bb7: { return; // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2 } - - bb8 (cleanup): { - resume; // scope 0 at $DIR/remove_fake_borrows.rs:+0:1: +5:2 - } } From 4251289f27949cec69d8aa39d3891a4977fbc856 Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Mon, 19 Dec 2022 17:38:18 -0800 Subject: [PATCH 05/10] Disable `NormalizeArrayLen` --- .../rustc_mir_transform/src/normalize_array_len.rs | 3 ++- .../const_prop/slice_len.main.ConstProp.32bit.diff | 7 ++----- .../const_prop/slice_len.main.ConstProp.64bit.diff | 7 ++----- .../issue_76432.test.SimplifyComparisonIntegral.diff | 12 +++++------- src/test/mir-opt/lower_array_len_e2e.rs | 2 +- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index a159e617178..1708b287e56 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -16,7 +16,8 @@ pub struct NormalizeArrayLen; impl<'tcx> MirPass<'tcx> for NormalizeArrayLen { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 4 + // See #105929 + sess.mir_opt_level() >= 4 && sess.opts.unstable_opts.unsound_mir_opts } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff index 624376769b7..44445731e72 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff @@ -12,7 +12,6 @@ let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 bb0: { StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 @@ -25,16 +24,14 @@ // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19 StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 - _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 - StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 - _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 } diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff index 624376769b7..44445731e72 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff @@ -12,7 +12,6 @@ let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 bb0: { StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 @@ -25,16 +24,14 @@ // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19 StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 - _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 - StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 - _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 } diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index 2368c021eda..e97b46f6ecc 100644 --- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -22,7 +22,6 @@ let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84 let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84 let mut _22: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL - let mut _23: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 scope 1 { debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10 let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 @@ -52,17 +51,16 @@ StorageDead(_6); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 _4 = &_5; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 _3 = _4; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 - StorageLive(_23); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 - _23 = _3; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 StorageDead(_3); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 StorageDead(_4); // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30 StorageLive(_9); // scope 1 at $DIR/issue_76432.rs:+2:5: +5:6 - _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 - StorageDead(_23); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _10 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 _11 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 - _12 = const true; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 - goto -> bb2; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- _12 = Eq(move _10, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- switchInt(move _12) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ nop; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ switchInt(move _10) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 } bb1: { diff --git a/src/test/mir-opt/lower_array_len_e2e.rs b/src/test/mir-opt/lower_array_len_e2e.rs index 49b35d509f0..d8e4e521ee6 100644 --- a/src/test/mir-opt/lower_array_len_e2e.rs +++ b/src/test/mir-opt/lower_array_len_e2e.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 +// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts // EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir pub fn array_bound(index: usize, slice: &[u8; N]) -> u8 { From 8c73ce6611e08c09c2ba6344c1fc9168e2daed55 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Mon, 19 Dec 2022 23:08:38 -0800 Subject: [PATCH 06/10] Update coerce_unsized tracking issue from #27732 to #18598 Issue #27732 was closed as a duplicate of #18598. Signed-off-by: Anders Kaseorg --- library/alloc/src/boxed.rs | 2 +- library/alloc/src/rc.rs | 4 ++-- library/alloc/src/sync.rs | 4 ++-- library/core/src/cell.rs | 12 ++++++------ library/core/src/marker.rs | 2 +- library/core/src/ops/mod.rs | 2 +- library/core/src/ops/unsize.rs | 20 ++++++++++---------- library/core/src/ptr/non_null.rs | 2 +- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e5f6b0c0c65..b154688fb08 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2033,7 +2033,7 @@ impl + ?Sized, A: Allocator> Fn for Box { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 38e31b1802a..80a5913daa6 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -336,7 +336,7 @@ impl UnwindSafe for Rc {} #[stable(feature = "rc_ref_unwind_safe", since = "1.58.0")] impl RefUnwindSafe for Rc {} -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized> for Rc {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] @@ -2190,7 +2190,7 @@ impl !marker::Send for Weak {} #[stable(feature = "rc_weak", since = "1.4.0")] impl !marker::Sync for Weak {} -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized> for Weak {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index f7dc4d1094c..ddcd863aa3e 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -254,7 +254,7 @@ unsafe impl Sync for Arc {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl UnwindSafe for Arc {} -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized> for Arc {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] @@ -306,7 +306,7 @@ unsafe impl Send for Weak {} #[stable(feature = "arc_weak", since = "1.4.0")] unsafe impl Sync for Weak {} -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized> for Weak {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U: ?Sized> DispatchFromDyn> for Weak {} diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 47cce2aa39b..b4e173ce03d 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -568,7 +568,7 @@ impl Cell { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U> CoerceUnsized> for Cell {} impl Cell<[T]> { @@ -1266,7 +1266,7 @@ impl const From for RefCell { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U> CoerceUnsized> for RefCell {} struct BorrowRef<'b> { @@ -1492,7 +1492,7 @@ impl<'b, T: ?Sized> Ref<'b, T> { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'b, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for Ref<'b, T> {} #[stable(feature = "std_guard_impls", since = "1.20.0")] @@ -1738,7 +1738,7 @@ impl DerefMut for RefMut<'_, T> { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'b, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for RefMut<'b, T> {} #[stable(feature = "std_guard_impls", since = "1.20.0")] @@ -2074,7 +2074,7 @@ impl const From for UnsafeCell { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U> CoerceUnsized> for UnsafeCell {} /// [`UnsafeCell`], but [`Sync`]. @@ -2164,7 +2164,7 @@ impl const From for SyncUnsafeCell { } } -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] //#[unstable(feature = "sync_unsafe_cell", issue = "95439")] impl, U> CoerceUnsized> for SyncUnsafeCell {} diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 42c34280197..4b85c1112b9 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -126,7 +126,7 @@ pub trait Sized { /// [`Rc`]: ../../std/rc/struct.Rc.html /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md /// [nomicon-coerce]: ../../nomicon/coercions.html -#[unstable(feature = "unsize", issue = "27732")] +#[unstable(feature = "unsize", issue = "18598")] #[lang = "unsize"] #[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] pub trait Unsize { diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index eb2a92f4644..97d9b750d92 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -201,7 +201,7 @@ pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit}; #[unstable(feature = "generator_trait", issue = "43122")] pub use self::generator::{Generator, GeneratorState}; -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] pub use self::unsize::CoerceUnsized; #[unstable(feature = "dispatch_from_dyn", issue = "none")] diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs index a920b9165c1..b51f12580ea 100644 --- a/library/core/src/ops/unsize.rs +++ b/library/core/src/ops/unsize.rs @@ -31,41 +31,41 @@ use crate::marker::Unsize; /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md /// [unsize]: crate::marker::Unsize /// [nomicon-coerce]: ../../nomicon/coercions.html -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] #[lang = "coerce_unsized"] pub trait CoerceUnsized { // Empty. } // &mut T -> &mut U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} // &mut T -> &U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} // &mut T -> *mut U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} // &mut T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} // &T -> &U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} // &T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a T {} // *mut T -> *mut U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} // *mut T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} // *const T -> *const U -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} /// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c4348169c78..af79d4bbd83 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -712,7 +712,7 @@ impl const Clone for NonNull { #[stable(feature = "nonnull", since = "1.25.0")] impl Copy for NonNull {} -#[unstable(feature = "coerce_unsized", issue = "27732")] +#[unstable(feature = "coerce_unsized", issue = "18598")] impl CoerceUnsized> for NonNull where T: Unsize {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] From babd174aceb848e6dd3f67d9a8808cefe8b49193 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Dec 2022 08:22:31 +0100 Subject: [PATCH 07/10] Improve description of struct-fields GUI test --- src/test/rustdoc-gui/struct-fields.goml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc-gui/struct-fields.goml b/src/test/rustdoc-gui/struct-fields.goml index 3ec60b58cfd..fa3e16cb81e 100644 --- a/src/test/rustdoc-gui/struct-fields.goml +++ b/src/test/rustdoc-gui/struct-fields.goml @@ -1,5 +1,5 @@ +// This test ensures that each field is on its own line (In other words, they have display: block). goto: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html" -// Both fields must be on their own line. In other words, they have display: block. store-property: (first_top, "//*[@id='structfield.first']", "offsetTop") assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| }) From a115a59cb2716f06c7511084c5678a85a32d446c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 20 Dec 2022 18:24:04 +0900 Subject: [PATCH 08/10] Add regression test for #102206 Signed-off-by: Yuki Okushi --- .../ui/async-await/issues/issue-102206.rs | 8 +++++++ .../ui/async-await/issues/issue-102206.stderr | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/ui/async-await/issues/issue-102206.rs create mode 100644 src/test/ui/async-await/issues/issue-102206.stderr diff --git a/src/test/ui/async-await/issues/issue-102206.rs b/src/test/ui/async-await/issues/issue-102206.rs new file mode 100644 index 00000000000..a3a2ebc5896 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-102206.rs @@ -0,0 +1,8 @@ +// edition:2021 + +async fn foo() {} + +fn main() { + std::mem::size_of_val(foo()); + //~^ ERROR: mismatched types +} diff --git a/src/test/ui/async-await/issues/issue-102206.stderr b/src/test/ui/async-await/issues/issue-102206.stderr new file mode 100644 index 00000000000..2ab790ac761 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-102206.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/issue-102206.rs:6:27 + | +LL | std::mem::size_of_val(foo()); + | --------------------- ^^^^^ + | | | + | | expected reference, found opaque type + | | help: consider borrowing here: `&foo()` + | arguments to this function are incorrect + | +note: while checking the return type of the `async fn` + --> $DIR/issue-102206.rs:3:16 + | +LL | async fn foo() {} + | ^ checked the `Output` of this `async fn`, found opaque type + = note: expected reference `&_` + found opaque type `impl Future` +note: function defined here + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 17d7d71d9416077ec3c005bbc4b9a59bf95335e1 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 20 Dec 2022 18:48:02 +0900 Subject: [PATCH 09/10] Add regression test for #80816 Signed-off-by: Yuki Okushi --- src/test/ui/inference/issue-80816.rs | 54 ++++++++++++++++++++++++ src/test/ui/inference/issue-80816.stderr | 27 ++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/test/ui/inference/issue-80816.rs create mode 100644 src/test/ui/inference/issue-80816.stderr diff --git a/src/test/ui/inference/issue-80816.rs b/src/test/ui/inference/issue-80816.rs new file mode 100644 index 00000000000..ead320a4fe4 --- /dev/null +++ b/src/test/ui/inference/issue-80816.rs @@ -0,0 +1,54 @@ +#![allow(unreachable_code)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::sync::Arc; + +pub struct Guard { + _phantom: PhantomData, +} +impl Deref for Guard { + type Target = T; + fn deref(&self) -> &T { + unimplemented!() + } +} + +pub struct DirectDeref(T); +impl Deref for DirectDeref> { + type Target = T; + fn deref(&self) -> &T { + unimplemented!() + } +} + +pub trait Access { + type Guard: Deref; + fn load(&self) -> Self::Guard { + unimplemented!() + } +} +impl, P: Deref> Access for P { + //~^ NOTE: required for `Arc>>` to implement `Access<_>` + type Guard = A::Guard; +} +impl Access for ArcSwapAny { + //~^ NOTE: multiple `impl`s satisfying `ArcSwapAny>: Access<_>` found + type Guard = Guard; +} +impl Access for ArcSwapAny> { + type Guard = DirectDeref>; +} + +pub struct ArcSwapAny { + _phantom_arc: PhantomData, +} + +pub fn foo() { + let s: Arc>> = unimplemented!(); + let guard: Guard> = s.load(); + //~^ ERROR: type annotations needed + //~| HELP: try using a fully qualified path to specify the expected types +} + +fn main() {} diff --git a/src/test/ui/inference/issue-80816.stderr b/src/test/ui/inference/issue-80816.stderr new file mode 100644 index 00000000000..bd833340df4 --- /dev/null +++ b/src/test/ui/inference/issue-80816.stderr @@ -0,0 +1,27 @@ +error[E0283]: type annotations needed + --> $DIR/issue-80816.rs:49:38 + | +LL | let guard: Guard> = s.load(); + | ^^^^ + | +note: multiple `impl`s satisfying `ArcSwapAny>: Access<_>` found + --> $DIR/issue-80816.rs:35:1 + | +LL | impl Access for ArcSwapAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Access for ArcSwapAny> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required for `Arc>>` to implement `Access<_>` + --> $DIR/issue-80816.rs:31:45 + | +LL | impl, P: Deref> Access for P { + | ^^^^^^^^^ ^ +help: try using a fully qualified path to specify the expected types + | +LL | let guard: Guard> = >> as Access>::load(&s); + | ++++++++++++++++++++++++++++++++++++++++++++++++++ ~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. From 8f88cecab64504e9f8317e96bba41feb4ac10a29 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 20 Dec 2022 18:52:30 +0900 Subject: [PATCH 10/10] Add regression test for #57404 Signed-off-by: Yuki Okushi --- src/test/ui/typeck/issue-57404.rs | 7 +++++++ src/test/ui/typeck/issue-57404.stderr | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/test/ui/typeck/issue-57404.rs create mode 100644 src/test/ui/typeck/issue-57404.stderr diff --git a/src/test/ui/typeck/issue-57404.rs b/src/test/ui/typeck/issue-57404.rs new file mode 100644 index 00000000000..ecabca66a00 --- /dev/null +++ b/src/test/ui/typeck/issue-57404.rs @@ -0,0 +1,7 @@ +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +fn main() { + let handlers: Option FnMut<&'a mut (), Output=()>>> = None; + handlers.unwrap().as_mut().call_mut(&mut ()); //~ ERROR: `&mut ()` is not a tuple +} diff --git a/src/test/ui/typeck/issue-57404.stderr b/src/test/ui/typeck/issue-57404.stderr new file mode 100644 index 00000000000..5065ac32ad2 --- /dev/null +++ b/src/test/ui/typeck/issue-57404.stderr @@ -0,0 +1,16 @@ +error[E0277]: `&mut ()` is not a tuple + --> $DIR/issue-57404.rs:6:41 + | +LL | handlers.unwrap().as_mut().call_mut(&mut ()); + | -------- -^^^^^^ + | | | + | | the trait `Tuple` is not implemented for `&mut ()` + | | help: consider removing the leading `&`-reference + | required by a bound introduced by this call + | +note: required by a bound in `call_mut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.