Skip to content

Commit 3978e86

Browse files
dingxiangfei2009ehuss
authored andcommitted
bugfix on runtime borrows
1 parent 1c7c23d commit 3978e86

File tree

1 file changed

+69
-5
lines changed

1 file changed

+69
-5
lines changed

compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,18 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> {
103103
// we will proceed with `succ`
104104
let dropped_local_there = match self.visited.entry(succ) {
105105
hash_map::Entry::Occupied(occupied_entry) => {
106-
if !occupied_entry.get().borrow_mut().union(&*dropped_local_here.borrow()) {
106+
if succ == block
107+
|| !occupied_entry.get().borrow_mut().union(&*dropped_local_here.borrow())
108+
{
107109
// `succ` has been visited but no new drops observed so far,
108110
// so we can bail on `succ` until new drop information arrives
109111
continue;
110112
}
111113
occupied_entry.get().clone()
112114
}
113-
hash_map::Entry::Vacant(vacant_entry) => {
114-
vacant_entry.insert(dropped_local_here.clone()).clone()
115-
}
115+
hash_map::Entry::Vacant(vacant_entry) => vacant_entry
116+
.insert(Rc::new(RefCell::new(dropped_local_here.borrow().clone())))
117+
.clone(),
116118
};
117119
if let Some(terminator) = &target.terminator
118120
&& let TerminatorKind::Drop {
@@ -141,6 +143,61 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> {
141143
}
142144
}
143145

146+
fn true_significant_drop_ty<'tcx>(
147+
tcx: TyCtxt<'tcx>,
148+
ty: Ty<'tcx>,
149+
) -> Option<SmallVec<[Ty<'tcx>; 2]>> {
150+
if let ty::Adt(def, args) = ty.kind() {
151+
let mut did = def.did();
152+
let mut name_rev = vec![];
153+
loop {
154+
let key = tcx.def_key(did);
155+
156+
match key.disambiguated_data.data {
157+
rustc_hir::definitions::DefPathData::CrateRoot => {
158+
name_rev.push(tcx.crate_name(did.krate))
159+
}
160+
rustc_hir::definitions::DefPathData::TypeNs(symbol) => name_rev.push(symbol),
161+
_ => return None,
162+
}
163+
if let Some(parent) = key.parent {
164+
did = DefId { krate: did.krate, index: parent };
165+
} else {
166+
break;
167+
}
168+
}
169+
let name_str: Vec<_> = name_rev.iter().rev().map(|x| x.as_str()).collect();
170+
debug!(?name_str);
171+
match name_str[..] {
172+
// These are the types from Rust core ecosystem
173+
["sym" | "proc_macro2", ..] | ["core" | "std", "task", "RawWaker"] => Some(smallvec![]),
174+
// These are important types from Rust ecosystem
175+
["tracing", "instrument", "Instrumented"] | ["bytes", "Bytes"] => Some(smallvec![]),
176+
["hashbrown", "raw", "RawTable" | "RawIntoIter"] => {
177+
if let [ty, ..] = &***args
178+
&& let Some(ty) = ty.as_type()
179+
{
180+
Some(smallvec![ty])
181+
} else {
182+
None
183+
}
184+
}
185+
["hashbrown", "raw", "RawDrain"] => {
186+
if let [_, ty, ..] = &***args
187+
&& let Some(ty) = ty.as_type()
188+
{
189+
Some(smallvec![ty])
190+
} else {
191+
None
192+
}
193+
}
194+
_ => None,
195+
}
196+
} else {
197+
None
198+
}
199+
}
200+
144201
#[instrument(level = "debug", skip(tcx, param_env))]
145202
fn extract_component_raw<'tcx>(
146203
tcx: TyCtxt<'tcx>,
@@ -154,7 +211,14 @@ fn extract_component_raw<'tcx>(
154211
debug!(?ty, "components");
155212
let mut out_tys = smallvec![];
156213
for ty in tys {
157-
out_tys.push(ty);
214+
if let Some(tys) = true_significant_drop_ty(tcx, ty) {
215+
// Some types can be further opened up because the drop is simply delegated
216+
for ty in tys {
217+
out_tys.extend(extract_component_raw(tcx, param_env, ty));
218+
}
219+
} else {
220+
out_tys.push(ty);
221+
}
158222
}
159223
out_tys
160224
}

0 commit comments

Comments
 (0)