[−][src]Struct rustc_middle::mir::LocalDecl
A MIR local.
This can be a binding declared by the user, a temporary inserted by the compiler, a function argument, or the return place.
Fields
mutability: MutabilityWhether this is a mutable binding (i.e., let x or let mut x).
Temporaries and the return place are always mutable.
local_info: Option<Box<LocalInfo<'tcx>>>internal: booltrue if this is an internal local.
These locals are not based on types in the source code and are only used for a few desugarings at the moment.
The generator transformation will sanity check the locals which are live across a suspension point against the type components of the generator which type checking knows are live across a suspension point. We need to flag drop flags to avoid triggering this check as they are introduced after typeck.
This should be sound because the drop flags are fully algebraic, and therefore don't affect the OIBIT or outlives properties of the generator.
is_block_tail: Option<BlockTailInfo>If this local is a temporary and is_block_tail is Some,
then it is a temporary created for evaluation of some
subexpression of some block's tail expression (with no
intervening statement context).
ty: Ty<'tcx>The type of this local.
user_ty: Option<Box<UserTypeProjections>>If the user manually ascribed a type to this variable,
e.g., via let x: T, then we carry that type here. The MIR
borrow checker needs this information since it can affect
region inference.
source_info: SourceInfoThe syntactic (i.e., not visibility) source scope the local is defined in. If the local was defined in a let-statement, this is within the let-statement, rather than outside of it.
This is needed because the visibility source scope of locals within a let-statement is weird.
The reason is that we want the local to be within the let-statement for lint purposes, but we want the local to be after the let-statement for names-in-scope purposes.
That's it, if we have a let-statement like the one in this function:
fn foo(x: &str) { #[allow(unused_mut)] let mut x: u32 = { // <- one unused mut let mut y: u32 = x.parse().unwrap(); y + 2 }; drop(x); }
Then, from a lint point of view, the declaration of x: u32
(and y: u32) are within the #[allow(unused_mut)] scope - the
lint scopes are the same as the AST/HIR nesting.
However, from a name lookup point of view, the scopes look more like
as if the let-statements were match expressions:
fn foo(x: &str) { match { match x.parse().unwrap() { y => y + 2 } } { x => drop(x) }; }
We care about the name-lookup scopes for debuginfo - if the
debuginfo instruction pointer is at the call to x.parse(), we
want x to refer to x: &str, but if it is at the call to
drop(x), we want it to refer to x: u32.
To allow both uses to work, we need to have more than a single scope
for a local. We have the source_info.scope represent the "syntactic"
lint scope (with a variable being under its let block) while the
var_debug_info.source_info.scope represents the "local variable"
scope (where the "rest" of a block is under all prior let-statements).
The end result looks like this:
ROOT SCOPE
│{ argument x: &str }
│
│ │{ #[allow(unused_mut)] } // This is actually split into 2 scopes
│ │ // in practice because I'm lazy.
│ │
│ │← x.source_info.scope
│ │← `x.parse().unwrap()`
│ │
│ │ │← y.source_info.scope
│ │
│ │ │{ let y: u32 }
│ │ │
│ │ │← y.var_debug_info.source_info.scope
│ │ │← `y + 2`
│
│ │{ let x: u32 }
│ │← x.var_debug_info.source_info.scope
│ │← `drop(x)` // This accesses `x: u32`.
Implementations
impl<'tcx> LocalDecl<'tcx>[src]
pub fn can_be_made_mutable(&self) -> bool[src]
Returns true only if local is a binding that can itself be
made mutable via the addition of the mut keyword, namely
something like the occurrences of x in:
fn foo(x: Type) { ... },let x = ...,- or
match ... { C(x) => ... }
pub fn is_nonref_binding(&self) -> bool[src]
Returns true if local is definitely not a ref ident or
ref mut ident binding. (Such bindings cannot be made into
mutable bindings, but the inverse does not necessarily hold).
pub fn is_user_variable(&self) -> bool[src]
Returns true if this variable is a named variable or function
parameter declared by the user.
pub fn is_ref_for_guard(&self) -> bool[src]
Returns true if this is a reference to a variable bound in a match
expression that is used to access said variable for the guard of the
match arm.
pub fn is_ref_to_static(&self) -> bool[src]
Returns Some if this is a reference to a static item that is used to
access that static.
pub fn is_ref_to_thread_local(&self) -> bool[src]
Returns Some if this is a reference to a thread-local static item that is used to
access that static.
pub fn from_compiler_desugaring(&self) -> bool[src]
Returns true is the local is from a compiler desugaring, e.g.,
__next from a for loop.
pub fn new(ty: Ty<'tcx>, span: Span) -> Self[src]
Creates a new LocalDecl for a temporary: mutable, non-internal.
pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self[src]
Like LocalDecl::new, but takes a SourceInfo instead of a Span.
pub fn internal(self) -> Self[src]
Converts self into same LocalDecl except tagged as internal.
pub fn immutable(self) -> Self[src]
Converts self into same LocalDecl except tagged as immutable.
pub fn block_tail(self, info: BlockTailInfo) -> Self[src]
Converts self into same LocalDecl except tagged as internal temporary.
Trait Implementations
impl<'tcx> Clone for LocalDecl<'tcx>[src]
impl<'tcx> Debug for LocalDecl<'tcx>[src]
impl<'tcx, __D: TyDecoder<'tcx>> Decodable<__D> for LocalDecl<'tcx>[src]
impl<'tcx, __E: TyEncoder<'tcx>> Encodable<__E> for LocalDecl<'tcx>[src]
impl<'tcx, '__ctx> HashStable<StableHashingContext<'__ctx>> for LocalDecl<'tcx>[src]
pub fn hash_stable(
&self,
__hcx: &mut StableHashingContext<'__ctx>,
__hasher: &mut StableHasher
)[src]
&self,
__hcx: &mut StableHashingContext<'__ctx>,
__hasher: &mut StableHasher
)
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx>[src]
pub fn super_fold_with<__F: TypeFolder<'tcx>>(self, __folder: &mut __F) -> Self[src]
pub fn super_visit_with<__F: TypeVisitor<'tcx>>(
&self,
__folder: &mut __F
) -> ControlFlow<__F::BreakTy>[src]
&self,
__folder: &mut __F
) -> ControlFlow<__F::BreakTy>
pub fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self[src]
pub fn visit_with<V: TypeVisitor<'tcx>>(
&self,
visitor: &mut V
) -> ControlFlow<V::BreakTy>[src]
&self,
visitor: &mut V
) -> ControlFlow<V::BreakTy>
pub fn has_vars_bound_at_or_above(&self, binder: DebruijnIndex) -> bool[src]
pub fn has_vars_bound_above(&self, binder: DebruijnIndex) -> bool[src]
pub fn has_escaping_bound_vars(&self) -> bool[src]
pub fn has_type_flags(&self, flags: TypeFlags) -> bool[src]
pub fn has_projections(&self) -> bool[src]
pub fn has_opaque_types(&self) -> bool[src]
pub fn references_error(&self) -> bool[src]
pub fn has_param_types_or_consts(&self) -> bool[src]
pub fn has_infer_regions(&self) -> bool[src]
pub fn has_infer_types(&self) -> bool[src]
pub fn has_infer_types_or_consts(&self) -> bool[src]
pub fn needs_infer(&self) -> bool[src]
pub fn has_placeholders(&self) -> bool[src]
pub fn needs_subst(&self) -> bool[src]
pub fn has_free_regions(&self) -> bool[src]
pub fn has_erased_regions(&self) -> bool[src]
pub fn has_erasable_regions(&self) -> bool[src]
pub fn is_global(&self) -> bool[src]
pub fn has_late_bound_regions(&self) -> bool[src]
pub fn still_further_specializable(&self) -> bool[src]
Auto Trait Implementations
impl<'tcx> !RefUnwindSafe for LocalDecl<'tcx>
impl<'tcx> !Send for LocalDecl<'tcx>
impl<'tcx> !Sync for LocalDecl<'tcx>
impl<'tcx> Unpin for LocalDecl<'tcx>
impl<'tcx> !UnwindSafe for LocalDecl<'tcx>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized, [src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized, [src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T[src]
impl<'a, T> Captures<'a> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> From<T> for T[src]
impl<T, U> Into<U> for T where
U: From<T>, [src]
U: From<T>,
impl<T> MaybeResult<T> for T[src]
type Error = !
pub fn from(Result<T, <T as MaybeResult<T>>::Error>) -> T[src]
pub fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>[src]
impl<'tcx, T> Subst<'tcx> for T where
T: TypeFoldable<'tcx>, [src]
T: TypeFoldable<'tcx>,
pub fn subst_spanned(Self, TyCtxt<'tcx>, &[GenericArg<'tcx>], Option<Span>) -> T[src]
pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self[src]
impl<T> ToOwned for T where
T: Clone, [src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T[src]
pub fn clone_into(&self, target: &mut T)[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>, [src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>, [src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.