From 48811048f853128ad87bc62bb611ecb73522be41 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 28 Oct 2019 10:24:29 -0700 Subject: [PATCH] Allow `Validator` to get qualifs for the return place --- .../transform/check_consts/validation.rs | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) 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 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 @@ fn needs_drop_lazy_seek(&mut self, local: Local, location: Location) -> bool { || 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 @@ fn has_mut_interior_eager_seek(&self, local: Local) -> bool { 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::(self.needs_drop_lazy_seek(RETURN_PLACE, return_loc)); + qualifs.set::(self.has_mut_interior_lazy_seek(RETURN_PLACE, return_loc)); + + qualifs + } } pub struct Validator<'a, 'mir, 'tcx> { -- 2.44.0