Fix ICE in dereference.rs

This commit is contained in:
Jason Newcomb 2022-07-02 00:59:58 -04:00
parent 8c341d66a1
commit 3e80d3988d
4 changed files with 42 additions and 14 deletions

View File

@ -8,7 +8,7 @@
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{ use rustc_hir::{
self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, GenericArg, HirId, ImplItem, self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, FnRetTy, GenericArg, HirId, ImplItem,
ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem, ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
TraitItemKind, TyKind, UnOp, TraitItemKind, TyKind, UnOp,
}; };
@ -717,18 +717,32 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind { Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
ExprKind::Ret(_) => { ExprKind::Ret(_) => {
let output = cx let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
.tcx Some(
.fn_sig(cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap())) if let Node::Expr(Expr {
.skip_binder() kind: ExprKind::Closure { fn_decl, .. },
.output(); ..
Some(if !output.is_ref() { }) = cx.tcx.hir().get(owner_id)
Position::Other(precedence) {
} else if output.has_placeholders() || output.has_opaque_types() { match fn_decl.output {
Position::ReborrowStable(precedence) FnRetTy::Return(ty) => binding_ty_auto_deref_stability(ty, precedence),
} else { FnRetTy::DefaultReturn(_) => Position::Other(precedence),
Position::DerefStable(precedence) }
}) } else {
let output = cx
.tcx
.fn_sig(cx.tcx.hir().local_def_id(owner_id))
.skip_binder()
.output();
if !output.is_ref() {
Position::Other(precedence)
} else if output.has_placeholders() || output.has_opaque_types() {
Position::ReborrowStable(precedence)
} else {
Position::DerefStable(precedence)
}
},
)
}, },
ExprKind::Call(func, _) if func.hir_id == child_id => (child_id == e.hir_id).then(|| Position::Callee), ExprKind::Call(func, _) if func.hir_id == child_id => (child_id == e.hir_id).then(|| Position::Callee),
ExprKind::Call(func, args) => args ExprKind::Call(func, args) => args

View File

@ -211,4 +211,8 @@ fn main() {
unsafe { unsafe {
var(0, &**x); var(0, &**x);
} }
let s = &"str";
let _ = || return *s;
let _ = || -> &'static str { return s };
} }

View File

@ -211,4 +211,8 @@ fn _f5(x: &u32) -> u32 {
unsafe { unsafe {
var(0, &**x); var(0, &**x);
} }
let s = &"str";
let _ = || return *s;
let _ = || -> &'static str { return *s };
} }

View File

@ -192,5 +192,11 @@ error: deref which would be done by auto-deref
LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
| ^^^^^^^^^^ help: try this: `ref_str` | ^^^^^^^^^^ help: try this: `ref_str`
error: aborting due to 32 previous errors error: deref which would be done by auto-deref
--> $DIR/explicit_auto_deref.rs:217:41
|
LL | let _ = || -> &'static str { return *s };
| ^^ help: try this: `s`
error: aborting due to 33 previous errors