Skip to content

Commit b15f06e

Browse files
committed
Auto merge of #9093 - Jarcho:deref_ice, r=giraffate
Fix ICE in `dereference.rs` fixes #9089 changelog: Fix ICE when dereferencing or borrowing on explicit returns from closures
2 parents 8c89877 + 3e80d39 commit b15f06e

File tree

4 files changed

+42
-14
lines changed

4 files changed

+42
-14
lines changed

clippy_lints/src/dereference.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxIndexMap;
88
use rustc_errors::Applicability;
99
use rustc_hir::intravisit::{walk_ty, Visitor};
1010
use rustc_hir::{
11-
self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, GenericArg, HirId, ImplItem,
11+
self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, FnRetTy, GenericArg, HirId, ImplItem,
1212
ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
1313
TraitItemKind, TyKind, UnOp,
1414
};
@@ -717,18 +717,32 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
717717

718718
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
719719
ExprKind::Ret(_) => {
720-
let output = cx
721-
.tcx
722-
.fn_sig(cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()))
723-
.skip_binder()
724-
.output();
725-
Some(if !output.is_ref() {
726-
Position::Other(precedence)
727-
} else if output.has_placeholders() || output.has_opaque_types() {
728-
Position::ReborrowStable(precedence)
729-
} else {
730-
Position::DerefStable(precedence)
731-
})
720+
let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
721+
Some(
722+
if let Node::Expr(Expr {
723+
kind: ExprKind::Closure { fn_decl, .. },
724+
..
725+
}) = cx.tcx.hir().get(owner_id)
726+
{
727+
match fn_decl.output {
728+
FnRetTy::Return(ty) => binding_ty_auto_deref_stability(ty, precedence),
729+
FnRetTy::DefaultReturn(_) => Position::Other(precedence),
730+
}
731+
} else {
732+
let output = cx
733+
.tcx
734+
.fn_sig(cx.tcx.hir().local_def_id(owner_id))
735+
.skip_binder()
736+
.output();
737+
if !output.is_ref() {
738+
Position::Other(precedence)
739+
} else if output.has_placeholders() || output.has_opaque_types() {
740+
Position::ReborrowStable(precedence)
741+
} else {
742+
Position::DerefStable(precedence)
743+
}
744+
},
745+
)
732746
},
733747
ExprKind::Call(func, _) if func.hir_id == child_id => (child_id == e.hir_id).then(|| Position::Callee),
734748
ExprKind::Call(func, args) => args

tests/ui/explicit_auto_deref.fixed

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,8 @@ fn main() {
211211
unsafe {
212212
var(0, &**x);
213213
}
214+
215+
let s = &"str";
216+
let _ = || return *s;
217+
let _ = || -> &'static str { return s };
214218
}

tests/ui/explicit_auto_deref.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,8 @@ fn main() {
211211
unsafe {
212212
var(0, &**x);
213213
}
214+
215+
let s = &"str";
216+
let _ = || return *s;
217+
let _ = || -> &'static str { return *s };
214218
}

tests/ui/explicit_auto_deref.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,11 @@ error: deref which would be done by auto-deref
192192
LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
193193
| ^^^^^^^^^^ help: try this: `ref_str`
194194

195-
error: aborting due to 32 previous errors
195+
error: deref which would be done by auto-deref
196+
--> $DIR/explicit_auto_deref.rs:217:41
197+
|
198+
LL | let _ = || -> &'static str { return *s };
199+
| ^^ help: try this: `s`
200+
201+
error: aborting due to 33 previous errors
196202

0 commit comments

Comments
 (0)