diff options
| author | bors <bors@rust-lang.org> | 2019-08-13 06:25:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-08-13 06:25:52 +0000 |
| commit | eae3437dfe991621e8afdc82734f4a172d7ddf9b (patch) | |
| tree | 8936a353a9fe2195322baf40de256354626bbbcc /src/librustc_mir | |
| parent | 3f55461efb25b3c8b5c5c3d829065cb032ec953b (diff) | |
| parent | c9be294d11352614f6f0eaa7161df325b9300de2 (diff) | |
| download | rust-1.37.0.tar.gz rust-1.37.0.zip | |
Auto merge of #63498 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum 1.37.0
1.37.0 stable This promotes beta to stable and backports a few PRs: - Avoid ICE when referencing desugared local binding in borrow error (#63051) - Don't access a static just for its size and alignment (#62982) via 331e09b143aebfcf82dc1f9b69b31ee0083cbf0b
Diffstat (limited to 'src/librustc_mir')
| -rw-r--r-- | src/librustc_mir/borrow_check/conflict_errors.rs | 25 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/machine.rs | 5 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 47 |
3 files changed, 42 insertions, 35 deletions
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index f23cffeda68..b9cd1f07e83 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -1116,19 +1116,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { bug!("try_report_cannot_return_reference_to_local: not a local") }; match self.body.local_kind(local) { - LocalKind::ReturnPointer | LocalKind::Temp => { - ( - "temporary value".to_string(), - "temporary value created here".to_string(), - ) - } - LocalKind::Arg => { - ( - "function parameter".to_string(), - "function parameter borrowed here".to_string(), - ) - }, - LocalKind::Var => bug!("local variable without a name"), + LocalKind::ReturnPointer | LocalKind::Temp => ( + "temporary value".to_string(), + "temporary value created here".to_string(), + ), + LocalKind::Arg => ( + "function parameter".to_string(), + "function parameter borrowed here".to_string(), + ), + LocalKind::Var => ( + "local binding".to_string(), + "local binding introduced here".to_string(), + ), } }; diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 4eb95f20d93..91263932ccd 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -54,6 +54,11 @@ pub trait AllocMap<K: Hash + Eq, V> { k: K, vacant: impl FnOnce() -> Result<V, E> ) -> Result<&mut V, E>; + + /// Read-only lookup. + fn get(&self, k: K) -> Option<&V> { + self.get_or(k, || Err(())).ok() + } } /// Methods of this trait signifies a point where CTFE evaluation would fail diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index c3eec677a48..56a0e14535b 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -492,13 +492,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { id: AllocId, liveness: AllocCheck, ) -> InterpResult<'static, (Size, Align)> { - if let Ok(alloc) = self.get(id) { + // # Regular allocations + // Don't use `self.get` here as that will + // a) cause cycles in case `id` refers to a static + // b) duplicate a static's allocation in miri + if let Some((_, alloc)) = self.alloc_map.get(id) { return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)); } - // can't do this in the match argument, we may get cycle errors since the lock would get - // dropped after the match. + + // # Statics and function pointers + // Can't do this in the match argument, we may get cycle errors since the lock would + // be held throughout the match. let alloc = self.tcx.alloc_map.lock().get(id); - // Could also be a fn ptr or extern static match alloc { Some(GlobalAlloc::Function(..)) => { if let AllocCheck::Dereferencable = liveness { @@ -507,28 +512,26 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { Ok((Size::ZERO, Align::from_bytes(1).unwrap())) } - } - // `self.get` would also work, but can cause cycles if a static refers to itself + }, Some(GlobalAlloc::Static(did)) => { - // The only way `get` couldn't have worked here is if this is an extern static - assert!(self.tcx.is_foreign_item(did)); - // Use size and align of the type + // Use size and align of the type. let ty = self.tcx.type_of(did); let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); Ok((layout.size, layout.align.abi)) - } - _ => { - if let Ok(alloc) = self.get(id) { - Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)) - } - else if let AllocCheck::MaybeDead = liveness { - // Deallocated pointers are allowed, we should be able to find - // them in the map. - Ok(*self.dead_alloc_map.get(&id) - .expect("deallocated pointers should all be recorded in `dead_alloc_map`")) - } else { - err!(DanglingPointerDeref) - } + }, + Some(GlobalAlloc::Memory(alloc)) => + // Need to duplicate the logic here, because the global allocations have + // different associated types than the interpreter-local ones. + Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)), + // The rest must be dead. + None => if let AllocCheck::MaybeDead = liveness { + // Deallocated pointers are allowed, we should be able to find + // them in the map. + Ok(*self.dead_alloc_map.get(&id) + .expect("deallocated pointers should all be recorded in \ + `dead_alloc_map`")) + } else { + err!(DanglingPointerDeref) }, } } |
