Stop using HirId for fn-like parents
This commit is contained in:
parent
62cffeedcf
commit
68d7c837fc
@ -2004,16 +2004,17 @@ fn report_return_mismatched_types<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_id = fcx.tcx.hir().get_parent_item(id);
|
let mut parent_id = fcx.tcx.hir().get_parent_item(id).def_id;
|
||||||
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
|
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id);
|
||||||
// When suggesting return, we need to account for closures and async blocks, not just items.
|
// When suggesting return, we need to account for closures and async blocks, not just items.
|
||||||
for (_, node) in fcx.tcx.hir().parent_iter(id) {
|
for (_, node) in fcx.tcx.hir().parent_iter(id) {
|
||||||
match node {
|
match node {
|
||||||
hir::Node::Expr(&hir::Expr {
|
hir::Node::Expr(&hir::Expr {
|
||||||
kind: hir::ExprKind::Closure(hir::Closure { .. }),
|
kind: hir::ExprKind::Closure(hir::Closure { def_id, .. }),
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
parent_item = node;
|
parent_item = node;
|
||||||
|
parent_id = *def_id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break,
|
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break,
|
||||||
@ -2023,13 +2024,7 @@ fn report_return_mismatched_types<'a>(
|
|||||||
|
|
||||||
if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) {
|
if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) {
|
||||||
fcx.suggest_missing_break_or_return_expr(
|
fcx.suggest_missing_break_or_return_expr(
|
||||||
&mut err,
|
&mut err, expr, fn_decl, expected, found, id, parent_id,
|
||||||
expr,
|
|
||||||
fn_decl,
|
|
||||||
expected,
|
|
||||||
found,
|
|
||||||
id,
|
|
||||||
parent_id.into(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +942,7 @@ pub fn resolve_ty_and_res_fully_qualified_call(
|
|||||||
pub(in super::super) fn get_node_fn_decl(
|
pub(in super::super) fn get_node_fn_decl(
|
||||||
&self,
|
&self,
|
||||||
node: Node<'tcx>,
|
node: Node<'tcx>,
|
||||||
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
|
) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
|
||||||
match node {
|
match node {
|
||||||
Node::Item(&hir::Item {
|
Node::Item(&hir::Item {
|
||||||
ident,
|
ident,
|
||||||
@ -953,25 +953,20 @@ pub(in super::super) fn get_node_fn_decl(
|
|||||||
// This is less than ideal, it will not suggest a return type span on any
|
// This is less than ideal, it will not suggest a return type span on any
|
||||||
// method called `main`, regardless of whether it is actually the entry point,
|
// method called `main`, regardless of whether it is actually the entry point,
|
||||||
// but it will still present it as the reason for the expected type.
|
// but it will still present it as the reason for the expected type.
|
||||||
Some((
|
Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
|
||||||
hir::HirId::make_owner(owner_id.def_id),
|
|
||||||
&sig.decl,
|
|
||||||
ident,
|
|
||||||
ident.name != sym::main,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
Node::TraitItem(&hir::TraitItem {
|
Node::TraitItem(&hir::TraitItem {
|
||||||
ident,
|
ident,
|
||||||
kind: hir::TraitItemKind::Fn(ref sig, ..),
|
kind: hir::TraitItemKind::Fn(ref sig, ..),
|
||||||
owner_id,
|
owner_id,
|
||||||
..
|
..
|
||||||
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, true)),
|
}) => Some((owner_id.def_id, &sig.decl, ident, true)),
|
||||||
Node::ImplItem(&hir::ImplItem {
|
Node::ImplItem(&hir::ImplItem {
|
||||||
ident,
|
ident,
|
||||||
kind: hir::ImplItemKind::Fn(ref sig, ..),
|
kind: hir::ImplItemKind::Fn(ref sig, ..),
|
||||||
owner_id,
|
owner_id,
|
||||||
..
|
..
|
||||||
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
|
}) => Some((owner_id.def_id, &sig.decl, ident, false)),
|
||||||
Node::Expr(&hir::Expr {
|
Node::Expr(&hir::Expr {
|
||||||
hir_id,
|
hir_id,
|
||||||
kind:
|
kind:
|
||||||
@ -1001,12 +996,7 @@ pub(in super::super) fn get_node_fn_decl(
|
|||||||
}) => (ident, sig, owner_id),
|
}) => (ident, sig, owner_id),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some((
|
Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
|
||||||
hir::HirId::make_owner(owner_id.def_id),
|
|
||||||
&sig.decl,
|
|
||||||
ident,
|
|
||||||
ident.name != sym::main,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -1017,7 +1007,7 @@ pub(in super::super) fn get_node_fn_decl(
|
|||||||
pub fn get_fn_decl(
|
pub fn get_fn_decl(
|
||||||
&self,
|
&self,
|
||||||
blk_id: hir::HirId,
|
blk_id: hir::HirId,
|
||||||
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, bool)> {
|
) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> {
|
||||||
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
|
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
|
||||||
// `while` before reaching it, as block tail returns are not available in them.
|
// `while` before reaching it, as block tail returns are not available in them.
|
||||||
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
|
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
use crate::rustc_middle::ty::Article;
|
use crate::rustc_middle::ty::Article;
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
use core::iter;
|
use core::iter;
|
||||||
|
use hir::def_id::LocalDefId;
|
||||||
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
|
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
|
||||||
use rustc_data_structures::packed::Pu128;
|
use rustc_data_structures::packed::Pu128;
|
||||||
use rustc_errors::{Applicability, Diag, MultiSpan};
|
use rustc_errors::{Applicability, Diag, MultiSpan};
|
||||||
@ -796,7 +797,7 @@ pub(in super::super) fn suggest_missing_return_type(
|
|||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
found: Ty<'tcx>,
|
found: Ty<'tcx>,
|
||||||
can_suggest: bool,
|
can_suggest: bool,
|
||||||
fn_id: hir::HirId,
|
fn_id: LocalDefId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let found =
|
let found =
|
||||||
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
|
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
|
||||||
@ -923,7 +924,7 @@ fn try_suggest_return_impl_trait(
|
|||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
found: Ty<'tcx>,
|
found: Ty<'tcx>,
|
||||||
fn_id: hir::HirId,
|
fn_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
// Only apply the suggestion if:
|
// Only apply the suggestion if:
|
||||||
// - the return type is a generic parameter
|
// - the return type is a generic parameter
|
||||||
@ -937,7 +938,7 @@ fn try_suggest_return_impl_trait(
|
|||||||
|
|
||||||
let ty::Param(expected_ty_as_param) = expected.kind() else { return };
|
let ty::Param(expected_ty_as_param) = expected.kind() else { return };
|
||||||
|
|
||||||
let fn_node = self.tcx.hir_node(fn_id);
|
let fn_node = self.tcx.hir_node_by_def_id(fn_id);
|
||||||
|
|
||||||
let hir::Node::Item(hir::Item {
|
let hir::Node::Item(hir::Item {
|
||||||
kind:
|
kind:
|
||||||
@ -1031,7 +1032,7 @@ pub(in super::super) fn suggest_missing_break_or_return_expr(
|
|||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
found: Ty<'tcx>,
|
found: Ty<'tcx>,
|
||||||
id: hir::HirId,
|
id: hir::HirId,
|
||||||
fn_id: hir::HirId,
|
fn_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
if !expected.is_unit() {
|
if !expected.is_unit() {
|
||||||
return;
|
return;
|
||||||
@ -1083,11 +1084,11 @@ pub(in super::super) fn suggest_missing_break_or_return_expr(
|
|||||||
let can_return = match fn_decl.output {
|
let can_return = match fn_decl.output {
|
||||||
hir::FnRetTy::Return(ty) => {
|
hir::FnRetTy::Return(ty) => {
|
||||||
let ty = self.lowerer().lower_ty(ty);
|
let ty = self.lowerer().lower_ty(ty);
|
||||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
let bound_vars = self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id));
|
||||||
let ty = self
|
let ty = self
|
||||||
.tcx
|
.tcx
|
||||||
.instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
|
.instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
|
||||||
let ty = match self.tcx.asyncness(fn_id.owner) {
|
let ty = match self.tcx.asyncness(fn_id) {
|
||||||
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
|
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
fn_decl.output.span(),
|
fn_decl.output.span(),
|
||||||
@ -1108,8 +1109,9 @@ pub(in super::super) fn suggest_missing_break_or_return_expr(
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if can_return
|
if can_return
|
||||||
&& let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
|
&& let Some(span) = expr.span.find_ancestor_inside(
|
||||||
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
|
self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
|
||||||
|
)
|
||||||
{
|
{
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
"you might have meant to return this value",
|
"you might have meant to return this value",
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
fn call(_: impl Fn() -> bool) {}
|
||||||
|
|
||||||
|
async fn test() {
|
||||||
|
call(|| -> Option<()> {
|
||||||
|
//~^ ERROR expected
|
||||||
|
if true {
|
||||||
|
false
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
true
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,46 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:9:13
|
||||||
|
|
|
||||||
|
LL | / if true {
|
||||||
|
LL | | false
|
||||||
|
| | ^^^^^ expected `()`, found `bool`
|
||||||
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_________- expected this to be `()`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:12:9
|
||||||
|
|
|
||||||
|
LL | true
|
||||||
|
| ^^^^ expected `Option<()>`, found `bool`
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<()>`
|
||||||
|
found type `bool`
|
||||||
|
|
||||||
|
error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to be a closure that returns `bool`, but it returns `Option<()>`
|
||||||
|
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10
|
||||||
|
|
|
||||||
|
LL | call(|| -> Option<()> {
|
||||||
|
| _____----_^
|
||||||
|
| | |
|
||||||
|
| | required by a bound introduced by this call
|
||||||
|
LL | |
|
||||||
|
LL | | if true {
|
||||||
|
LL | | false
|
||||||
|
... |
|
||||||
|
LL | |
|
||||||
|
LL | | })
|
||||||
|
| |_____^ expected `bool`, found `Option<()>`
|
||||||
|
|
|
||||||
|
= note: expected type `bool`
|
||||||
|
found enum `Option<()>`
|
||||||
|
note: required by a bound in `call`
|
||||||
|
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:3:25
|
||||||
|
|
|
||||||
|
LL | fn call(_: impl Fn() -> bool) {}
|
||||||
|
| ^^^^ required by this bound in `call`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0271, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0271`.
|
Loading…
Reference in New Issue
Block a user