Skip to content

Commit 3e80d39

Browse files
committed
Fix ICE in dereference.rs
1 parent 8c341d6 commit 3e80d39

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)