diff options
| author | Dylan MacKenzie <ecstaticmorse@gmail.com> | 2019-10-28 10:24:29 -0700 |
|---|---|---|
| committer | Dylan MacKenzie <ecstaticmorse@gmail.com> | 2019-11-15 10:33:32 -0800 |
| commit | 48811048f853128ad87bc62bb611ecb73522be41 (patch) | |
| tree | f3d79cea34b692f9b14db0dd6064e22f303a962d /src/librustc_mir/transform | |
| parent | dbae15a41b11624b26cf25f1fa414e3280d9f47f (diff) | |
| download | rust-48811048f853128ad87bc62bb611ecb73522be41.tar.gz rust-48811048f853128ad87bc62bb611ecb73522be41.zip | |
Allow `Validator` to get qualifs for the return place
Diffstat (limited to 'src/librustc_mir/transform')
| -rw-r--r-- | src/librustc_mir/transform/check_consts/validation.rs | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 74b22d8e143..53fb0bab80f 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -17,7 +17,7 @@ use self::old_dataflow::IndirectlyMutableLocals; use super::ops::{self, NonConstOp}; use super::qualifs::{HasMutInterior, NeedsDrop}; use super::resolver::FlowSensitiveAnalysis; -use super::{ConstKind, Item, Qualif, is_lang_panic_fn}; +use super::{ConstKind, Item, Qualif, QualifSet, is_lang_panic_fn}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum CheckOpResult { @@ -85,6 +85,19 @@ impl Qualifs<'a, 'mir, 'tcx> { || self.indirectly_mutable(local, location) } + /// Returns `true` if `local` is `HasMutInterior` at the given `Location`. + /// + /// Only updates the cursor if absolutely necessary. + fn has_mut_interior_lazy_seek(&mut self, local: Local, location: Location) -> bool { + if !self.has_mut_interior.in_any_value_of_ty.contains(local) { + return false; + } + + self.has_mut_interior.cursor.seek_before(location); + self.has_mut_interior.cursor.get().contains(local) + || self.indirectly_mutable(local, location) + } + /// Returns `true` if `local` is `HasMutInterior`, but requires the `has_mut_interior` and /// `indirectly_mutable` cursors to be updated beforehand. fn has_mut_interior_eager_seek(&self, local: Local) -> bool { @@ -95,6 +108,37 @@ impl Qualifs<'a, 'mir, 'tcx> { self.has_mut_interior.cursor.get().contains(local) || self.indirectly_mutable.get().contains(local) } + + fn in_return_place(&mut self, item: &Item<'_, 'tcx>) -> QualifSet { + // Find the `Return` terminator if one exists. + // + // If no `Return` terminator exists, this MIR is divergent. Just return the conservative + // qualifs for the return type. + let return_block = item.body + .basic_blocks() + .iter_enumerated() + .find(|(_, block)| { + match block.terminator().kind { + TerminatorKind::Return => true, + _ => false, + } + }) + .map(|(bb, _)| bb); + + let return_block = match return_block { + None => return QualifSet::in_any_value_of_ty(item, item.body.return_ty()), + Some(bb) => bb, + }; + + let return_loc = item.body.terminator_loc(return_block); + + let mut qualifs = QualifSet::default(); + + qualifs.set::<NeedsDrop>(self.needs_drop_lazy_seek(RETURN_PLACE, return_loc)); + qualifs.set::<HasMutInterior>(self.has_mut_interior_lazy_seek(RETURN_PLACE, return_loc)); + + qualifs + } } pub struct Validator<'a, 'mir, 'tcx> { |
