/// <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/> for
/// more details.
///
- /// For code that is not specific to stacked borrows, you should consider retags to read
- /// and modify the place in an opaque way.
+ /// For code that is not specific to stacked borrows, you should consider retags to read and
+ /// modify the place in an opaque way.
+ ///
+ /// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted.
Retag(RetagKind, Box<Place<'tcx>>),
/// Encodes a user's type ascription. These need to be preserved
Unreachable,
/// The behavior of this statement differs significantly before and after drop elaboration.
- /// After drop elaboration, `Drop` executes the drop glue for the specified place, after which
- /// it continues execution/unwinds at the given basic blocks. It is possible that executing drop
- /// glue is special - this would be part of Rust's memory model. (**FIXME**: due we have an
- /// issue tracking if drop glue has any interesting semantics in addition to those of a function
- /// call?)
///
- /// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically, the
- /// `Drop` will be executed if...
+ /// After drop elaboration: `Drop` terminators are a complete nop for types that have no drop
+ /// glue. For other types, `Drop` terminators behave exactly like a call to
+ /// `core::mem::drop_in_place` with a pointer to the given place.
+ ///
+ /// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically,
+ /// the `Drop` will be executed if...
///
/// **Needs clarification**: End of that sentence. This in effect should document the exact
/// behavior of drop elaboration. The following sounds vaguely right, but I'm not quite sure:
pub projection: &'tcx List<PlaceElem<'tcx>>,
}
-/// The different kinds of projections that can be used in the projection of a `Place`.
-///
-/// `T1` is the generic type for a field projection. For an actual projection on a `Place`
-/// this parameter will always be `Ty`, but the field type can be unavailable when
-/// building (by using `PlaceBuilder`) places that correspond to upvars.
-/// `T2` is the generic type for an `OpaqueCast` (is generic since it's abstracted over
-/// in dataflow analysis, see `AbstractElem`).
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
-pub enum ProjectionElem<V, T1, T2> {
+pub enum ProjectionElem<V, T> {
Deref,
- Field(Field, T1),
+ Field(Field, T),
/// Index into a slice/array.
///
/// Note that this does not also dereference, and so it does not exactly correspond to slice
/// Like an explicit cast from an opaque type to a concrete type, but without
/// requiring an intermediate variable.
- OpaqueCast(T2),
+ OpaqueCast(T),
}
/// Alias for projections as they appear in places, where the base is a place
/// and the index is a local.
-pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>, Ty<'tcx>>;
-
-/// Alias for projections that appear in `PlaceBuilder::Upvar`, for which
-/// we cannot provide any field types.
-pub type UpvarProjectionElem<'tcx> = ProjectionElem<Local, (), Ty<'tcx>>;
-
-impl<'tcx> From<PlaceElem<'tcx>> for UpvarProjectionElem<'tcx> {
- fn from(elem: PlaceElem<'tcx>) -> Self {
- match elem {
- ProjectionElem::Deref => ProjectionElem::Deref,
- ProjectionElem::Field(field, _) => ProjectionElem::Field(field, ()),
- ProjectionElem::Index(v) => ProjectionElem::Index(v),
- ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
- ProjectionElem::ConstantIndex { offset, min_length, from_end }
- }
- ProjectionElem::Subslice { from, to, from_end } => {
- ProjectionElem::Subslice { from, to, from_end }
- }
- ProjectionElem::Downcast(opt_sym, variant_idx) => {
- ProjectionElem::Downcast(opt_sym, variant_idx)
- }
- ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
- }
- }
-}
+pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
///////////////////////////////////////////////////////////////////////////
// Operands