Generate error delegation body when delegation is not resolved

This commit is contained in:
aerooneqq 2025-12-02 15:30:06 +03:00
parent 2fb805367d
commit 3e717121a1
5 changed files with 81 additions and 6 deletions

View file

@ -96,7 +96,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let generics = self.lower_delegation_generics(span);
DelegationResults { body_id, sig, ident, generics }
}
Err(err) => self.generate_delegation_error(err, span),
Err(err) => self.generate_delegation_error(err, span, delegation),
}
}
@ -404,6 +404,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
err: ErrorGuaranteed,
span: Span,
delegation: &Delegation,
) -> DelegationResults<'hir> {
let generics = self.lower_delegation_generics(span);
@ -418,8 +419,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
let header = self.generate_header_error();
let sig = hir::FnSig { decl, header, span };
let ident = Ident::dummy();
let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span)));
let ident = self.lower_ident(delegation.ident);
let body_id = self.lower_body(|this| {
let body_expr = match delegation.body.as_ref() {
Some(box block) => {
// Generates a block when we failed to resolve delegation, where a target expression is its only statement,
// thus there will be no ICEs on further stages of analysis (see #144594)
// As we generate a void function we want to convert target expression to statement to avoid additional
// errors, such as mismatched return type
let stmts = this.arena.alloc_from_iter([hir::Stmt {
hir_id: this.next_id(),
kind: rustc_hir::StmtKind::Semi(
this.arena.alloc(this.lower_target_expr(block)),
),
span,
}]);
let block = this.arena.alloc(hir::Block {
stmts,
expr: None,
hir_id: this.next_id(),
rules: hir::BlockCheckMode::DefaultBlock,
span,
targeted_by_break: false,
});
hir::ExprKind::Block(block, None)
}
None => hir::ExprKind::Err(err),
};
(&[], this.mk_expr(body_expr, span))
});
DelegationResults { ident, generics, body_id, sig }
}

View file

@ -3,6 +3,7 @@ reuse a as b {
//~| ERROR functions delegation is not yet fully implemented
dbg!(b);
//~^ ERROR missing lifetime specifier
//~| ERROR `fn() {b}` doesn't implement `Debug`
}
fn main() {}

View file

@ -20,7 +20,7 @@ LL | / reuse a as b {
LL | |
LL | |
LL | | dbg!(b);
LL | |
... |
LL | | }
| |_^
|
@ -28,7 +28,19 @@ LL | | }
= help: add `#![feature(fn_delegation)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
error[E0277]: `fn() {b}` doesn't implement `Debug`
--> $DIR/ice-line-bounds-issue-148732.rs:4:5
|
LL | reuse a as b {
| - consider calling this function
...
LL | dbg!(b);
| ^^^^^^^ the trait `Debug` is not implemented for fn item `fn() {b}`
|
= help: use parentheses to call this function: `b()`
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
Some errors have detailed explanations: E0106, E0425, E0658.
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0106, E0277, E0425, E0658.
For more information about an error, try `rustc --explain E0106`.

View file

@ -0,0 +1,13 @@
#![allow(incomplete_features)]
#![feature(fn_delegation)]
reuse a as b {
//~^ ERROR cannot find function `a` in this scope [E0425]
|| {
use std::ops::Add;
x.add
//~^ ERROR cannot find value `x` in this scope [E0425]
}
}
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0425]: cannot find function `a` in this scope
--> $DIR/unused-import-ice-144594.rs:4:7
|
LL | reuse a as b {
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/unused-import-ice-144594.rs:8:9
|
LL | x.add
| ^ not found in this scope
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.