Skip to content

Commit 3bc1d01

Browse files
committed
Clear up get_size_and_align
1 parent 34e7a3c commit 3bc1d01

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

src/librustc_mir/interpret/memory.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -535,41 +535,44 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
535535
id: AllocId,
536536
liveness: AllocCheck,
537537
) -> InterpResult<'static, (Size, Align)> {
538-
let alloc_or_size_align = self.alloc_map.get_or(id, || {
539-
// Can't do this in the match argument, we may get cycle errors since the lock would
540-
// be held throughout the match.
541-
let alloc = self.tcx.alloc_map.lock().get(id);
542-
Err(match alloc {
543-
Some(GlobalAlloc::Static(did)) => {
544-
// Use size and align of the type
545-
let ty = self.tcx.type_of(did);
546-
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
547-
Ok((layout.size, layout.align.abi))
548-
},
549-
Some(GlobalAlloc::Memory(alloc)) =>
550-
// this duplicates the logic on the `match alloc_or_size_align`, but due to the
551-
// API of `get_or` there's no way around that.
552-
Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
553-
Some(GlobalAlloc::Function(_)) => if let AllocCheck::Dereferencable = liveness {
554-
// The caller requested no function pointers.
555-
err!(DerefFunctionPointer)
556-
} else {
557-
Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
558-
},
559-
// The rest must be dead.
560-
None => if let AllocCheck::MaybeDead = liveness {
561-
// Deallocated pointers are allowed, we should be able to find
562-
// them in the map.
563-
Ok(*self.dead_alloc_map.get(&id)
564-
.expect("deallocated pointers should all be recorded in `dead_alloc_map`"))
565-
} else {
566-
err!(DanglingPointerDeref)
567-
},
568-
})
569-
});
570-
match alloc_or_size_align {
538+
// Don't use `self.get` here as that will
539+
// a) cause cycles in case `id` refers to a static
540+
// b) duplicate a static's allocation in miri
541+
match self.alloc_map.get_or(id, || Err(())) {
571542
Ok((_, alloc)) => Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
572-
Err(done) => done,
543+
Err(()) => {
544+
// Can't do this in the match argument, we may get cycle errors since the lock would
545+
// be held throughout the match.
546+
let alloc = self.tcx.alloc_map.lock().get(id);
547+
match alloc {
548+
Some(GlobalAlloc::Static(did)) => {
549+
// Use size and align of the type
550+
let ty = self.tcx.type_of(did);
551+
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
552+
return Ok((layout.size, layout.align.abi));
553+
},
554+
Some(GlobalAlloc::Memory(alloc)) =>
555+
// Need to duplicate the logic here, because the global allocations have
556+
// different associated types than the interpreter-local ones
557+
Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
558+
Some(GlobalAlloc::Function(_)) => if let AllocCheck::Dereferencable = liveness {
559+
// The caller requested no function pointers.
560+
return err!(DerefFunctionPointer);
561+
} else {
562+
return Ok((Size::ZERO, Align::from_bytes(1).unwrap()));
563+
},
564+
// The rest must be dead.
565+
None => return if let AllocCheck::MaybeDead = liveness {
566+
// Deallocated pointers are allowed, we should be able to find
567+
// them in the map.
568+
Ok(*self.dead_alloc_map.get(&id)
569+
.expect("deallocated pointers should all be recorded in \
570+
`dead_alloc_map`"))
571+
} else {
572+
err!(DanglingPointerDeref)
573+
},
574+
}
575+
}
573576
}
574577
}
575578

0 commit comments

Comments
 (0)