Skip to content

Commit d1bc16c

Browse files
committed
Use a more accurate span for the implicit block return assignment
1 parent 0df64c5 commit d1bc16c

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed

compiler/rustc_mir_build/src/builder/block.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
6464
// By doing so, we can be sure that even temporaries that receive extended lifetime
6565
// assignments are dropped, too.
6666
let mut last_remainder_scope = region_scope;
67-
67+
let mut last_span = None;
6868
let source_info = this.source_info(span);
6969
for stmt in stmts {
7070
let Stmt { ref kind } = this.thir[*stmt];
71+
last_span = match kind {
72+
StmtKind::Expr { expr, .. } => Some(this.thir[*expr].span),
73+
StmtKind::Let { span, .. } => Some(*span),
74+
};
75+
7176
match kind {
7277
StmtKind::Expr { scope, expr } => {
7378
this.block_context.push(BlockFrame::Statement { ignores_expr_result: true });
@@ -334,6 +339,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
334339
{
335340
// We only want to assign an implicit `()` as the return value of the block if the
336341
// block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
342+
// Shrink the span to the tail of the block to avoid confusing diagnostics highlighting the entire block
343+
let source_info = if let Some(span) = last_span {
344+
SourceInfo { span: span.shrink_to_hi(), ..source_info }
345+
} else {
346+
source_info
347+
};
337348
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
338349
}
339350
}

tests/ui/uninhabited/void-branch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ enum Void {}
66
fn with_void() {
77
if false {
88
unsafe {
9-
//~^ ERROR unreachable expression
109
std::mem::uninitialized::<Void>();
10+
//~^ ERROR unreachable expression
1111
}
1212
}
1313

@@ -20,8 +20,8 @@ fn infallible() -> std::convert::Infallible {
2020

2121
fn with_infallible() {
2222
if false {
23-
//~^ ERROR unreachable expression
2423
infallible();
24+
//~^ ERROR unreachable expression
2525
}
2626

2727
println!()

tests/ui/uninhabited/void-branch.stderr

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
error: unreachable expression
2-
--> $DIR/void-branch.rs:8:9
2+
--> $DIR/void-branch.rs:9:46
33
|
4-
LL | / unsafe {
5-
LL | |
6-
LL | | std::mem::uninitialized::<Void>();
7-
| | --------------------------------- any code following this expression is unreachable
8-
LL | | }
9-
| |_________^ unreachable expression
4+
LL | std::mem::uninitialized::<Void>();
5+
| ---------------------------------^ unreachable expression
6+
| |
7+
| any code following this expression is unreachable
108
|
119
note: this expression has type `Void`, which is uninhabited
12-
--> $DIR/void-branch.rs:10:13
10+
--> $DIR/void-branch.rs:9:13
1311
|
1412
LL | std::mem::uninitialized::<Void>();
1513
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,18 +18,15 @@ LL | #![deny(unreachable_code)]
2018
| ^^^^^^^^^^^^^^^^
2119

2220
error: unreachable expression
23-
--> $DIR/void-branch.rs:22:14
21+
--> $DIR/void-branch.rs:23:21
2422
|
25-
LL | if false {
26-
| ______________^
27-
LL | |
28-
LL | | infallible();
29-
| | ------------ any code following this expression is unreachable
30-
LL | | }
31-
| |_____^ unreachable expression
23+
LL | infallible();
24+
| ------------^ unreachable expression
25+
| |
26+
| any code following this expression is unreachable
3227
|
3328
note: this expression has type `Infallible`, which is uninhabited
34-
--> $DIR/void-branch.rs:24:9
29+
--> $DIR/void-branch.rs:23:9
3530
|
3631
LL | infallible();
3732
| ^^^^^^^^^^^^

0 commit comments

Comments
 (0)