Skip to content

Commit 17a8ee6

Browse files
authored
Rollup merge of #123804 - compiler-errors:podcrab-fix, r=jieyouxu
Stop using `HirId` for fn-like parents since closures are not `OwnerNode`s This is a minimal fix for #123273. I'm overall pretty disappointed w/ the state of this code; although it's "just diagnostics", it still should be maintainable and understandable and neither of those are true. I believe this code really needs some major overhauling before anything more should be added to it, because there are subtle invariants that are being exercised and subsequently broken all over the place, and I don't think we should just paper over them (e.g.) by delaying bugs or things like that. I wouldn't be surprised if fixing up this code would also yield better diagnostics.
2 parents f361026 + 68d7c83 commit 17a8ee6

File tree

5 files changed

+84
-34
lines changed

5 files changed

+84
-34
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -2004,16 +2004,17 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
20042004
}
20052005
}
20062006

2007-
let parent_id = fcx.tcx.hir().get_parent_item(id);
2008-
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
2007+
let mut parent_id = fcx.tcx.hir().get_parent_item(id).def_id;
2008+
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id);
20092009
// When suggesting return, we need to account for closures and async blocks, not just items.
20102010
for (_, node) in fcx.tcx.hir().parent_iter(id) {
20112011
match node {
20122012
hir::Node::Expr(&hir::Expr {
2013-
kind: hir::ExprKind::Closure(hir::Closure { .. }),
2013+
kind: hir::ExprKind::Closure(hir::Closure { def_id, .. }),
20142014
..
20152015
}) => {
20162016
parent_item = node;
2017+
parent_id = *def_id;
20172018
break;
20182019
}
20192020
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break,
@@ -2023,13 +2024,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
20232024

20242025
if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) {
20252026
fcx.suggest_missing_break_or_return_expr(
2026-
&mut err,
2027-
expr,
2028-
fn_decl,
2029-
expected,
2030-
found,
2031-
id,
2032-
parent_id.into(),
2027+
&mut err, expr, fn_decl, expected, found, id, parent_id,
20332028
);
20342029
}
20352030

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+6-16
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
942942
pub(in super::super) fn get_node_fn_decl(
943943
&self,
944944
node: Node<'tcx>,
945-
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
945+
) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
946946
match node {
947947
Node::Item(&hir::Item {
948948
ident,
@@ -953,25 +953,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
953953
// This is less than ideal, it will not suggest a return type span on any
954954
// method called `main`, regardless of whether it is actually the entry point,
955955
// but it will still present it as the reason for the expected type.
956-
Some((
957-
hir::HirId::make_owner(owner_id.def_id),
958-
&sig.decl,
959-
ident,
960-
ident.name != sym::main,
961-
))
956+
Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
962957
}
963958
Node::TraitItem(&hir::TraitItem {
964959
ident,
965960
kind: hir::TraitItemKind::Fn(ref sig, ..),
966961
owner_id,
967962
..
968-
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, true)),
963+
}) => Some((owner_id.def_id, &sig.decl, ident, true)),
969964
Node::ImplItem(&hir::ImplItem {
970965
ident,
971966
kind: hir::ImplItemKind::Fn(ref sig, ..),
972967
owner_id,
973968
..
974-
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
969+
}) => Some((owner_id.def_id, &sig.decl, ident, false)),
975970
Node::Expr(&hir::Expr {
976971
hir_id,
977972
kind:
@@ -1001,12 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1001996
}) => (ident, sig, owner_id),
1002997
_ => return None,
1003998
};
1004-
Some((
1005-
hir::HirId::make_owner(owner_id.def_id),
1006-
&sig.decl,
1007-
ident,
1008-
ident.name != sym::main,
1009-
))
999+
Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
10101000
}
10111001
_ => None,
10121002
}
@@ -1017,7 +1007,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10171007
pub fn get_fn_decl(
10181008
&self,
10191009
blk_id: hir::HirId,
1020-
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, bool)> {
1010+
) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> {
10211011
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
10221012
// `while` before reaching it, as block tail returns are not available in them.
10231013
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
99
use crate::rustc_middle::ty::Article;
1010
use core::cmp::min;
1111
use core::iter;
12+
use hir::def_id::LocalDefId;
1213
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
1314
use rustc_data_structures::packed::Pu128;
1415
use rustc_errors::{Applicability, Diag, MultiSpan};
@@ -796,7 +797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
796797
expected: Ty<'tcx>,
797798
found: Ty<'tcx>,
798799
can_suggest: bool,
799-
fn_id: hir::HirId,
800+
fn_id: LocalDefId,
800801
) -> bool {
801802
let found =
802803
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
@@ -923,7 +924,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
923924
err: &mut Diag<'_>,
924925
expected: Ty<'tcx>,
925926
found: Ty<'tcx>,
926-
fn_id: hir::HirId,
927+
fn_id: LocalDefId,
927928
) {
928929
// Only apply the suggestion if:
929930
// - the return type is a generic parameter
@@ -937,7 +938,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
937938

938939
let ty::Param(expected_ty_as_param) = expected.kind() else { return };
939940

940-
let fn_node = self.tcx.hir_node(fn_id);
941+
let fn_node = self.tcx.hir_node_by_def_id(fn_id);
941942

942943
let hir::Node::Item(hir::Item {
943944
kind:
@@ -1031,7 +1032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10311032
expected: Ty<'tcx>,
10321033
found: Ty<'tcx>,
10331034
id: hir::HirId,
1034-
fn_id: hir::HirId,
1035+
fn_id: LocalDefId,
10351036
) {
10361037
if !expected.is_unit() {
10371038
return;
@@ -1083,11 +1084,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10831084
let can_return = match fn_decl.output {
10841085
hir::FnRetTy::Return(ty) => {
10851086
let ty = self.lowerer().lower_ty(ty);
1086-
let bound_vars = self.tcx.late_bound_vars(fn_id);
1087+
let bound_vars = self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id));
10871088
let ty = self
10881089
.tcx
10891090
.instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
1090-
let ty = match self.tcx.asyncness(fn_id.owner) {
1091+
let ty = match self.tcx.asyncness(fn_id) {
10911092
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
10921093
span_bug!(
10931094
fn_decl.output.span(),
@@ -1108,8 +1109,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11081109
_ => false,
11091110
};
11101111
if can_return
1111-
&& let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
1112-
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
1112+
&& let Some(span) = expr.span.find_ancestor_inside(
1113+
self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
1114+
)
11131115
{
11141116
err.multipart_suggestion(
11151117
"you might have meant to return this value",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ edition: 2021
2+
3+
fn call(_: impl Fn() -> bool) {}
4+
5+
async fn test() {
6+
call(|| -> Option<()> {
7+
//~^ ERROR expected
8+
if true {
9+
false
10+
//~^ ERROR mismatched types
11+
}
12+
true
13+
//~^ ERROR mismatched types
14+
})
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:9:13
3+
|
4+
LL | / if true {
5+
LL | | false
6+
| | ^^^^^ expected `()`, found `bool`
7+
LL | |
8+
LL | | }
9+
| |_________- expected this to be `()`
10+
11+
error[E0308]: mismatched types
12+
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:12:9
13+
|
14+
LL | true
15+
| ^^^^ expected `Option<()>`, found `bool`
16+
|
17+
= note: expected enum `Option<()>`
18+
found type `bool`
19+
20+
error[E0271]: expected `{[email protected]:6:10}` to be a closure that returns `bool`, but it returns `Option<()>`
21+
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10
22+
|
23+
LL | call(|| -> Option<()> {
24+
| _____----_^
25+
| | |
26+
| | required by a bound introduced by this call
27+
LL | |
28+
LL | | if true {
29+
LL | | false
30+
... |
31+
LL | |
32+
LL | | })
33+
| |_____^ expected `bool`, found `Option<()>`
34+
|
35+
= note: expected type `bool`
36+
found enum `Option<()>`
37+
note: required by a bound in `call`
38+
--> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:3:25
39+
|
40+
LL | fn call(_: impl Fn() -> bool) {}
41+
| ^^^^ required by this bound in `call`
42+
43+
error: aborting due to 3 previous errors
44+
45+
Some errors have detailed explanations: E0271, E0308.
46+
For more information about an error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)