@@ -46,7 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
46
46
use rustc_data_structures:: sorted_map:: SortedMap ;
47
47
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
48
48
use rustc_data_structures:: sync:: Lrc ;
49
- use rustc_errors:: struct_span_err;
49
+ use rustc_errors:: { struct_span_err, Applicability } ;
50
50
use rustc_hir as hir;
51
51
use rustc_hir:: def:: { DefKind , Namespace , PartialRes , PerNS , Res } ;
52
52
use rustc_hir:: def_id:: { DefId , DefPathHash , LocalDefId , CRATE_DEF_ID } ;
@@ -901,7 +901,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
901
901
mut itctx : ImplTraitContext < ' _ , ' hir > ,
902
902
) -> hir:: TypeBinding < ' hir > {
903
903
debug ! ( "lower_assoc_ty_constraint(constraint={:?}, itctx={:?})" , constraint, itctx) ;
904
-
905
904
// lower generic arguments of identifier in constraint
906
905
let gen_args = if let Some ( ref gen_args) = constraint. gen_args {
907
906
let gen_args_ctor = match gen_args {
@@ -914,12 +913,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
914
913
. 0
915
914
}
916
915
GenericArgs :: Parenthesized ( ref data) => {
917
- let mut err = self . sess . struct_span_err (
918
- gen_args. span ( ) ,
919
- "parenthesized generic arguments cannot be used in associated type constraints"
920
- ) ;
921
- // FIXME: try to write a suggestion here
922
- err. emit ( ) ;
916
+ self . assoc_ty_contraint_param_error_emit ( data) ;
923
917
self . lower_angle_bracketed_parameter_data (
924
918
& data. as_angle_bracketed_args ( ) ,
925
919
ParamMode :: Explicit ,
@@ -1033,6 +1027,42 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1033
1027
}
1034
1028
}
1035
1029
1030
+ fn assoc_ty_contraint_param_error_emit ( & self , data : & ParenthesizedArgs ) -> ( ) {
1031
+ let mut err = self . sess . struct_span_err (
1032
+ data. span ,
1033
+ "parenthesized generic arguments cannot be used in associated type constraints" ,
1034
+ ) ;
1035
+ // Suggest removing empty parentheses: "Trait()" -> "Trait"
1036
+ if data. inputs . is_empty ( ) {
1037
+ let parentheses_span =
1038
+ data. inputs_span . shrink_to_lo ( ) . to ( data. inputs_span . shrink_to_hi ( ) ) ;
1039
+ err. multipart_suggestion (
1040
+ "remove these parentheses" ,
1041
+ vec ! [ ( parentheses_span, String :: new( ) ) ] ,
1042
+ Applicability :: MaybeIncorrect ,
1043
+ ) ;
1044
+ }
1045
+ // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1046
+ else {
1047
+ // Start of parameters to the 1st argument
1048
+ let open_param = data. inputs_span . shrink_to_lo ( ) . to ( data
1049
+ . inputs
1050
+ . first ( )
1051
+ . unwrap ( )
1052
+ . span
1053
+ . shrink_to_lo ( ) ) ;
1054
+ // End of last argument to end of parameters
1055
+ let close_param =
1056
+ data. inputs . last ( ) . unwrap ( ) . span . shrink_to_hi ( ) . to ( data. inputs_span . shrink_to_hi ( ) ) ;
1057
+ err. multipart_suggestion (
1058
+ & format ! ( "use angle brackets instead" , ) ,
1059
+ vec ! [ ( open_param, String :: from( "<" ) ) , ( close_param, String :: from( ">" ) ) ] ,
1060
+ Applicability :: MaybeIncorrect ,
1061
+ ) ;
1062
+ }
1063
+ err. emit ( ) ;
1064
+ }
1065
+
1036
1066
fn lower_generic_arg (
1037
1067
& mut self ,
1038
1068
arg : & ast:: GenericArg ,
0 commit comments