Skip to content

Commit 136f057

Browse files
committed
Make get_return_block() return Some only for HIR nodes in body
Fixes # 114918
1 parent 3f8c8f5 commit 136f057

9 files changed

+103
-1
lines changed

compiler/rustc_middle/src/hir/map/mod.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@ impl<'hir> Map<'hir> {
701701
// expressions.
702702
ignore_tail = true;
703703
}
704+
705+
let mut prev_hir_id = None;
704706
while let Some((hir_id, node)) = iter.next() {
705707
if let (Some((_, next_node)), false) = (iter.peek(), ignore_tail) {
706708
match next_node {
@@ -715,14 +717,23 @@ impl<'hir> Map<'hir> {
715717
| Node::ForeignItem(_)
716718
| Node::TraitItem(_)
717719
| Node::Expr(Expr { kind: ExprKind::Closure { .. }, .. })
718-
| Node::ImplItem(_) => return Some(hir_id),
720+
| Node::ImplItem(_)
721+
// The input node `id` must be enclosed in the method's body as opposed
722+
// to some other place such as its return type (fixes #114918).
723+
// We verify that indirectly by checking that the previous node is the
724+
// current node's body
725+
if node.body_id().map(|b| b.hir_id) == prev_hir_id => {
726+
return Some(hir_id)
727+
}
719728
// Ignore `return`s on the first iteration
720729
Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. })
721730
| Node::Local(_) => {
722731
return None;
723732
}
724733
_ => {}
725734
}
735+
736+
prev_hir_id = Some(hir_id);
726737
}
727738
None
728739
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Regression test for #114918
2+
// Test that a const generic enclosed in a block within a return type
3+
// produces a type mismatch error instead of triggering a const eval cycle
4+
5+
#[allow(unused_braces)]
6+
fn func() -> [u8; { () } ] { //~ ERROR mismatched types
7+
loop {}
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/const-in-fn-return-type.rs:6:21
3+
|
4+
LL | fn func() -> [u8; { () } ] {
5+
| ^^ expected `usize`, found `()`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Regression test for #114918
2+
// Test that a const generic enclosed in a block within the return type
3+
// of an impl fn produces a type mismatch error instead of triggering
4+
// a const eval cycle
5+
6+
7+
trait Trait {
8+
fn func<const N: u32>() -> [ (); N ];
9+
}
10+
11+
struct S {}
12+
13+
#[allow(unused_braces)]
14+
impl Trait for S {
15+
fn func<const N: u32>() -> [ (); { () }] { //~ ERROR mismatched types
16+
N
17+
}
18+
}
19+
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/const-in-impl-fn-return-type.rs:15:40
3+
|
4+
LL | fn func<const N: u32>() -> [ (); { () }] {
5+
| ^^ expected `usize`, found `()`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Regression test for #114918
2+
// Test that a const generic enclosed in a block in a struct's type arg
3+
// produces a type mismatch error instead of triggering a const eval cycle
4+
5+
#[allow(unused_braces)]
6+
struct S<const N: usize> {
7+
arr: [u8; N]
8+
}
9+
10+
fn main() {
11+
let s = S::<{ () }> { arr: [5, 6, 7]}; //~ ERROR mismatched types
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/const-in-struct-type-arg.rs:11:19
3+
|
4+
LL | let s = S::<{ () }> { arr: [5, 6, 7]};
5+
| ^^ expected `usize`, found `()`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Regression test for #114918
2+
// Test that a const generic enclosed in a block within the return type
3+
// of a trait method produces a type mismatch error instead of triggering
4+
// a const eval cycle
5+
6+
#[allow(unused_braces)]
7+
trait Trait {
8+
fn func<const N: u32>() -> [ (); { () }] { //~ ERROR mismatched types
9+
N
10+
}
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/const-in-trait-fn-return-type.rs:8:40
3+
|
4+
LL | fn func<const N: u32>() -> [ (); { () }] {
5+
| ^^ expected `usize`, found `()`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)