Skip to content

Commit 3e71712

Browse files
committed
Generate error delegation body when delegation is not resolved
1 parent 2fb8053 commit 3e71712

File tree

5 files changed

+81
-6
lines changed

5 files changed

+81
-6
lines changed

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
9696
let generics = self.lower_delegation_generics(span);
9797
DelegationResults { body_id, sig, ident, generics }
9898
}
99-
Err(err) => self.generate_delegation_error(err, span),
99+
Err(err) => self.generate_delegation_error(err, span, delegation),
100100
}
101101
}
102102

@@ -404,6 +404,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
404404
&mut self,
405405
err: ErrorGuaranteed,
406406
span: Span,
407+
delegation: &Delegation,
407408
) -> DelegationResults<'hir> {
408409
let generics = self.lower_delegation_generics(span);
409410

@@ -418,8 +419,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
418419
let header = self.generate_header_error();
419420
let sig = hir::FnSig { decl, header, span };
420421

421-
let ident = Ident::dummy();
422-
let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span)));
422+
let ident = self.lower_ident(delegation.ident);
423+
424+
let body_id = self.lower_body(|this| {
425+
let body_expr = match delegation.body.as_ref() {
426+
Some(box block) => {
427+
// Generates a block when we failed to resolve delegation, where a target expression is its only statement,
428+
// thus there will be no ICEs on further stages of analysis (see #144594)
429+
430+
// As we generate a void function we want to convert target expression to statement to avoid additional
431+
// errors, such as mismatched return type
432+
let stmts = this.arena.alloc_from_iter([hir::Stmt {
433+
hir_id: this.next_id(),
434+
kind: rustc_hir::StmtKind::Semi(
435+
this.arena.alloc(this.lower_target_expr(block)),
436+
),
437+
span,
438+
}]);
439+
440+
let block = this.arena.alloc(hir::Block {
441+
stmts,
442+
expr: None,
443+
hir_id: this.next_id(),
444+
rules: hir::BlockCheckMode::DefaultBlock,
445+
span,
446+
targeted_by_break: false,
447+
});
448+
449+
hir::ExprKind::Block(block, None)
450+
}
451+
None => hir::ExprKind::Err(err),
452+
};
453+
454+
(&[], this.mk_expr(body_expr, span))
455+
});
456+
423457
DelegationResults { ident, generics, body_id, sig }
424458
}
425459

tests/ui/delegation/ice-line-bounds-issue-148732.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ reuse a as b {
33
//~| ERROR functions delegation is not yet fully implemented
44
dbg!(b);
55
//~^ ERROR missing lifetime specifier
6+
//~| ERROR `fn() {b}` doesn't implement `Debug`
67
}
78

89
fn main() {}

tests/ui/delegation/ice-line-bounds-issue-148732.stderr

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,27 @@ LL | / reuse a as b {
2020
LL | |
2121
LL | |
2222
LL | | dbg!(b);
23-
LL | |
23+
... |
2424
LL | | }
2525
| |_^
2626
|
2727
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
2828
= help: add `#![feature(fn_delegation)]` to the crate attributes to enable
2929
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3030

31-
error: aborting due to 3 previous errors
31+
error[E0277]: `fn() {b}` doesn't implement `Debug`
32+
--> $DIR/ice-line-bounds-issue-148732.rs:4:5
33+
|
34+
LL | reuse a as b {
35+
| - consider calling this function
36+
...
37+
LL | dbg!(b);
38+
| ^^^^^^^ the trait `Debug` is not implemented for fn item `fn() {b}`
39+
|
40+
= help: use parentheses to call this function: `b()`
41+
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
42+
43+
error: aborting due to 4 previous errors
3244

33-
Some errors have detailed explanations: E0106, E0425, E0658.
45+
Some errors have detailed explanations: E0106, E0277, E0425, E0658.
3446
For more information about an error, try `rustc --explain E0106`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![allow(incomplete_features)]
2+
#![feature(fn_delegation)]
3+
4+
reuse a as b {
5+
//~^ ERROR cannot find function `a` in this scope [E0425]
6+
|| {
7+
use std::ops::Add;
8+
x.add
9+
//~^ ERROR cannot find value `x` in this scope [E0425]
10+
}
11+
}
12+
13+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0425]: cannot find function `a` in this scope
2+
--> $DIR/unused-import-ice-144594.rs:4:7
3+
|
4+
LL | reuse a as b {
5+
| ^ not found in this scope
6+
7+
error[E0425]: cannot find value `x` in this scope
8+
--> $DIR/unused-import-ice-144594.rs:8:9
9+
|
10+
LL | x.add
11+
| ^ not found in this scope
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)