Auto merge of #105951 - matthiaskrgr:rollup-aqxz888, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #105835 (Refactor post borrowck cleanup passes)
 - #105930 (Disable `NormalizeArrayLen`)
 - #105938 (Update coerce_unsized tracking issue from #27732 to #18598)
 - #105939 (Improve description of struct-fields GUI test)
 - #105943 (Add regression test for #102206)
 - #105944 (Add regression test for #80816)
 - #105945 (Add regression test for #57404)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-12-20 13:58:08 +00:00
commit 65bd2a6a73
25 changed files with 207 additions and 124 deletions

View File

@ -1,39 +1,44 @@
//! 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::visit::MutVisitor;
use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue};
use rustc_middle::mir::{Statement, StatementKind};
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
use rustc_middle::ty::TyCtxt;
pub struct CleanupNonCodegenStatements;
pub struct CleanupPostBorrowck;
pub struct DeleteNonCodegenStatements<'tcx> {
tcx: TyCtxt<'tcx>,
}
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() {
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(),
_ => (),
}
}
let terminator = basic_block.terminator_mut();
match terminator.kind {
TerminatorKind::FalseEdge { real_target, .. }
| TerminatorKind::FalseUnwind { real_target, .. } => {
terminator.kind = TerminatorKind::Goto { target: real_target };
}
_ => {}
}
}
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);
body.user_type_annotations.raw.clear();
for decl in &mut body.local_decls {
@ -41,19 +46,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);
}
}

View File

@ -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::CleanupNonCodegenStatements,
&simplify::SimplifyCfg::new("early-opt"),
&deref_separator::Derefer,
];

View File

@ -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>) {

View File

@ -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,
}
}
}
}

View File

@ -2033,7 +2033,7 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]

View File

@ -336,7 +336,7 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
#[stable(feature = "rc_ref_unwind_safe", since = "1.58.0")]
impl<T: RefUnwindSafe + ?Sized> RefUnwindSafe for Rc<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
@ -2190,7 +2190,7 @@ impl<T: ?Sized> !marker::Send for Weak<T> {}
#[stable(feature = "rc_weak", since = "1.4.0")]
impl<T: ?Sized> !marker::Sync for Weak<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]

View File

@ -254,7 +254,7 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
@ -306,7 +306,7 @@ unsafe impl<T: ?Sized + Sync + Send> Send for Weak<T> {}
#[stable(feature = "arc_weak", since = "1.4.0")]
unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}

View File

@ -568,7 +568,7 @@ impl<T: Default> Cell<T> {
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
impl<T> Cell<[T]> {
@ -1266,7 +1266,7 @@ impl<T> const From<T> for RefCell<T> {
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}
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>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
#[stable(feature = "std_guard_impls", since = "1.20.0")]
@ -1738,7 +1738,7 @@ impl<T: ?Sized> DerefMut for RefMut<'_, T> {
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
#[stable(feature = "std_guard_impls", since = "1.20.0")]
@ -2074,7 +2074,7 @@ impl<T> const From<T> for UnsafeCell<T> {
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
/// [`UnsafeCell`], but [`Sync`].
@ -2164,7 +2164,7 @@ impl<T> const From<T> for SyncUnsafeCell<T> {
}
}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}

View File

@ -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<T: ?Sized> {

View File

@ -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")]

View File

@ -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<T: ?Sized> {
// Empty.
}
// &mut T -> &mut U
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: ?Sized + Unsize<U>, 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>, 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>, 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>, 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>, 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>, 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<T: ?Sized + Unsize<U>, 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<T: ?Sized + Unsize<U>, 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<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
/// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing

View File

@ -712,7 +712,7 @@ impl<T: ?Sized> const Clone for NonNull<T> {
#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> Copy for NonNull<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]

View File

@ -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
}

View File

@ -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
}

View File

@ -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: {

View File

@ -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<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {

View File

@ -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
}
}

View File

@ -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,

View File

@ -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| })

View File

@ -0,0 +1,8 @@
// edition:2021
async fn foo() {}
fn main() {
std::mem::size_of_val(foo());
//~^ ERROR: mismatched types
}

View File

@ -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<Output = ()>`
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`.

View File

@ -0,0 +1,54 @@
#![allow(unreachable_code)]
use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::Arc;
pub struct Guard<T> {
_phantom: PhantomData<T>,
}
impl<T> Deref for Guard<T> {
type Target = T;
fn deref(&self) -> &T {
unimplemented!()
}
}
pub struct DirectDeref<T>(T);
impl<T> Deref for DirectDeref<Arc<T>> {
type Target = T;
fn deref(&self) -> &T {
unimplemented!()
}
}
pub trait Access<T> {
type Guard: Deref<Target = T>;
fn load(&self) -> Self::Guard {
unimplemented!()
}
}
impl<T, A: Access<T>, P: Deref<Target = A>> Access<T> for P {
//~^ NOTE: required for `Arc<ArcSwapAny<Arc<usize>>>` to implement `Access<_>`
type Guard = A::Guard;
}
impl<T> Access<T> for ArcSwapAny<T> {
//~^ NOTE: multiple `impl`s satisfying `ArcSwapAny<Arc<usize>>: Access<_>` found
type Guard = Guard<T>;
}
impl<T> Access<T> for ArcSwapAny<Arc<T>> {
type Guard = DirectDeref<Arc<T>>;
}
pub struct ArcSwapAny<T> {
_phantom_arc: PhantomData<T>,
}
pub fn foo() {
let s: Arc<ArcSwapAny<Arc<usize>>> = unimplemented!();
let guard: Guard<Arc<usize>> = s.load();
//~^ ERROR: type annotations needed
//~| HELP: try using a fully qualified path to specify the expected types
}
fn main() {}

View File

@ -0,0 +1,27 @@
error[E0283]: type annotations needed
--> $DIR/issue-80816.rs:49:38
|
LL | let guard: Guard<Arc<usize>> = s.load();
| ^^^^
|
note: multiple `impl`s satisfying `ArcSwapAny<Arc<usize>>: Access<_>` found
--> $DIR/issue-80816.rs:35:1
|
LL | impl<T> Access<T> for ArcSwapAny<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | impl<T> Access<T> for ArcSwapAny<Arc<T>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required for `Arc<ArcSwapAny<Arc<usize>>>` to implement `Access<_>`
--> $DIR/issue-80816.rs:31:45
|
LL | impl<T, A: Access<T>, P: Deref<Target = A>> Access<T> for P {
| ^^^^^^^^^ ^
help: try using a fully qualified path to specify the expected types
|
LL | let guard: Guard<Arc<usize>> = <Arc<ArcSwapAny<Arc<usize>>> as Access<T>>::load(&s);
| ++++++++++++++++++++++++++++++++++++++++++++++++++ ~
error: aborting due to previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -0,0 +1,7 @@
#![feature(unboxed_closures)]
#![feature(fn_traits)]
fn main() {
let handlers: Option<Box<dyn for<'a> FnMut<&'a mut (), Output=()>>> = None;
handlers.unwrap().as_mut().call_mut(&mut ()); //~ ERROR: `&mut ()` is not a tuple
}

View File

@ -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`.