mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
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:
commit
65bd2a6a73
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
];
|
||||
|
@ -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>) {
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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")]
|
||||
|
@ -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")]
|
||||
|
@ -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> {}
|
||||
|
@ -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> {}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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: {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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| })
|
||||
|
8
src/test/ui/async-await/issues/issue-102206.rs
Normal file
8
src/test/ui/async-await/issues/issue-102206.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// edition:2021
|
||||
|
||||
async fn foo() {}
|
||||
|
||||
fn main() {
|
||||
std::mem::size_of_val(foo());
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
23
src/test/ui/async-await/issues/issue-102206.stderr
Normal file
23
src/test/ui/async-await/issues/issue-102206.stderr
Normal 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`.
|
54
src/test/ui/inference/issue-80816.rs
Normal file
54
src/test/ui/inference/issue-80816.rs
Normal 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() {}
|
27
src/test/ui/inference/issue-80816.stderr
Normal file
27
src/test/ui/inference/issue-80816.stderr
Normal 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`.
|
7
src/test/ui/typeck/issue-57404.rs
Normal file
7
src/test/ui/typeck/issue-57404.rs
Normal 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
|
||||
}
|
16
src/test/ui/typeck/issue-57404.stderr
Normal file
16
src/test/ui/typeck/issue-57404.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user