mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 14:38:46 +00:00
Fix significant drop detection
This commit is contained in:
parent
20b085d500
commit
a032189503
2 changed files with 42 additions and 28 deletions
|
@ -119,41 +119,49 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> {
|
|||
self.cx.typeck_results().expr_ty(ex)
|
||||
}
|
||||
|
||||
fn has_seen_type(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
!self.seen_types.insert(ty)
|
||||
fn has_sig_drop_attr(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
self.seen_types.clear();
|
||||
self.has_sig_drop_attr_impl(cx, ty)
|
||||
}
|
||||
|
||||
fn has_sig_drop_attr(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
fn has_sig_drop_attr_impl(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
if let Some(adt) = ty.ty_adt_def() {
|
||||
if get_attr(cx.sess(), cx.tcx.get_attrs_unchecked(adt.did()), "has_significant_drop").count() > 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
match ty.kind() {
|
||||
rustc_middle::ty::Adt(a, b) => {
|
||||
for f in a.all_fields() {
|
||||
let ty = f.ty(cx.tcx, b);
|
||||
if !self.has_seen_type(ty) && self.has_sig_drop_attr(cx, ty) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for generic_arg in *b {
|
||||
if let GenericArgKind::Type(ty) = generic_arg.unpack() {
|
||||
if self.has_sig_drop_attr(cx, ty) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
},
|
||||
rustc_middle::ty::Array(ty, _)
|
||||
| rustc_middle::ty::RawPtr(ty, _)
|
||||
| rustc_middle::ty::Ref(_, ty, _)
|
||||
| rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(cx, *ty),
|
||||
_ => false,
|
||||
if !self.seen_types.insert(ty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let result = match ty.kind() {
|
||||
rustc_middle::ty::Adt(adt, args) => {
|
||||
// if some field has significant drop,
|
||||
adt.all_fields()
|
||||
.map(|field| field.ty(cx.tcx, args))
|
||||
.any(|ty| self.has_sig_drop_attr(cx, ty))
|
||||
// or if there is no generic lifetime and..
|
||||
// (to avoid false positive on `Ref<'a, MutexGuard<Foo>>`)
|
||||
|| (args
|
||||
.iter()
|
||||
.all(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_)))
|
||||
// some generic parameter has significant drop
|
||||
// (to avoid false negative on `Box<MutexGuard<Foo>>`)
|
||||
&& args
|
||||
.iter()
|
||||
.filter_map(|arg| match arg.unpack() {
|
||||
GenericArgKind::Type(ty) => Some(ty),
|
||||
_ => None,
|
||||
})
|
||||
.any(|ty| self.has_sig_drop_attr(cx, ty)))
|
||||
},
|
||||
rustc_middle::ty::Tuple(tys) => tys.iter().any(|ty| self.has_sig_drop_attr(cx, ty)),
|
||||
rustc_middle::ty::Array(ty, _) | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(cx, *ty),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ LL | match s.lock_m().get_the_value() {
|
|||
LL | println!("{}", s.lock_m().get_the_value());
|
||||
| ---------- another value with significant `Drop` created here
|
||||
...
|
||||
LL | println!("{}", s.lock_m().get_the_value());
|
||||
| ---------- another value with significant `Drop` created here
|
||||
...
|
||||
LL | }
|
||||
| - temporary lives until here
|
||||
|
|
||||
|
@ -47,6 +50,9 @@ LL | match s.lock_m_m().get_the_value() {
|
|||
LL | println!("{}", s.lock_m().get_the_value());
|
||||
| ---------- another value with significant `Drop` created here
|
||||
...
|
||||
LL | println!("{}", s.lock_m().get_the_value());
|
||||
| ---------- another value with significant `Drop` created here
|
||||
...
|
||||
LL | }
|
||||
| - temporary lives until here
|
||||
|
|
||||
|
@ -360,7 +366,7 @@ LL | match s.lock().deref().deref() {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | _ => println!("Value is {}", s.lock().deref()),
|
||||
| ---------------- another value with significant `Drop` created here
|
||||
| -------- another value with significant `Drop` created here
|
||||
LL | };
|
||||
| - temporary lives until here
|
||||
|
|
||||
|
@ -378,7 +384,7 @@ LL | match s.lock().deref().deref() {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | matcher => println!("Value is {}", s.lock().deref()),
|
||||
| ---------------- another value with significant `Drop` created here
|
||||
| -------- another value with significant `Drop` created here
|
||||
LL | _ => println!("Value was not a match"),
|
||||
LL | };
|
||||
| - temporary lives until here
|
||||
|
|
Loading…
Add table
Reference in a new issue