Skip to content

Commit dae3e5a

Browse files
committed
Add suggestion to either change or remove parentheses from trait
1 parent 395a09c commit dae3e5a

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 35 additions & 3 deletions
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};
@@ -901,7 +901,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
901901
mut itctx: ImplTraitContext<'_, 'hir>,
902902
) -> hir::TypeBinding<'hir> {
903903
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
904-
905904
// lower generic arguments of identifier in constraint
906905
let gen_args = if let Some(ref gen_args) = constraint.gen_args {
907906
let gen_args_ctor = match gen_args {
@@ -918,7 +917,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
918917
gen_args.span(),
919918
"parenthesized generic arguments cannot be used in associated type constraints"
920919
);
921-
// FIXME: try to write a suggestion here
920+
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
921+
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
922+
if !data.inputs.is_empty() {
923+
// Suggest replacing `(` and `)` with `<` and `>`
924+
// The snippet may be missing the closing `)`, skip that case
925+
if snippet.ends_with(')') {
926+
if let Some(split) = snippet.find('(') {
927+
let trait_name = &snippet[0..split];
928+
let args = &snippet[split + 1..snippet.len() - 1];
929+
err.span_suggestion(
930+
data.span,
931+
"use angle brackets instead",
932+
format!("{}<{}>", trait_name, args),
933+
Applicability::MaybeIncorrect,
934+
);
935+
}
936+
}
937+
}
938+
// Suggest removing empty parentheses: "Trait()" -> "Trait"
939+
else {
940+
// The snippet may be missing the closing `)`, skip that case
941+
if snippet.ends_with(')') {
942+
if let Some(split) = snippet.find('(') {
943+
let trait_name = &snippet[0..split];
944+
err.span_suggestion(
945+
data.span,
946+
"remove parentheses",
947+
format!("{}", trait_name),
948+
Applicability::MaybeIncorrect,
949+
);
950+
}
951+
}
952+
}
953+
};
922954
err.emit();
923955
self.lower_angle_bracketed_parameter_data(
924956
&data.as_angle_bracketed_args(),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ error: parenthesized generic arguments cannot be used in associated type constra
88
--> $DIR/gat-trait-path-parenthesised-args.rs:7:27
99
|
1010
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
11-
| ^^^^^
11+
| ^^^^^ help: use angle brackets instead: `Y<'a>`
1212

1313
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
1414
--> $DIR/gat-trait-path-parenthesised-args.rs:7:27

0 commit comments

Comments
 (0)