Don't do AccessDepth::Drop for types with no drop impl
This commit is contained in:
parent
197f6d8081
commit
4a099b29cd
2 changed files with 68 additions and 4 deletions
|
|
@ -1166,10 +1166,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
|||
fn check_backward_incompatible_drop(
|
||||
&mut self,
|
||||
location: Location,
|
||||
place_span: (Place<'tcx>, Span),
|
||||
(place, place_span): (Place<'tcx>, Span),
|
||||
state: &BorrowckDomain,
|
||||
) {
|
||||
let sd = AccessDepth::Drop;
|
||||
let tcx = self.infcx.tcx;
|
||||
// If this type does not need `Drop`, then treat it like a `StorageDead`.
|
||||
// This is needed because we track the borrows of refs to thread locals,
|
||||
// and we'll ICE because we don't track borrows behind shared references.
|
||||
let sd = if place.ty(self.body, tcx).ty.needs_drop(tcx, self.body.typing_env(tcx)) {
|
||||
AccessDepth::Drop
|
||||
} else {
|
||||
AccessDepth::Shallow(None)
|
||||
};
|
||||
|
||||
let borrows_in_scope = self.borrows_in_scope(location, state);
|
||||
|
||||
|
|
@ -1179,7 +1187,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
|||
self,
|
||||
self.infcx.tcx,
|
||||
self.body,
|
||||
(sd, place_span.0),
|
||||
(sd, place),
|
||||
self.borrow_set,
|
||||
|borrow_index| borrows_in_scope.contains(borrow_index),
|
||||
|this, _borrow_index, borrow| {
|
||||
|
|
@ -1190,7 +1198,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
|||
this.infcx.tcx.emit_node_span_lint(
|
||||
TAIL_EXPR_DROP_ORDER,
|
||||
CRATE_HIR_ID,
|
||||
place_span.1,
|
||||
place_span,
|
||||
session_diagnostics::TailExprDropOrder { borrowed },
|
||||
);
|
||||
// We may stop at the first case
|
||||
|
|
|
|||
56
tests/ui/drop/tail_expr_drop_order-on-thread-local.rs
Normal file
56
tests/ui/drop/tail_expr_drop_order-on-thread-local.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(thread_local)]
|
||||
#![deny(tail_expr_drop_order)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub struct Global;
|
||||
|
||||
#[thread_local]
|
||||
static REENTRANCY_STATE: State<Global> = State { marker: PhantomData, controller: Global };
|
||||
|
||||
pub struct Token(PhantomData<*mut ()>);
|
||||
|
||||
pub fn with_mut<T>(f: impl FnOnce(&mut Token) -> T) -> T {
|
||||
f(&mut REENTRANCY_STATE.borrow_mut())
|
||||
}
|
||||
|
||||
pub struct State<T: ?Sized = Global> {
|
||||
marker: PhantomData<*mut ()>,
|
||||
controller: T,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> State<T> {
|
||||
pub fn borrow_mut(&self) -> TokenMut<'_, T> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TokenMut<'a, T: ?Sized = Global> {
|
||||
state: &'a State<T>,
|
||||
token: Token,
|
||||
}
|
||||
|
||||
impl<T> Deref for TokenMut<'_, T> {
|
||||
type Target = Token;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for TokenMut<'_, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Drop for TokenMut<'_, T> {
|
||||
fn drop(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue