diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/syntax.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/tcx.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/type_foldable.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/type_visitable.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs | 7 |
6 files changed, 39 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 26314e3fe8e..333a88ba520 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -61,7 +61,7 @@ mod syntax; pub use syntax::*; mod switch_sources; pub mod tcx; -mod terminator; +pub mod terminator; pub use terminator::*; pub mod traversal; @@ -925,6 +925,15 @@ impl<'tcx> LocalDecl<'tcx> { } } + /// Returns `true` if this is a DerefTemp + pub fn is_deref_temp(&self) -> bool { + match self.local_info { + Some(box LocalInfo::DerefTemp) => return true, + _ => (), + } + return false; + } + /// Returns `true` is the local is from a compiler desugaring, e.g., /// `__next` from a `for` loop. #[inline] @@ -1795,6 +1804,7 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false, Rvalue::Use(_) + | Rvalue::CopyForDeref(_) | Rvalue::Repeat(_, _) | Rvalue::Ref(_, _, _) | Rvalue::ThreadLocalRef(_) @@ -1889,6 +1899,8 @@ impl<'tcx> Debug for Rvalue<'tcx> { write!(fmt, "&{}{}{:?}", region, kind_str, place) } + CopyForDeref(ref place) => write!(fmt, "deref_copy {:#?}", place), + AddressOf(mutability, ref place) => { let kind_str = match mutability { Mutability::Mut => "mut", diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 45fc5f24a60..510316c778b 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -52,6 +52,8 @@ pub enum MirPhase { /// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir` /// query. ConstsPromoted = 2, + /// After this projections may only contain deref projections as the first element. + Derefered = 3, /// Beginning with this phase, the following variants are disallowed: /// * [`TerminatorKind::DropAndReplace`] /// * [`TerminatorKind::FalseUnwind`] @@ -66,9 +68,7 @@ pub enum MirPhase { /// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop` /// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands /// are allowed for non-`Copy` types. - DropsLowered = 3, - /// After this projections may only contain deref projections as the first element. - Derefered = 4, + DropsLowered = 4, /// Beginning with this phase, the following variant is disallowed: /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` /// @@ -1051,6 +1051,16 @@ pub enum Rvalue<'tcx> { /// initialized but its content as uninitialized. Like other pointer casts, this in general /// affects alias analysis. ShallowInitBox(Operand<'tcx>, Ty<'tcx>), + + /// A CopyForDeref is equivalent to a read from a place at the + /// codegen level, but is treated specially by drop elaboration. When such a read happens, it + /// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator) + /// that the only use of the returned value is a deref operation, immediately + /// followed by one or more projections. Drop elaboration treats this rvalue as if the + /// read never happened and just projects further. This allows simplifying various MIR + /// optimizations and codegen backends that previously had to handle deref operations anywhere + /// in a place. + CopyForDeref(Place<'tcx>), } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index c99faf80187..fd3359ea80f 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -211,6 +211,7 @@ impl<'tcx> Rvalue<'tcx> { } }, Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty), + Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty, } } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 3c9850a9eb3..82a6b0c506f 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -122,6 +122,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { Ref(region, bk, place) => { Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?) } + CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?), AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?), Len(place) => Len(place.try_fold_with(folder)?), Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?), diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index d52ae5fac67..6a0801cb0dd 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -78,6 +78,10 @@ impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> { use crate::mir::Rvalue::*; match *self { Use(ref op) => op.visit_with(visitor), + CopyForDeref(ref place) => { + let op = &Operand::Copy(*place); + op.visit_with(visitor) + } Repeat(ref op, _) => op.visit_with(visitor), ThreadLocalRef(did) => did.visit_with(visitor), Ref(region, _, ref place) => { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 0ecb83996a8..d285728ec07 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -711,6 +711,13 @@ macro_rules! make_mir_visitor { }; self.visit_place(path, ctx, location); } + Rvalue::CopyForDeref(place) => { + self.visit_place( + place, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), + location + ); + } Rvalue::AddressOf(m, path) => { let ctx = match m { |
