Tweak invalid RTN errors

Make suggestions verbose.

When encountering `method(type)` bound, suggest `method(..)` instead of `method()`.

```
error: argument types not allowed with return type notation
  --> $DIR/bad-inputs-and-output.rs:9:23
   |
LL | fn foo<T: Trait<method(i32): Send>>() {}
   |                       ^^^^^
   |
help: remove the input types
   |
LL - fn foo<T: Trait<method(i32): Send>>() {}
LL + fn foo<T: Trait<method(..): Send>>() {}
   |
```

When encountering both return type and arg list that isn't `..`, suggest replacing both.

```
error: return type not allowed with return type notation
  --> $DIR/bad-inputs-and-output.rs:12:25
   |
LL | fn bar<T: Trait<method() -> (): Send>>() {}
   |                         ^^^^^^
   |
help: use the right argument notation and remove the return type
   |
LL - fn bar<T: Trait<method() -> (): Send>>() {}
LL + fn bar<T: Trait<method(..): Send>>() {}
   |
```

When encountering a return type, suggest removing it including the leading whitespace.

```
error: return type not allowed with return type notation
  --> $DIR/bad-inputs-and-output.rs:24:45
   |
LL | fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
   |                                             ^^^^^
   |
help: remove the return type
   |
LL - fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
LL + fn bay_path<T: Trait>() where T::method(..): Send {}
   |
```
This commit is contained in:
Esteban Küber
2025-02-28 20:05:43 +00:00
parent f45d4acf1b
commit adb5ecabdb
9 changed files with 133 additions and 44 deletions

View File

@@ -13,7 +13,7 @@ use tracing::{debug, instrument};
use super::errors::{
AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, BadReturnTypeNotation,
GenericTypeWithParentheses, UseAngleBrackets,
GenericTypeWithParentheses, RTNSuggestion, UseAngleBrackets,
};
use super::{
AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition,
@@ -268,19 +268,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
GenericArgs::Parenthesized(data) => match generic_args_mode {
GenericArgsMode::ReturnTypeNotation => {
let mut err = if !data.inputs.is_empty() {
self.dcx().create_err(BadReturnTypeNotation::Inputs {
span: data.inputs_span,
})
} else if let FnRetTy::Ty(ty) = &data.output {
self.dcx().create_err(BadReturnTypeNotation::Output {
span: data.inputs_span.shrink_to_hi().to(ty.span),
})
} else {
self.dcx().create_err(BadReturnTypeNotation::NeedsDots {
span: data.inputs_span,
})
tracing::info!(?data, ?data.inputs);
let err = match (&data.inputs[..], &data.output) {
([_, ..], FnRetTy::Default(_)) => {
BadReturnTypeNotation::Inputs { span: data.inputs_span }
}
([], FnRetTy::Default(_)) => {
BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
}
// The case `T: Trait<method(..) -> Ret>` is handled in the parser.
(_, FnRetTy::Ty(ty)) => {
let span = data.inputs_span.shrink_to_hi().to(ty.span);
BadReturnTypeNotation::Output {
span,
suggestion: RTNSuggestion {
output: span,
input: data.inputs_span,
},
}
}
};
let mut err = self.dcx().create_err(err);
if !self.tcx.features().return_type_notation()
&& self.tcx.sess.is_nightly_build()
{