Skip to content

Commit 401be78

Browse files
authored
Rollup merge of #97656 - EdwinRy:error_ast_low_type_contraint_parentheses, r=cjgillot
Add a suggestion to replace parentheses with angle brackets on associated trait constraint This implements a requested suggestion FIXME in [`compiler/rustc_ast_lowering/src/lib.rs` ](https://github.com/rust-lang/rust/blob/9598b4b594c97dff66feb93522e22db500deea07/compiler/rustc_ast_lowering/src/lib.rs#L921) The suggestion asks for the parentheses to either be replaced with angle brackets or removed completely depending on whether there are arguments provided within. ![image](https://user-images.githubusercontent.com/20026256/171770414-ab60bfe2-ae27-44b0-964d-9ffcc32a7475.png) ![image](https://user-images.githubusercontent.com/20026256/171770383-ca8a2766-b3aa-43e3-8ba4-ae18874886ce.png) r? `@oli-obk`
2 parents e33c6ed + cd03fe1 commit 401be78

File tree

3 files changed

+73
-9
lines changed

3 files changed

+73
-9
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+38-8
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4646
use rustc_data_structures::sorted_map::SortedMap;
4747
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4848
use rustc_data_structures::sync::Lrc;
49-
use rustc_errors::struct_span_err;
49+
use rustc_errors::{struct_span_err, Applicability};
5050
use rustc_hir as hir;
5151
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
5252
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
@@ -857,20 +857,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
857857
itctx: ImplTraitContext,
858858
) -> hir::TypeBinding<'hir> {
859859
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
860-
861860
// lower generic arguments of identifier in constraint
862861
let gen_args = if let Some(ref gen_args) = constraint.gen_args {
863862
let gen_args_ctor = match gen_args {
864863
GenericArgs::AngleBracketed(ref data) => {
865864
self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
866865
}
867866
GenericArgs::Parenthesized(ref data) => {
868-
let mut err = self.sess.struct_span_err(
869-
gen_args.span(),
870-
"parenthesized generic arguments cannot be used in associated type constraints"
871-
);
872-
// FIXME: try to write a suggestion here
873-
err.emit();
867+
self.assoc_ty_contraint_param_error_emit(data);
874868
self.lower_angle_bracketed_parameter_data(
875869
&data.as_angle_bracketed_args(),
876870
ParamMode::Explicit,
@@ -984,6 +978,42 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
984978
}
985979
}
986980

981+
fn assoc_ty_contraint_param_error_emit(&self, data: &ParenthesizedArgs) -> () {
982+
let mut err = self.sess.struct_span_err(
983+
data.span,
984+
"parenthesized generic arguments cannot be used in associated type constraints",
985+
);
986+
// Suggest removing empty parentheses: "Trait()" -> "Trait"
987+
if data.inputs.is_empty() {
988+
let parentheses_span =
989+
data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
990+
err.multipart_suggestion(
991+
"remove these parentheses",
992+
vec![(parentheses_span, String::new())],
993+
Applicability::MaybeIncorrect,
994+
);
995+
}
996+
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
997+
else {
998+
// Start of parameters to the 1st argument
999+
let open_param = data.inputs_span.shrink_to_lo().to(data
1000+
.inputs
1001+
.first()
1002+
.unwrap()
1003+
.span
1004+
.shrink_to_lo());
1005+
// End of last argument to end of parameters
1006+
let close_param =
1007+
data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1008+
err.multipart_suggestion(
1009+
&format!("use angle brackets instead",),
1010+
vec![(open_param, String::from("<")), (close_param, String::from(">"))],
1011+
Applicability::MaybeIncorrect,
1012+
);
1013+
}
1014+
err.emit();
1015+
}
1016+
9871017
fn lower_generic_arg(
9881018
&mut self,
9891019
arg: &ast::GenericArg,

src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs

+5
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
1010
//~| ERROR this associated type takes 0 generic arguments but 1 generic argument
1111
//~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
1212

13+
14+
fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
15+
//~^ ERROR: parenthesized generic arguments cannot be used
16+
//~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
17+
1318
fn main() {}

src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr

+30-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ error: parenthesized generic arguments cannot be used in associated type constra
99
|
1010
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
1111
| ^^^^^
12+
|
13+
help: use angle brackets instead
14+
|
15+
LL | fn foo<'a>(arg: Box<dyn X<Y<'a> = &'a ()>>) {}
16+
| ~ ~
17+
18+
error: parenthesized generic arguments cannot be used in associated type constraints
19+
--> $DIR/gat-trait-path-parenthesised-args.rs:14:27
20+
|
21+
LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
22+
| ^--
23+
| |
24+
| help: remove these parentheses
1225

1326
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
1427
--> $DIR/gat-trait-path-parenthesised-args.rs:7:27
@@ -40,6 +53,22 @@ note: associated type defined here, with 0 generic parameters
4053
LL | type Y<'a>;
4154
| ^
4255

43-
error: aborting due to 4 previous errors
56+
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
57+
--> $DIR/gat-trait-path-parenthesised-args.rs:14:27
58+
|
59+
LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
60+
| ^ expected 1 lifetime argument
61+
|
62+
note: associated type defined here, with 1 lifetime parameter: `'a`
63+
--> $DIR/gat-trait-path-parenthesised-args.rs:4:8
64+
|
65+
LL | type Y<'a>;
66+
| ^ --
67+
help: add missing lifetime argument
68+
|
69+
LL | fn bar<'a>(arg: Box<dyn X<Y('a) = ()>>) {}
70+
| ++
71+
72+
error: aborting due to 6 previous errors
4473

4574
For more information about this error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)