1 use crate::hir::def_id::DefId;
2 use crate::ty::subst::SubstsRef;
3 use crate::ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, Region, Ty};
11 // There are two visitors, one for immutable and one for mutable references,
12 // but both are generated by the following macro. The code is written according
13 // to the following conventions:
15 // - introduce a `visit_foo` and a `super_foo` method for every MIR type
16 // - `visit_foo`, by default, calls `super_foo`
17 // - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
19 // This allows you as a user to override `visit_foo` for types are
20 // interested in, and invoke (within that method) call
21 // `self.super_foo` to get the default behavior. Just as in an OO
22 // language, you should never call `super` methods ordinarily except
23 // in that circumstance.
25 // For the most part, we do not destructure things external to the
26 // MIR, e.g., types, spans, etc, but simply visit them and stop. This
27 // avoids duplication with other visitors like `TypeFoldable`.
31 // The code is written in a very deliberate style intended to minimize
32 // the chance of things being overlooked. You'll notice that we always
33 // use pattern matching to reference fields and we ensure that all
34 // matches are exhaustive.
36 // For example, the `super_basic_block_data` method begins like this:
39 // fn super_basic_block_data(&mut self,
41 // data: & $($mutability)? BasicBlockData<'tcx>) {
42 // let BasicBlockData {
48 // for statement in statements {
49 // self.visit_statement(block, statement);
56 // Here we used `let BasicBlockData { <fields> } = *data` deliberately,
57 // rather than writing `data.statements` in the body. This is because if one
58 // adds a new field to `BasicBlockData`, one will be forced to revise this code,
59 // and hence one will (hopefully) invoke the correct visit methods (if any).
61 // For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
62 // That means you never write `..` to skip over fields, nor do you write `_`
63 // to skip over variants in a `match`.
65 // The only place that `_` is acceptable is to match a field (or
66 // variant argument) that does not require visiting, as in
67 // `is_cleanup` above.
69 macro_rules! make_mir_visitor {
70 ($visitor_trait_name:ident, $($mutability:ident)?) => {
71 pub trait $visitor_trait_name<'tcx> {
72 // Override these, and call `self.super_xxx` to revert back to the
75 fn visit_mir(&mut self, mir: & $($mutability)? Mir<'tcx>) {
79 fn visit_basic_block_data(&mut self,
81 data: & $($mutability)? BasicBlockData<'tcx>) {
82 self.super_basic_block_data(block, data);
85 fn visit_source_scope_data(&mut self,
86 scope_data: & $($mutability)? SourceScopeData) {
87 self.super_source_scope_data(scope_data);
90 fn visit_statement(&mut self,
91 statement: & $($mutability)? Statement<'tcx>,
93 self.super_statement(statement, location);
96 fn visit_assign(&mut self,
97 place: & $($mutability)? Place<'tcx>,
98 rvalue: & $($mutability)? Rvalue<'tcx>,
100 self.super_assign(place, rvalue, location);
103 fn visit_terminator(&mut self,
104 terminator: & $($mutability)? Terminator<'tcx>,
105 location: Location) {
106 self.super_terminator(terminator, location);
109 fn visit_terminator_kind(&mut self,
110 kind: & $($mutability)? TerminatorKind<'tcx>,
111 location: Location) {
112 self.super_terminator_kind(kind, location);
115 fn visit_assert_message(&mut self,
116 msg: & $($mutability)? AssertMessage<'tcx>,
117 location: Location) {
118 self.super_assert_message(msg, location);
121 fn visit_rvalue(&mut self,
122 rvalue: & $($mutability)? Rvalue<'tcx>,
123 location: Location) {
124 self.super_rvalue(rvalue, location);
127 fn visit_operand(&mut self,
128 operand: & $($mutability)? Operand<'tcx>,
129 location: Location) {
130 self.super_operand(operand, location);
133 fn visit_ascribe_user_ty(&mut self,
134 place: & $($mutability)? Place<'tcx>,
135 variance: & $($mutability)? ty::Variance,
136 user_ty: & $($mutability)? UserTypeProjection,
137 location: Location) {
138 self.super_ascribe_user_ty(place, variance, user_ty, location);
141 fn visit_retag(&mut self,
142 kind: & $($mutability)? RetagKind,
143 place: & $($mutability)? Place<'tcx>,
144 location: Location) {
145 self.super_retag(kind, place, location);
148 fn visit_place(&mut self,
149 place: & $($mutability)? Place<'tcx>,
150 context: PlaceContext<'tcx>,
151 location: Location) {
152 self.super_place(place, context, location);
155 fn visit_projection(&mut self,
156 place: & $($mutability)? PlaceProjection<'tcx>,
157 context: PlaceContext<'tcx>,
158 location: Location) {
159 self.super_projection(place, context, location);
162 fn visit_projection_elem(&mut self,
163 place: & $($mutability)? PlaceElem<'tcx>,
164 location: Location) {
165 self.super_projection_elem(place, location);
168 fn visit_branch(&mut self,
170 target: BasicBlock) {
171 self.super_branch(source, target);
174 fn visit_constant(&mut self,
175 constant: & $($mutability)? Constant<'tcx>,
176 location: Location) {
177 self.super_constant(constant, location);
180 fn visit_def_id(&mut self,
181 def_id: & $($mutability)? DefId,
183 self.super_def_id(def_id);
186 fn visit_span(&mut self,
187 span: & $($mutability)? Span) {
188 self.super_span(span);
191 fn visit_source_info(&mut self,
192 source_info: & $($mutability)? SourceInfo) {
193 self.super_source_info(source_info);
196 fn visit_ty(&mut self,
197 ty: & $($mutability)? Ty<'tcx>,
202 fn visit_user_type_projection(
204 ty: & $($mutability)? UserTypeProjection,
206 self.super_user_type_projection(ty);
209 fn visit_user_type_annotation(
211 index: UserTypeAnnotationIndex,
212 ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
214 self.super_user_type_annotation(index, ty);
217 fn visit_region(&mut self,
218 region: & $($mutability)? ty::Region<'tcx>,
220 self.super_region(region);
223 fn visit_const(&mut self,
224 constant: & $($mutability)? &'tcx ty::Const<'tcx>,
226 self.super_const(constant);
229 fn visit_substs(&mut self,
230 substs: & $($mutability)? SubstsRef<'tcx>,
232 self.super_substs(substs);
235 fn visit_closure_substs(&mut self,
236 substs: & $($mutability)? ClosureSubsts<'tcx>,
238 self.super_closure_substs(substs);
241 fn visit_generator_substs(&mut self,
242 substs: & $($mutability)? GeneratorSubsts<'tcx>,
244 self.super_generator_substs(substs);
247 fn visit_local_decl(&mut self,
249 local_decl: & $($mutability)? LocalDecl<'tcx>) {
250 self.super_local_decl(local, local_decl);
253 fn visit_local(&mut self,
254 _local: & $($mutability)? Local,
255 _context: PlaceContext<'tcx>,
256 _location: Location) {
259 fn visit_source_scope(&mut self,
260 scope: & $($mutability)? SourceScope) {
261 self.super_source_scope(scope);
264 // The `super_xxx` methods comprise the default behavior and are
265 // not meant to be overridden.
267 fn super_mir(&mut self,
268 mir: & $($mutability)? Mir<'tcx>) {
269 if let Some(yield_ty) = &$($mutability)? mir.yield_ty {
270 self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo {
272 scope: OUTERMOST_SOURCE_SCOPE,
276 // for best performance, we want to use an iterator rather
277 // than a for-loop, to avoid calling Mir::invalidate for
279 macro_rules! basic_blocks {
280 (mut) => (mir.basic_blocks_mut().iter_enumerated_mut());
281 () => (mir.basic_blocks().iter_enumerated());
283 for (bb, data) in basic_blocks!($($mutability)?) {
284 self.visit_basic_block_data(bb, data);
287 for scope in &$($mutability)? mir.source_scopes {
288 self.visit_source_scope_data(scope);
291 self.visit_ty(&$($mutability)? mir.return_ty(), TyContext::ReturnTy(SourceInfo {
293 scope: OUTERMOST_SOURCE_SCOPE,
296 for local in mir.local_decls.indices() {
297 self.visit_local_decl(local, & $($mutability)? mir.local_decls[local]);
300 macro_rules! type_annotations {
301 (mut) => (mir.user_type_annotations.iter_enumerated_mut());
302 () => (mir.user_type_annotations.iter_enumerated());
305 for (index, annotation) in type_annotations!($($mutability)?) {
306 self.visit_user_type_annotation(
311 self.visit_span(&$($mutability)? mir.span);
314 fn super_basic_block_data(&mut self,
316 data: & $($mutability)? BasicBlockData<'tcx>) {
324 for statement in statements {
325 let location = Location { block: block, statement_index: index };
326 self.visit_statement(statement, location);
330 if let Some(terminator) = terminator {
331 let location = Location { block: block, statement_index: index };
332 self.visit_terminator(terminator, location);
336 fn super_source_scope_data(&mut self, scope_data: & $($mutability)? SourceScopeData) {
337 let SourceScopeData {
342 self.visit_span(span);
343 if let Some(parent_scope) = parent_scope {
344 self.visit_source_scope(parent_scope);
348 fn super_statement(&mut self,
349 statement: & $($mutability)? Statement<'tcx>,
350 location: Location) {
356 self.visit_source_info(source_info);
358 StatementKind::Assign(place, rvalue) => {
359 self.visit_assign(place, rvalue, location);
361 StatementKind::FakeRead(_, place) => {
364 PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
368 StatementKind::SetDiscriminant { place, .. } => {
371 PlaceContext::MutatingUse(MutatingUseContext::Store),
375 StatementKind::StorageLive(local) => {
378 PlaceContext::NonUse(NonUseContext::StorageLive),
382 StatementKind::StorageDead(local) => {
385 PlaceContext::NonUse(NonUseContext::StorageDead),
389 StatementKind::InlineAsm(asm) => {
390 for output in & $($mutability)? asm.outputs[..] {
393 PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
397 for (span, input) in & $($mutability)? asm.inputs[..] {
398 self.visit_span(span);
399 self.visit_operand(input, location);
402 StatementKind::Retag(kind, place) => {
403 self.visit_retag(kind, place, location);
405 StatementKind::AscribeUserType(place, variance, user_ty) => {
406 self.visit_ascribe_user_ty(place, variance, user_ty, location);
408 StatementKind::Nop => {}
412 fn super_assign(&mut self,
413 place: &$($mutability)? Place<'tcx>,
414 rvalue: &$($mutability)? Rvalue<'tcx>,
415 location: Location) {
418 PlaceContext::MutatingUse(MutatingUseContext::Store),
421 self.visit_rvalue(rvalue, location);
424 fn super_terminator(&mut self,
425 terminator: &$($mutability)? Terminator<'tcx>,
426 location: Location) {
427 let Terminator { source_info, kind } = terminator;
429 self.visit_source_info(source_info);
430 self.visit_terminator_kind(kind, location);
433 fn super_terminator_kind(&mut self,
434 kind: & $($mutability)? TerminatorKind<'tcx>,
435 source_location: Location) {
436 let block = source_location.block;
438 TerminatorKind::Goto { target } => {
439 self.visit_branch(block, *target);
442 TerminatorKind::SwitchInt {
448 self.visit_operand(discr, source_location);
449 self.visit_ty(switch_ty, TyContext::Location(source_location));
450 for target in targets {
451 self.visit_branch(block, *target);
455 TerminatorKind::Resume |
456 TerminatorKind::Abort |
457 TerminatorKind::Return |
458 TerminatorKind::GeneratorDrop |
459 TerminatorKind::Unreachable => {
462 TerminatorKind::Drop {
469 PlaceContext::MutatingUse(MutatingUseContext::Drop),
472 self.visit_branch(block, *target);
473 unwind.map(|t| self.visit_branch(block, t));
476 TerminatorKind::DropAndReplace {
484 PlaceContext::MutatingUse(MutatingUseContext::Drop),
487 self.visit_operand(value, source_location);
488 self.visit_branch(block, *target);
489 unwind.map(|t| self.visit_branch(block, t));
492 TerminatorKind::Call {
499 self.visit_operand(func, source_location);
501 self.visit_operand(arg, source_location);
503 if let Some((destination, target)) = destination {
506 PlaceContext::MutatingUse(MutatingUseContext::Call),
509 self.visit_branch(block, *target);
511 cleanup.map(|t| self.visit_branch(block, t));
514 TerminatorKind::Assert {
521 self.visit_operand(cond, source_location);
522 self.visit_assert_message(msg, source_location);
523 self.visit_branch(block, *target);
524 cleanup.map(|t| self.visit_branch(block, t));
527 TerminatorKind::Yield {
532 self.visit_operand(value, source_location);
533 self.visit_branch(block, *resume);
534 drop.map(|t| self.visit_branch(block, t));
537 TerminatorKind::FalseEdges { real_target, imaginary_targets } => {
538 self.visit_branch(block, *real_target);
539 for target in imaginary_targets {
540 self.visit_branch(block, *target);
544 TerminatorKind::FalseUnwind { real_target, unwind } => {
545 self.visit_branch(block, *real_target);
546 if let Some(unwind) = unwind {
547 self.visit_branch(block, *unwind);
553 fn super_assert_message(&mut self,
554 msg: & $($mutability)? AssertMessage<'tcx>,
555 location: Location) {
556 use crate::mir::interpret::InterpError::*;
557 if let BoundsCheck { len, index } = msg {
558 self.visit_operand(len, location);
559 self.visit_operand(index, location);
563 fn super_rvalue(&mut self,
564 rvalue: & $($mutability)? Rvalue<'tcx>,
565 location: Location) {
567 Rvalue::Use(operand) => {
568 self.visit_operand(operand, location);
571 Rvalue::Repeat(value, _) => {
572 self.visit_operand(value, location);
575 Rvalue::Ref(r, bk, path) => {
576 self.visit_region(r, location);
578 BorrowKind::Shared => PlaceContext::NonMutatingUse(
579 NonMutatingUseContext::SharedBorrow(*r)
581 BorrowKind::Shallow => PlaceContext::NonMutatingUse(
582 NonMutatingUseContext::ShallowBorrow(*r)
584 BorrowKind::Unique => PlaceContext::NonMutatingUse(
585 NonMutatingUseContext::UniqueBorrow(*r)
587 BorrowKind::Mut { .. } =>
588 PlaceContext::MutatingUse(MutatingUseContext::Borrow(*r)),
590 self.visit_place(path, ctx, location);
593 Rvalue::Len(path) => {
596 PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
601 Rvalue::Cast(_cast_kind, operand, ty) => {
602 self.visit_operand(operand, location);
603 self.visit_ty(ty, TyContext::Location(location));
606 Rvalue::BinaryOp(_bin_op, lhs, rhs)
607 | Rvalue::CheckedBinaryOp(_bin_op, lhs, rhs) => {
608 self.visit_operand(lhs, location);
609 self.visit_operand(rhs, location);
612 Rvalue::UnaryOp(_un_op, op) => {
613 self.visit_operand(op, location);
616 Rvalue::Discriminant(place) => {
619 PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
624 Rvalue::NullaryOp(_op, ty) => {
625 self.visit_ty(ty, TyContext::Location(location));
628 Rvalue::Aggregate(kind, operands) => {
629 let kind = &$($mutability)? **kind;
631 AggregateKind::Array(ty) => {
632 self.visit_ty(ty, TyContext::Location(location));
634 AggregateKind::Tuple => {
643 self.visit_substs(substs, location);
645 AggregateKind::Closure(
649 self.visit_def_id(def_id, location);
650 self.visit_closure_substs(closure_substs, location);
652 AggregateKind::Generator(
657 self.visit_def_id(def_id, location);
658 self.visit_generator_substs(generator_substs, location);
662 for operand in operands {
663 self.visit_operand(operand, location);
669 fn super_operand(&mut self,
670 operand: & $($mutability)? Operand<'tcx>,
671 location: Location) {
673 Operand::Copy(place) => {
676 PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
680 Operand::Move(place) => {
683 PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
687 Operand::Constant(constant) => {
688 self.visit_constant(constant, location);
693 fn super_ascribe_user_ty(&mut self,
694 place: & $($mutability)? Place<'tcx>,
695 _variance: & $($mutability)? ty::Variance,
696 user_ty: & $($mutability)? UserTypeProjection,
697 location: Location) {
700 PlaceContext::NonUse(NonUseContext::AscribeUserTy),
703 self.visit_user_type_projection(user_ty);
706 fn super_retag(&mut self,
707 _kind: & $($mutability)? RetagKind,
708 place: & $($mutability)? Place<'tcx>,
709 location: Location) {
712 PlaceContext::MutatingUse(MutatingUseContext::Retag),
717 fn super_place(&mut self,
718 place: & $($mutability)? Place<'tcx>,
719 context: PlaceContext<'tcx>,
720 location: Location) {
722 Place::Base(PlaceBase::Local(local)) => {
723 self.visit_local(local, context, location);
725 Place::Base(PlaceBase::Static(box Static { kind, ty })) => {
726 if let StaticKind::Static(def_id) = kind {
727 self.visit_def_id(& $($mutability)? *def_id, location)
729 self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
731 Place::Projection(proj) => {
732 self.visit_projection(proj, context, location);
737 fn super_projection(&mut self,
738 proj: & $($mutability)? PlaceProjection<'tcx>,
739 context: PlaceContext<'tcx>,
740 location: Location) {
741 let Projection { base, elem } = proj;
742 let context = if context.is_mutating_use() {
743 PlaceContext::MutatingUse(MutatingUseContext::Projection)
745 PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
747 self.visit_place(base, context, location);
748 self.visit_projection_elem(elem, location);
751 fn super_projection_elem(&mut self,
752 proj: & $($mutability)? PlaceElem<'tcx>,
753 location: Location) {
755 ProjectionElem::Deref => {
757 ProjectionElem::Subslice { from: _, to: _ } => {
759 ProjectionElem::Field(_field, ty) => {
760 self.visit_ty(ty, TyContext::Location(location));
762 ProjectionElem::Index(local) => {
765 PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
769 ProjectionElem::ConstantIndex { offset: _,
773 ProjectionElem::Downcast(_name, _variant_index) => {
778 fn super_local_decl(&mut self,
780 local_decl: & $($mutability)? LocalDecl<'tcx>) {
793 self.visit_ty(ty, TyContext::LocalDecl {
795 source_info: *source_info,
797 for (user_ty, _) in & $($mutability)? user_ty.contents {
798 self.visit_user_type_projection(user_ty);
800 self.visit_source_info(source_info);
801 self.visit_source_scope(visibility_scope);
804 fn super_source_scope(&mut self,
805 _scope: & $($mutability)? SourceScope) {
808 fn super_branch(&mut self,
810 _target: BasicBlock) {
813 fn super_constant(&mut self,
814 constant: & $($mutability)? Constant<'tcx>,
815 location: Location) {
823 self.visit_span(span);
824 self.visit_ty(ty, TyContext::Location(location));
825 drop(user_ty); // no visit method for this
826 self.visit_const(literal, location);
829 fn super_def_id(&mut self, _def_id: & $($mutability)? DefId) {
832 fn super_span(&mut self, _span: & $($mutability)? Span) {
835 fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) {
841 self.visit_span(span);
842 self.visit_source_scope(scope);
845 fn super_user_type_projection(
847 _ty: & $($mutability)? UserTypeProjection,
851 fn super_user_type_annotation(
853 _index: UserTypeAnnotationIndex,
854 ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
856 self.visit_span(& $($mutability)? ty.span);
857 self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
860 fn super_ty(&mut self, _ty: & $($mutability)? Ty<'tcx>) {
863 fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
866 fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
869 fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
872 fn super_generator_substs(&mut self,
873 _substs: & $($mutability)? GeneratorSubsts<'tcx>) {
876 fn super_closure_substs(&mut self,
877 _substs: & $($mutability)? ClosureSubsts<'tcx>) {
880 // Convenience methods
882 fn visit_location(&mut self, mir: & $($mutability)? Mir<'tcx>, location: Location) {
883 let basic_block = & $($mutability)? mir[location.block];
884 if basic_block.statements.len() == location.statement_index {
885 if let Some(ref $($mutability)? terminator) = basic_block.terminator {
886 self.visit_terminator(terminator, location)
889 let statement = & $($mutability)?
890 basic_block.statements[location.statement_index];
891 self.visit_statement(statement, location)
898 make_mir_visitor!(Visitor,);
899 make_mir_visitor!(MutVisitor,mut);
901 pub trait MirVisitable<'tcx> {
902 fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>);
905 impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> {
906 fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
908 visitor.visit_statement(self, location)
912 impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> {
913 fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
915 visitor.visit_terminator(self, location)
919 impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
920 fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
922 visitor.visit_terminator(self.as_ref().unwrap(), location)
926 /// Extra information passed to `visit_ty` and friends to give context
927 /// about where the type etc appears.
928 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
931 /// The index of the local variable we are visiting.
934 /// The source location where this local variable was declared.
935 source_info: SourceInfo,
938 /// The inferred type of a user type annotation.
941 /// The return type of the function.
942 ReturnTy(SourceInfo),
946 /// A type found at some location.
950 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
951 pub enum NonMutatingUseContext<'tcx> {
952 /// Being inspected in some way, like loading a len.
954 /// Consumed as part of an operand.
956 /// Consumed as part of an operand.
959 SharedBorrow(Region<'tcx>),
961 ShallowBorrow(Region<'tcx>),
963 UniqueBorrow(Region<'tcx>),
964 /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
965 /// For example, the projection `x.y` is not marked as a mutation in these cases:
973 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
974 pub enum MutatingUseContext<'tcx> {
975 /// Appears as LHS of an assignment.
977 /// Can often be treated as a `Store`, but needs to be separate because
978 /// ASM is allowed to read outputs as well, so a `Store`-`AsmOutput` sequence
979 /// cannot be simplified the way a `Store`-`Store` can be.
981 /// Destination of a call.
986 Borrow(Region<'tcx>),
987 /// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
988 /// For example, the projection `x.y` is marked as a mutation in these cases:
994 /// Retagging, a "Stacked Borrows" shadow state operation
998 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
999 pub enum NonUseContext {
1000 /// Starting a storage live range.
1002 /// Ending a storage live range.
1004 /// User type annotation assertions for NLL.
1008 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1009 pub enum PlaceContext<'tcx> {
1010 NonMutatingUse(NonMutatingUseContext<'tcx>),
1011 MutatingUse(MutatingUseContext<'tcx>),
1012 NonUse(NonUseContext),
1015 impl<'tcx> PlaceContext<'tcx> {
1016 /// Returns `true` if this place context represents a drop.
1017 pub fn is_drop(&self) -> bool {
1019 PlaceContext::MutatingUse(MutatingUseContext::Drop) => true,
1024 /// Returns `true` if this place context represents a borrow.
1025 pub fn is_borrow(&self) -> bool {
1027 PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) |
1028 PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) |
1029 PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow(..)) |
1030 PlaceContext::MutatingUse(MutatingUseContext::Borrow(..)) => true,
1035 /// Returns `true` if this place context represents a storage live or storage dead marker.
1036 pub fn is_storage_marker(&self) -> bool {
1038 PlaceContext::NonUse(NonUseContext::StorageLive) |
1039 PlaceContext::NonUse(NonUseContext::StorageDead) => true,
1044 /// Returns `true` if this place context represents a storage live marker.
1045 pub fn is_storage_live_marker(&self) -> bool {
1047 PlaceContext::NonUse(NonUseContext::StorageLive) => true,
1052 /// Returns `true` if this place context represents a storage dead marker.
1053 pub fn is_storage_dead_marker(&self) -> bool {
1055 PlaceContext::NonUse(NonUseContext::StorageDead) => true,
1060 /// Returns `true` if this place context represents a use that potentially changes the value.
1061 pub fn is_mutating_use(&self) -> bool {
1063 PlaceContext::MutatingUse(..) => true,
1068 /// Returns `true` if this place context represents a use that does not change the value.
1069 pub fn is_nonmutating_use(&self) -> bool {
1071 PlaceContext::NonMutatingUse(..) => true,
1076 /// Returns `true` if this place context represents a use.
1077 pub fn is_use(&self) -> bool {
1079 PlaceContext::NonUse(..) => false,
1084 /// Returns `true` if this place context represents an assignment statement.
1085 pub fn is_place_assignment(&self) -> bool {
1087 PlaceContext::MutatingUse(MutatingUseContext::Store) |
1088 PlaceContext::MutatingUse(MutatingUseContext::Call) |
1089 PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) => true,