Skip to content

Commit 78fac69

Browse files
Rollup merge of rust-lang#152628 - Enselic:ptr-const-allocation, r=jieyouxu
tests: rustc_public: Check const allocation for all variables (1 of 11 was missing) In the test `tests/ui-fulldeps/rustc_public/check_allocation.rs` there is a check for constant allocations of local variables of this function: fn other_consts() {{ let _max_u128 = u128::MAX; let _min_i128 = i128::MIN; let _max_i8 = i8::MAX; let _char = 'x'; let _false = false; let _true = true; let _ptr = &BAR; let _null_ptr: *const u8 = NULL; let _tuple = TUPLE; let _char_id = const {{ type_id::<char>() }}; let _bool_id = const {{ type_id::<bool>() }}; }} The current test only finds 10 out of 11 allocations. The constant allocation for let _ptr = &BAR; is not checked, because the `SingleUseConsts` MIR pass does not optimize away that assignment. Add code to also collect constant allocation from assignment rvalues to find the constant allocation for that last variable. Not only does this change make sense on its own, it also makes the test pass both with and without the `SingleUseConsts` pass. Discovered while investigating ways to avoid [this tests/ui-fulldeps/rustc_public/check_allocation.rs](Enselic@d7fffab#diff-c4a926f9e8ba22bcfb1e6f2491b79b80608ab018641f85f66d6718d7f3716a5e) hack from rust-lang#151426 which wants to stop running `SingleUseConsts` for non-optimized builds.
2 parents b558b9a + 1e367f9 commit 78fac69

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

tests/ui-fulldeps/rustc_public/check_allocation.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ use std::io::Write;
2727
use std::ops::ControlFlow;
2828

2929
use rustc_public::crate_def::CrateDef;
30-
use rustc_public::mir::Body;
3130
use rustc_public::mir::alloc::GlobalAlloc;
3231
use rustc_public::mir::mono::{Instance, StaticDef};
32+
use rustc_public::mir::{Body, Operand, Rvalue, StatementKind};
3333
use rustc_public::ty::{Allocation, ConstantKind};
3434
use rustc_public::{CrateItem, CrateItems, ItemKind};
3535

@@ -106,7 +106,7 @@ fn check_other_consts(item: CrateItem) {
106106
// Instance body will force constant evaluation.
107107
let body = Instance::try_from(item).unwrap().body().unwrap();
108108
let assigns = collect_consts(&body);
109-
assert_eq!(assigns.len(), 10);
109+
assert_eq!(assigns.len(), 11);
110110
let mut char_id = None;
111111
let mut bool_id = None;
112112
for (name, alloc) in assigns {
@@ -167,17 +167,44 @@ fn check_other_consts(item: CrateItem) {
167167
assert_ne!(bool_id, char_id);
168168
}
169169

170-
/// Collects all the constant assignments.
170+
/// Collects all constant allocations from `fn other_consts()`. The returned map
171+
/// maps variable names to their corresponding constant allocation.
171172
pub fn collect_consts(body: &Body) -> HashMap<String, &Allocation> {
172-
body.var_debug_info
173+
let local_to_const_alloc = body
174+
.blocks
173175
.iter()
174-
.filter_map(|info| {
175-
info.constant().map(|const_op| {
176-
let ConstantKind::Allocated(alloc) = const_op.const_.kind() else { unreachable!() };
177-
(info.name.clone(), alloc)
178-
})
176+
.flat_map(|block| block.statements.iter())
177+
.filter_map(|statement| {
178+
let StatementKind::Assign(place, Rvalue::Use(Operand::Constant(const_op))) =
179+
&statement.kind
180+
else {
181+
return None;
182+
};
183+
let ConstantKind::Allocated(alloc) = const_op.const_.kind() else { return None };
184+
Some((place.local, alloc))
179185
})
180-
.collect::<HashMap<_, _>>()
186+
.collect::<HashMap<_, _>>();
187+
188+
let mut allocations = HashMap::new();
189+
for info in &body.var_debug_info {
190+
// MIR optimzations sometimes gets rid of assignments. Look up the
191+
// constant allocation directly in this case.
192+
if let Some(const_op) = info.constant() {
193+
let ConstantKind::Allocated(alloc) = const_op.const_.kind() else { unreachable!() };
194+
allocations.insert(info.name.clone(), alloc);
195+
}
196+
197+
// If MIR optimzations didn't get rid of the assignment, then we can
198+
// find the constant allocation as an rvalue of the corresponding
199+
// assignment.
200+
if let Some(local) = info.local() {
201+
if let Some(alloc) = local_to_const_alloc.get(&local) {
202+
allocations.insert(info.name.clone(), alloc);
203+
}
204+
}
205+
}
206+
207+
allocations
181208
}
182209

183210
/// Check the allocation data for `LEN`.

0 commit comments

Comments
 (0)