Skip to content

Commit 5285928

Browse files
committed
Fix ICE when checking the HIR ty of closure args.
1 parent d602ab1 commit 5285928

File tree

4 files changed

+112
-63
lines changed

4 files changed

+112
-63
lines changed

clippy_lints/src/dereference.rs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::{
1515
use rustc_infer::infer::TyCtxtInferExt;
1616
use rustc_lint::{LateContext, LateLintPass};
1717
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
18-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
18+
use rustc_middle::ty::{self, Binder, BoundVariableKind, List, Ty, TyCtxt, TypeVisitable, TypeckResults};
1919
use rustc_session::{declare_tool_lint, impl_lint_pass};
2020
use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
2121
use rustc_trait_selection::infer::InferCtxtExt;
@@ -651,7 +651,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
651651
}
652652
match parent {
653653
Node::Local(Local { ty: Some(ty), span, .. }) if span.ctxt() == ctxt => {
654-
Some(binding_ty_auto_deref_stability(cx, ty, precedence))
654+
Some(binding_ty_auto_deref_stability(cx, ty, precedence, List::empty()))
655655
},
656656
Node::Item(&Item {
657657
kind: ItemKind::Static(..) | ItemKind::Const(..),
@@ -703,13 +703,23 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
703703
ExprKind::Ret(_) => {
704704
let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
705705
Some(
706-
if let Node::Expr(Expr {
707-
kind: ExprKind::Closure(&Closure { fn_decl, .. }),
708-
..
709-
}) = cx.tcx.hir().get(owner_id)
706+
if let Node::Expr(
707+
closure @ Expr {
708+
kind: ExprKind::Closure(&Closure { fn_decl, .. }),
709+
..
710+
},
711+
) = cx.tcx.hir().get(owner_id)
710712
{
711713
match fn_decl.output {
712-
FnRetTy::Return(ty) => binding_ty_auto_deref_stability(cx, ty, precedence),
714+
FnRetTy::Return(ty) => {
715+
if let Some(sig) = expr_sig(cx, closure)
716+
&& let Some(output) = sig.output()
717+
{
718+
binding_ty_auto_deref_stability(cx, ty, precedence, output.bound_vars())
719+
} else {
720+
Position::Other(precedence)
721+
}
722+
},
713723
FnRetTy::DefaultReturn(_) => Position::Other(precedence),
714724
}
715725
} else {
@@ -731,7 +741,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
731741
.map(|(hir_ty, ty)| match hir_ty {
732742
// Type inference for closures can depend on how they're called. Only go by the explicit
733743
// types here.
734-
Some(ty) => binding_ty_auto_deref_stability(cx, ty, precedence),
744+
Some(hir_ty) => binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars()),
735745
None => ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
736746
.position_for_arg(),
737747
}),
@@ -824,7 +834,12 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
824834
//
825835
// Here `y1` and `y2` would resolve to different types, so the type `&Box<_>` is not stable when
826836
// switching to auto-dereferencing.
827-
fn binding_ty_auto_deref_stability(cx: &LateContext<'_>, ty: &hir::Ty<'_>, precedence: i8) -> Position {
837+
fn binding_ty_auto_deref_stability<'tcx>(
838+
cx: &LateContext<'tcx>,
839+
ty: &'tcx hir::Ty<'_>,
840+
precedence: i8,
841+
binder_args: &'tcx List<BoundVariableKind>,
842+
) -> Position {
828843
let TyKind::Rptr(_, ty) = &ty.kind else {
829844
return Position::Other(precedence);
830845
};
@@ -856,31 +871,31 @@ fn binding_ty_auto_deref_stability(cx: &LateContext<'_>, ty: &hir::Ty<'_>, prece
856871
} else {
857872
Position::DerefStable(
858873
precedence,
859-
cx
860-
.typeck_results()
861-
.node_type(ty.ty.hir_id)
874+
cx.tcx
875+
.erase_late_bound_regions(Binder::bind_with_vars(
876+
cx.typeck_results().node_type(ty.ty.hir_id),
877+
binder_args,
878+
))
862879
.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
863880
)
864881
}
865882
},
866-
TyKind::Slice(_)
867-
| TyKind::Array(..)
868-
| TyKind::BareFn(_)
869-
| TyKind::Never
883+
TyKind::Slice(_) => Position::DerefStable(precedence, false),
884+
TyKind::Array(..) | TyKind::Ptr(_) | TyKind::BareFn(_) => Position::DerefStable(precedence, true),
885+
TyKind::Never
870886
| TyKind::Tup(_)
871-
| TyKind::Ptr(_)
872887
| TyKind::Path(_) => Position::DerefStable(
873888
precedence,
874-
cx
875-
.typeck_results()
876-
.node_type(ty.ty.hir_id)
877-
.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
889+
cx.tcx
890+
.erase_late_bound_regions(Binder::bind_with_vars(
891+
cx.typeck_results().node_type(ty.ty.hir_id),
892+
binder_args,
893+
))
894+
.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
878895
),
879-
TyKind::OpaqueDef(..)
880-
| TyKind::Infer
881-
| TyKind::Typeof(..)
882-
| TyKind::TraitObject(..)
883-
| TyKind::Err => Position::ReborrowStable(precedence),
896+
TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => {
897+
Position::ReborrowStable(precedence)
898+
},
884899
};
885900
}
886901
}

tests/ui/explicit_auto_deref.fixed

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// run-rustfix
22

3+
#![feature(closure_lifetime_binder)]
34
#![warn(clippy::explicit_auto_deref)]
45
#![allow(
56
dead_code,
@@ -255,4 +256,14 @@ fn main() {
255256
}
256257
let x = S7([0]);
257258
let _: &[u32] = &*x;
259+
260+
let c1 = |x: &Vec<&u32>| {};
261+
let x = &&vec![&1u32];
262+
c1(x);
263+
let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {
264+
if b {
265+
return x;
266+
}
267+
*x
268+
};
258269
}

tests/ui/explicit_auto_deref.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// run-rustfix
22

3+
#![feature(closure_lifetime_binder)]
34
#![warn(clippy::explicit_auto_deref)]
45
#![allow(
56
dead_code,
@@ -255,4 +256,14 @@ fn main() {
255256
}
256257
let x = S7([0]);
257258
let _: &[u32] = &*x;
259+
260+
let c1 = |x: &Vec<&u32>| {};
261+
let x = &&vec![&1u32];
262+
c1(*x);
263+
let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {
264+
if b {
265+
return *x;
266+
}
267+
*x
268+
};
258269
}

0 commit comments

Comments
 (0)