Skip to content

Commit 4881104

Browse files
Allow Validator to get qualifs for the return place
1 parent dbae15a commit 4881104

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

src/librustc_mir/transform/check_consts/validation.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use self::old_dataflow::IndirectlyMutableLocals;
1717
use super::ops::{self, NonConstOp};
1818
use super::qualifs::{HasMutInterior, NeedsDrop};
1919
use super::resolver::FlowSensitiveAnalysis;
20-
use super::{ConstKind, Item, Qualif, is_lang_panic_fn};
20+
use super::{ConstKind, Item, Qualif, QualifSet, is_lang_panic_fn};
2121

2222
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2323
pub enum CheckOpResult {
@@ -85,6 +85,19 @@ impl Qualifs<'a, 'mir, 'tcx> {
8585
|| self.indirectly_mutable(local, location)
8686
}
8787

88+
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
89+
///
90+
/// Only updates the cursor if absolutely necessary.
91+
fn has_mut_interior_lazy_seek(&mut self, local: Local, location: Location) -> bool {
92+
if !self.has_mut_interior.in_any_value_of_ty.contains(local) {
93+
return false;
94+
}
95+
96+
self.has_mut_interior.cursor.seek_before(location);
97+
self.has_mut_interior.cursor.get().contains(local)
98+
|| self.indirectly_mutable(local, location)
99+
}
100+
88101
/// Returns `true` if `local` is `HasMutInterior`, but requires the `has_mut_interior` and
89102
/// `indirectly_mutable` cursors to be updated beforehand.
90103
fn has_mut_interior_eager_seek(&self, local: Local) -> bool {
@@ -95,6 +108,37 @@ impl Qualifs<'a, 'mir, 'tcx> {
95108
self.has_mut_interior.cursor.get().contains(local)
96109
|| self.indirectly_mutable.get().contains(local)
97110
}
111+
112+
fn in_return_place(&mut self, item: &Item<'_, 'tcx>) -> QualifSet {
113+
// Find the `Return` terminator if one exists.
114+
//
115+
// If no `Return` terminator exists, this MIR is divergent. Just return the conservative
116+
// qualifs for the return type.
117+
let return_block = item.body
118+
.basic_blocks()
119+
.iter_enumerated()
120+
.find(|(_, block)| {
121+
match block.terminator().kind {
122+
TerminatorKind::Return => true,
123+
_ => false,
124+
}
125+
})
126+
.map(|(bb, _)| bb);
127+
128+
let return_block = match return_block {
129+
None => return QualifSet::in_any_value_of_ty(item, item.body.return_ty()),
130+
Some(bb) => bb,
131+
};
132+
133+
let return_loc = item.body.terminator_loc(return_block);
134+
135+
let mut qualifs = QualifSet::default();
136+
137+
qualifs.set::<NeedsDrop>(self.needs_drop_lazy_seek(RETURN_PLACE, return_loc));
138+
qualifs.set::<HasMutInterior>(self.has_mut_interior_lazy_seek(RETURN_PLACE, return_loc));
139+
140+
qualifs
141+
}
98142
}
99143

100144
pub struct Validator<'a, 'mir, 'tcx> {

0 commit comments

Comments
 (0)