Generate more verbose error delegation
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 022f9e3..eb005e4 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -128,14 +128,12 @@ pub(crate) fn lower_delegation( { self.get_sig_id(delegation_info.resolution_node, span) } else { - return self.generate_delegation_error( - self.dcx().span_delayed_bug( - span, - format!("LoweringContext: the delegation {:?} is unresolved", item_id), - ), + self.dcx().span_delayed_bug( span, - delegation, + format!("LoweringContext: the delegation {:?} is unresolved", item_id), ); + + return self.generate_delegation_error(span, delegation); }; match sig_id { @@ -172,7 +170,7 @@ pub(crate) fn lower_delegation( DelegationResults { body_id, sig, ident, generics } } - Err(err) => self.generate_delegation_error(err, span, delegation), + Err(_) => self.generate_delegation_error(span, delegation), } } @@ -604,7 +602,6 @@ fn process_segment( fn generate_delegation_error( &mut self, - err: ErrorGuaranteed, span: Span, delegation: &Delegation, ) -> DelegationResults<'hir> { @@ -622,36 +619,35 @@ fn generate_delegation_error( 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) + let path = this.lower_qpath( + delegation.id, + &delegation.qself, + &delegation.path, + ParamMode::Optional, + AllowReturnTypeNotation::No, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); - // 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), + let callee_path = this.arena.alloc(this.mk_expr(hir::ExprKind::Path(path), span)); + let args = if let Some(box block) = delegation.body.as_ref() { + this.arena.alloc_slice(&[this.lower_target_expr(block)]) + } else { + &mut [] }; - (&[], this.mk_expr(body_expr, span)) + let call = this.arena.alloc(this.mk_expr(hir::ExprKind::Call(callee_path, args), span)); + + let block = this.arena.alloc(hir::Block { + stmts: &[], + expr: Some(call), + hir_id: this.next_id(), + rules: hir::BlockCheckMode::DefaultBlock, + span, + targeted_by_break: false, + }); + + (&[], this.mk_expr(hir::ExprKind::Block(block, None), span)) }); let generics = hir::Generics::empty();
diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs index 9c7afce..3c796b9 100644 --- a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs +++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs
@@ -18,6 +18,8 @@ impl Trait for S { reuse to_reuse::foo { self } reuse Trait::foo; //~^ ERROR duplicate definitions with name `foo` + //~| ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: mismatched types } fn main() {}
diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr index a0f1578..83d69d2 100644 --- a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr +++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr
@@ -9,6 +9,32 @@ LL | reuse Trait::foo; | ^^^^^^^^^^^^^^^^^ duplicate definition -error: aborting due to 1 previous error +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/duplicate-definition-inside-trait-impl.rs:19:18 + | +LL | reuse Trait::foo; + | ^^^ argument #1 of type `&_` is missing + | +note: method defined here + --> $DIR/duplicate-definition-inside-trait-impl.rs:5:8 + | +LL | fn foo(&self) -> u32 { 0 } + | ^^^ ----- +help: provide the argument + | +LL | reuse Trait::foo(/* value */); + | +++++++++++++ -For more information about this error, try `rustc --explain E0201`. +error[E0308]: mismatched types + --> $DIR/duplicate-definition-inside-trait-impl.rs:19:18 + | +LL | reuse Trait::foo; + | ^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `u32` + | expected `()` because of default return type + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0061, E0201, E0308. +For more information about an error, try `rustc --explain E0061`.
diff --git a/tests/ui/delegation/glob-glob-conflict.rs b/tests/ui/delegation/glob-glob-conflict.rs index 2843bf8..cb07a78 100644 --- a/tests/ui/delegation/glob-glob-conflict.rs +++ b/tests/ui/delegation/glob-glob-conflict.rs
@@ -3,9 +3,13 @@ trait Trait1 { fn method(&self) -> u8; + //~^ ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: mismatched types } trait Trait2 { fn method(&self) -> u8; + //~^ ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: mismatched types } trait Trait { fn method(&self) -> u8;
diff --git a/tests/ui/delegation/glob-glob-conflict.stderr b/tests/ui/delegation/glob-glob-conflict.stderr index 8c7e5a4..4259d71 100644 --- a/tests/ui/delegation/glob-glob-conflict.stderr +++ b/tests/ui/delegation/glob-glob-conflict.stderr
@@ -1,5 +1,5 @@ error[E0201]: duplicate definitions with name `method`: - --> $DIR/glob-glob-conflict.rs:26:5 + --> $DIR/glob-glob-conflict.rs:30:5 | LL | fn method(&self) -> u8; | ----------------------- item in trait @@ -10,7 +10,7 @@ | ^^^^^^^^^^^^^^^^ duplicate definition error[E0201]: duplicate definitions with name `method`: - --> $DIR/glob-glob-conflict.rs:30:5 + --> $DIR/glob-glob-conflict.rs:34:5 | LL | fn method(&self) -> u8; | ----------------------- item in trait @@ -20,6 +20,57 @@ LL | reuse Trait1::*; | ^^^^^^^^^^^^^^^^ duplicate definition -error: aborting due to 2 previous errors +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/glob-glob-conflict.rs:10:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ argument #1 of type `&_` is missing + | +note: method defined here + --> $DIR/glob-glob-conflict.rs:10:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ ---- +help: provide the argument + | +LL | fn method(/* value */)(&self) -> u8; + | +++++++++++++ -For more information about this error, try `rustc --explain E0201`. +error[E0308]: mismatched types + --> $DIR/glob-glob-conflict.rs:10:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `u8` + | expected `()` because of default return type + +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/glob-glob-conflict.rs:5:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ argument #1 of type `&_` is missing + | +note: method defined here + --> $DIR/glob-glob-conflict.rs:5:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ ---- +help: provide the argument + | +LL | fn method(/* value */)(&self) -> u8; + | +++++++++++++ + +error[E0308]: mismatched types + --> $DIR/glob-glob-conflict.rs:5:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `u8` + | expected `()` because of default return type + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0061, E0201, E0308. +For more information about an error, try `rustc --explain E0061`.
diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index 6bf3a08..2716347 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs
@@ -4,9 +4,11 @@ trait Trait { reuse Trait::foo { &self.0 } //~^ ERROR failed to resolve delegation callee + //~| ERROR: this function takes 0 arguments but 1 argument was supplied } reuse foo; //~^ ERROR failed to resolve delegation callee +//~| WARN: function cannot return without recursing fn main() {}
diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index 40be6be4..90ad839 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr
@@ -5,10 +5,40 @@ | ^^^ error: failed to resolve delegation callee - --> $DIR/ice-issue-124347.rs:9:7 + --> $DIR/ice-issue-124347.rs:10:7 | LL | reuse foo; | ^^^ -error: aborting due to 2 previous errors +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ ------- unexpected argument + | +note: associated function defined here + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ +help: remove the extra argument + | +LL - reuse Trait::foo { &self.0 } +LL + reuse Trait::fo&self.0 } + | +warning: function cannot return without recursing + --> $DIR/ice-issue-124347.rs:10:7 + | +LL | reuse foo; + | ^^^ + | | + | cannot return without recursing + | recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/delegation/recursive-delegation-errors.rs b/tests/ui/delegation/recursive-delegation-errors.rs index 194182e..da295b0 100644 --- a/tests/ui/delegation/recursive-delegation-errors.rs +++ b/tests/ui/delegation/recursive-delegation-errors.rs
@@ -5,6 +5,7 @@ mod first_mod { reuse foo; //~^ ERROR failed to resolve delegation callee + //~| WARN: function cannot return without recursing } mod second_mod { @@ -33,8 +34,10 @@ mod fourth_mod { trait Trait { reuse Trait::foo as bar; //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR: type annotations needed reuse Trait::bar as foo; //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR: type annotations needed } } @@ -48,6 +51,9 @@ trait GlobReuse { //~^ ERROR encountered a cycle during delegation signature resolution //~| ERROR encountered a cycle during delegation signature resolution //~| ERROR encountered a cycle during delegation signature resolution + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed } }
diff --git a/tests/ui/delegation/recursive-delegation-errors.stderr b/tests/ui/delegation/recursive-delegation-errors.stderr index 9c4e316..bf446bd 100644 --- a/tests/ui/delegation/recursive-delegation-errors.stderr +++ b/tests/ui/delegation/recursive-delegation-errors.stderr
@@ -5,94 +5,147 @@ | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:11:11 + --> $DIR/recursive-delegation-errors.rs:12:11 | LL | reuse foo as bar; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:13:11 + --> $DIR/recursive-delegation-errors.rs:14:11 | LL | reuse bar as foo; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:18:11 + --> $DIR/recursive-delegation-errors.rs:19:11 | LL | reuse foo as foo1; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:20:11 + --> $DIR/recursive-delegation-errors.rs:21:11 | LL | reuse foo1 as foo2; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:22:11 + --> $DIR/recursive-delegation-errors.rs:23:11 | LL | reuse foo2 as foo3; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:24:11 + --> $DIR/recursive-delegation-errors.rs:25:11 | LL | reuse foo3 as foo4; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:26:11 + --> $DIR/recursive-delegation-errors.rs:27:11 | LL | reuse foo4 as foo5; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:28:11 + --> $DIR/recursive-delegation-errors.rs:29:11 | LL | reuse foo5 as foo; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:34:22 + --> $DIR/recursive-delegation-errors.rs:35:22 | LL | reuse Trait::foo as bar; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:36:22 + --> $DIR/recursive-delegation-errors.rs:38:22 | LL | reuse Trait::bar as foo; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:42:30 + --> $DIR/recursive-delegation-errors.rs:45:30 | LL | reuse super::fifth_mod::{bar as foo, foo as bar}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:42:42 + --> $DIR/recursive-delegation-errors.rs:45:42 | LL | reuse super::fifth_mod::{bar as foo, foo as bar}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:47:27 + --> $DIR/recursive-delegation-errors.rs:50:27 | LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:47:39 + --> $DIR/recursive-delegation-errors.rs:50:39 | LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:47:51 + --> $DIR/recursive-delegation-errors.rs:50:51 | LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; | ^^^ -error: aborting due to 16 previous errors +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:35:22 + | +LL | reuse Trait::foo as bar; + | ^^^ cannot infer type + | + = note: the type must implement `fourth_mod::Trait` +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:38:22 + | +LL | reuse Trait::bar as foo; + | ^^^ cannot infer type + | + = note: the type must implement `fourth_mod::Trait` + +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:50:27 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ cannot infer type + | + = note: the type must implement `GlobReuse` + +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:50:39 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ cannot infer type + | + = note: the type must implement `GlobReuse` + +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:50:51 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ cannot infer type + | + = note: the type must implement `GlobReuse` + +warning: function cannot return without recursing + --> $DIR/recursive-delegation-errors.rs:6:11 + | +LL | reuse foo; + | ^^^ + | | + | cannot return without recursing + | recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: aborting due to 21 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/delegation/unlowered-path-ice-154820.rs b/tests/ui/delegation/unlowered-path-ice-154820.rs new file mode 100644 index 0000000..a527b17 --- /dev/null +++ b/tests/ui/delegation/unlowered-path-ice-154820.rs
@@ -0,0 +1,12 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +reuse foo:: < { //~ ERROR: failed to resolve delegation callee + //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied + fn foo() {} + reuse foo; + //~^ ERROR: the name `foo` is defined multiple times + } + >; + +fn main() {}
diff --git a/tests/ui/delegation/unlowered-path-ice-154820.stderr b/tests/ui/delegation/unlowered-path-ice-154820.stderr new file mode 100644 index 0000000..fbcb3ca --- /dev/null +++ b/tests/ui/delegation/unlowered-path-ice-154820.stderr
@@ -0,0 +1,40 @@ +error[E0428]: the name `foo` is defined multiple times + --> $DIR/unlowered-path-ice-154820.rs:7:5 + | +LL | fn foo() {} + | -------- previous definition of the value `foo` here +LL | reuse foo; + | ^^^^^^^^^^ `foo` redefined here + | + = note: `foo` must be defined only once in the value namespace of this block + +error: failed to resolve delegation callee + --> $DIR/unlowered-path-ice-154820.rs:4:7 + | +LL | reuse foo:: < { + | ^^^ + +error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/unlowered-path-ice-154820.rs:4:7 + | +LL | reuse foo:: < { + | _______^^^- + | | | + | | expected 0 generic arguments +LL | | +LL | | fn foo() {} +LL | | reuse foo; +... | +LL | | >; + | |___- help: remove the unnecessary generics + | +note: function defined here, with 0 generic parameters + --> $DIR/unlowered-path-ice-154820.rs:4:7 + | +LL | reuse foo:: < { + | ^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0428. +For more information about an error, try `rustc --explain E0107`.