Skip to content

Commit a500a43

Browse files
authored
Rollup merge of rust-lang#137824 - estebank:rtn-sugg, r=compiler-errors
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 {} | ``` r? ``@compiler-errors``
2 parents 88e7547 + adb5eca commit a500a43

File tree

9 files changed

+133
-44
lines changed

9 files changed

+133
-44
lines changed

Diff for: compiler/rustc_ast_lowering/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ ast_lowering_bad_return_type_notation_inputs =
3737
.suggestion = remove the input types
3838
3939
ast_lowering_bad_return_type_notation_needs_dots = return type notation arguments must be elided with `..`
40-
.suggestion = add `..`
40+
.suggestion = use the correct syntax by adding `..` to the arguments
4141
4242
ast_lowering_bad_return_type_notation_output =
4343
return type not allowed with return type notation
44-
.suggestion = remove the return type
44+
ast_lowering_bad_return_type_notation_output_suggestion = use the right argument notation and remove the return type
4545
4646
ast_lowering_bad_return_type_notation_position = return type notation not allowed in this position yet
4747

Diff for: compiler/rustc_ast_lowering/src/errors.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -373,24 +373,39 @@ pub(crate) struct InclusiveRangeWithNoEnd {
373373
pub span: Span,
374374
}
375375

376+
#[derive(Subdiagnostic)]
377+
#[multipart_suggestion(
378+
ast_lowering_bad_return_type_notation_output_suggestion,
379+
applicability = "machine-applicable",
380+
style = "verbose"
381+
)]
382+
/// Given `T: Tr<m() -> Ret>` or `T: Tr<m(Ty) -> Ret>`, suggest `T: Tr<m(..)>`.
383+
pub(crate) struct RTNSuggestion {
384+
#[suggestion_part(code = "")]
385+
pub output: Span,
386+
#[suggestion_part(code = "(..)")]
387+
pub input: Span,
388+
}
389+
376390
#[derive(Diagnostic)]
377391
pub(crate) enum BadReturnTypeNotation {
378392
#[diag(ast_lowering_bad_return_type_notation_inputs)]
379393
Inputs {
380394
#[primary_span]
381-
#[suggestion(code = "()", applicability = "maybe-incorrect")]
395+
#[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")]
382396
span: Span,
383397
},
384398
#[diag(ast_lowering_bad_return_type_notation_output)]
385399
Output {
386400
#[primary_span]
387-
#[suggestion(code = "", applicability = "maybe-incorrect")]
388401
span: Span,
402+
#[subdiagnostic]
403+
suggestion: RTNSuggestion,
389404
},
390405
#[diag(ast_lowering_bad_return_type_notation_needs_dots)]
391406
NeedsDots {
392407
#[primary_span]
393-
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
408+
#[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")]
394409
span: Span,
395410
},
396411
#[diag(ast_lowering_bad_return_type_notation_position)]

Diff for: compiler/rustc_ast_lowering/src/lib.rs

+20-12
Original file line numberDiff line numberDiff line change
@@ -926,19 +926,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
926926
if let Some(first_char) = constraint.ident.as_str().chars().next()
927927
&& first_char.is_ascii_lowercase()
928928
{
929-
let mut err = if !data.inputs.is_empty() {
930-
self.dcx().create_err(errors::BadReturnTypeNotation::Inputs {
931-
span: data.inputs_span,
932-
})
933-
} else if let FnRetTy::Ty(ty) = &data.output {
934-
self.dcx().create_err(errors::BadReturnTypeNotation::Output {
935-
span: data.inputs_span.shrink_to_hi().to(ty.span),
936-
})
937-
} else {
938-
self.dcx().create_err(errors::BadReturnTypeNotation::NeedsDots {
939-
span: data.inputs_span,
940-
})
929+
tracing::info!(?data, ?data.inputs);
930+
let err = match (&data.inputs[..], &data.output) {
931+
([_, ..], FnRetTy::Default(_)) => {
932+
errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
933+
}
934+
([], FnRetTy::Default(_)) => {
935+
errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
936+
}
937+
// The case `T: Trait<method(..) -> Ret>` is handled in the parser.
938+
(_, FnRetTy::Ty(ty)) => {
939+
let span = data.inputs_span.shrink_to_hi().to(ty.span);
940+
errors::BadReturnTypeNotation::Output {
941+
span,
942+
suggestion: errors::RTNSuggestion {
943+
output: span,
944+
input: data.inputs_span,
945+
},
946+
}
947+
}
941948
};
949+
let mut err = self.dcx().create_err(err);
942950
if !self.tcx.features().return_type_notation()
943951
&& self.tcx.sess.is_nightly_build()
944952
{

Diff for: compiler/rustc_ast_lowering/src/path.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use tracing::{debug, instrument};
1313

1414
use super::errors::{
1515
AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, BadReturnTypeNotation,
16-
GenericTypeWithParentheses, UseAngleBrackets,
16+
GenericTypeWithParentheses, RTNSuggestion, UseAngleBrackets,
1717
};
1818
use super::{
1919
AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition,
@@ -268,19 +268,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
268268
}
269269
GenericArgs::Parenthesized(data) => match generic_args_mode {
270270
GenericArgsMode::ReturnTypeNotation => {
271-
let mut err = if !data.inputs.is_empty() {
272-
self.dcx().create_err(BadReturnTypeNotation::Inputs {
273-
span: data.inputs_span,
274-
})
275-
} else if let FnRetTy::Ty(ty) = &data.output {
276-
self.dcx().create_err(BadReturnTypeNotation::Output {
277-
span: data.inputs_span.shrink_to_hi().to(ty.span),
278-
})
279-
} else {
280-
self.dcx().create_err(BadReturnTypeNotation::NeedsDots {
281-
span: data.inputs_span,
282-
})
271+
tracing::info!(?data, ?data.inputs);
272+
let err = match (&data.inputs[..], &data.output) {
273+
([_, ..], FnRetTy::Default(_)) => {
274+
BadReturnTypeNotation::Inputs { span: data.inputs_span }
275+
}
276+
([], FnRetTy::Default(_)) => {
277+
BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
278+
}
279+
// The case `T: Trait<method(..) -> Ret>` is handled in the parser.
280+
(_, FnRetTy::Ty(ty)) => {
281+
let span = data.inputs_span.shrink_to_hi().to(ty.span);
282+
BadReturnTypeNotation::Output {
283+
span,
284+
suggestion: RTNSuggestion {
285+
output: span,
286+
input: data.inputs_span,
287+
},
288+
}
289+
}
283290
};
291+
let mut err = self.dcx().create_err(err);
284292
if !self.tcx.features().return_type_notation()
285293
&& self.tcx.sess.is_nightly_build()
286294
{

Diff for: compiler/rustc_parse/src/errors.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2922,8 +2922,9 @@ pub(crate) struct AddBoxNew {
29222922
#[diag(parse_bad_return_type_notation_output)]
29232923
pub(crate) struct BadReturnTypeNotationOutput {
29242924
#[primary_span]
2925-
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
29262925
pub span: Span,
2926+
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
2927+
pub suggestion: Span,
29272928
}
29282929

29292930
#[derive(Diagnostic)]

Diff for: compiler/rustc_parse/src/parser/path.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,14 @@ impl<'a> Parser<'a> {
382382

383383
self.psess.gated_spans.gate(sym::return_type_notation, span);
384384

385+
let prev_lo = self.prev_token.span.shrink_to_hi();
385386
if self.eat_noexpect(&token::RArrow) {
386387
let lo = self.prev_token.span;
387388
let ty = self.parse_ty()?;
389+
let span = lo.to(ty.span);
390+
let suggestion = prev_lo.to(ty.span);
388391
self.dcx()
389-
.emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) });
392+
.emit_err(errors::BadReturnTypeNotationOutput { span, suggestion });
390393
}
391394

392395
P(ast::GenericArgs::ParenthesizedElided(span))

Diff for: tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ fn foo_path<T: Trait>() where T::method(i32): Send {}
2121
fn bar_path<T: Trait>() where T::method() -> (): Send {}
2222
//~^ ERROR return type not allowed with return type notation
2323

24+
fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
25+
//~^ ERROR return type not allowed with return type notation
26+
2427
fn baz_path<T: Trait>() where T::method(): Send {}
2528
//~^ ERROR return type notation arguments must be elided with `..`
2629

Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
1+
error: return type not allowed with return type notation
2+
--> $DIR/bad-inputs-and-output.rs:24:45
3+
|
4+
LL | fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
5+
| ^^^^^
6+
|
7+
help: remove the return type
8+
|
9+
LL - fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
10+
LL + fn bay_path<T: Trait>() where T::method(..): Send {}
11+
|
12+
113
error[E0575]: expected associated type, found associated function `Trait::method`
2-
--> $DIR/bad-inputs-and-output.rs:27:36
14+
--> $DIR/bad-inputs-and-output.rs:30:36
315
|
416
LL | fn foo_qualified<T: Trait>() where <T as Trait>::method(i32): Send {}
517
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type
618

719
error[E0575]: expected associated type, found associated function `Trait::method`
8-
--> $DIR/bad-inputs-and-output.rs:30:36
20+
--> $DIR/bad-inputs-and-output.rs:33:36
921
|
1022
LL | fn bar_qualified<T: Trait>() where <T as Trait>::method() -> (): Send {}
1123
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type
1224

1325
error[E0575]: expected associated type, found associated function `Trait::method`
14-
--> $DIR/bad-inputs-and-output.rs:33:36
26+
--> $DIR/bad-inputs-and-output.rs:36:36
1527
|
1628
LL | fn baz_qualified<T: Trait>() where <T as Trait>::method(): Send {}
1729
| ^^^^^^^^^^^^^^^^^^^^^^ not a associated type
@@ -20,38 +32,72 @@ error: argument types not allowed with return type notation
2032
--> $DIR/bad-inputs-and-output.rs:9:23
2133
|
2234
LL | fn foo<T: Trait<method(i32): Send>>() {}
23-
| ^^^^^ help: remove the input types: `()`
35+
| ^^^^^
36+
|
37+
help: remove the input types
38+
|
39+
LL - fn foo<T: Trait<method(i32): Send>>() {}
40+
LL + fn foo<T: Trait<method(..): Send>>() {}
41+
|
2442

2543
error: return type not allowed with return type notation
2644
--> $DIR/bad-inputs-and-output.rs:12:25
2745
|
2846
LL | fn bar<T: Trait<method() -> (): Send>>() {}
29-
| ^^^^^^ help: remove the return type
47+
| ^^^^^^
48+
|
49+
help: use the right argument notation and remove the return type
50+
|
51+
LL - fn bar<T: Trait<method() -> (): Send>>() {}
52+
LL + fn bar<T: Trait<method(..): Send>>() {}
53+
|
3054

3155
error: return type notation arguments must be elided with `..`
3256
--> $DIR/bad-inputs-and-output.rs:15:23
3357
|
3458
LL | fn baz<T: Trait<method(): Send>>() {}
35-
| ^^ help: add `..`: `(..)`
59+
| ^^
60+
|
61+
help: use the correct syntax by adding `..` to the arguments
62+
|
63+
LL | fn baz<T: Trait<method(..): Send>>() {}
64+
| ++
3665

3766
error: argument types not allowed with return type notation
3867
--> $DIR/bad-inputs-and-output.rs:18:40
3968
|
4069
LL | fn foo_path<T: Trait>() where T::method(i32): Send {}
41-
| ^^^^^ help: remove the input types: `()`
70+
| ^^^^^
71+
|
72+
help: remove the input types
73+
|
74+
LL - fn foo_path<T: Trait>() where T::method(i32): Send {}
75+
LL + fn foo_path<T: Trait>() where T::method(..): Send {}
76+
|
4277

4378
error: return type not allowed with return type notation
4479
--> $DIR/bad-inputs-and-output.rs:21:42
4580
|
4681
LL | fn bar_path<T: Trait>() where T::method() -> (): Send {}
47-
| ^^^^^^ help: remove the return type
82+
| ^^^^^^
83+
|
84+
help: use the right argument notation and remove the return type
85+
|
86+
LL - fn bar_path<T: Trait>() where T::method() -> (): Send {}
87+
LL + fn bar_path<T: Trait>() where T::method(..): Send {}
88+
|
4889

4990
error: return type notation arguments must be elided with `..`
50-
--> $DIR/bad-inputs-and-output.rs:24:40
91+
--> $DIR/bad-inputs-and-output.rs:27:40
5192
|
5293
LL | fn baz_path<T: Trait>() where T::method(): Send {}
53-
| ^^ help: add `..`: `(..)`
94+
| ^^
95+
|
96+
help: use the correct syntax by adding `..` to the arguments
97+
|
98+
LL | fn baz_path<T: Trait>() where T::method(..): Send {}
99+
| ++
54100

55-
error: aborting due to 9 previous errors
101+
error: aborting due to 10 previous errors
56102

57103
For more information about this error, try `rustc --explain E0575`.

Diff for: tests/ui/suggestions/let-binding-init-expr-as-ty.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ error: argument types not allowed with return type notation
1010
--> $DIR/let-binding-init-expr-as-ty.rs:2:26
1111
|
1212
LL | let foo: i32::from_be(num);
13-
| ^^^^^ help: remove the input types: `()`
13+
| ^^^^^
1414
|
1515
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
1616
= help: add `#![feature(return_type_notation)]` to the crate attributes to enable
1717
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
18+
help: remove the input types
19+
|
20+
LL - let foo: i32::from_be(num);
21+
LL + let foo: i32::from_be(..);
22+
|
1823

1924
error: return type notation not allowed in this position yet
2025
--> $DIR/let-binding-init-expr-as-ty.rs:2:14

0 commit comments

Comments
 (0)