@@ -46,7 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4646use rustc_data_structures:: sorted_map:: SortedMap ;
4747use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
4848use rustc_data_structures:: sync:: Lrc ;
49- use rustc_errors:: struct_span_err;
49+ use rustc_errors:: { struct_span_err, Applicability } ;
5050use rustc_hir as hir;
5151use rustc_hir:: def:: { DefKind , Namespace , PartialRes , PerNS , Res } ;
5252use 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 ,
0 commit comments