@@ -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 } ;
@@ -253,7 +253,7 @@ enum ImplTraitContext {
253
253
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
254
254
///
255
255
/// Newly generated parameters should be inserted into the given `Vec`.
256
- Universal ( LocalDefId ) ,
256
+ Universal ,
257
257
258
258
/// Treat `impl Trait` as shorthand for a new opaque type.
259
259
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@@ -857,20 +857,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
857
857
itctx : ImplTraitContext ,
858
858
) -> hir:: TypeBinding < ' hir > {
859
859
debug ! ( "lower_assoc_ty_constraint(constraint={:?}, itctx={:?})" , constraint, itctx) ;
860
-
861
860
// lower generic arguments of identifier in constraint
862
861
let gen_args = if let Some ( ref gen_args) = constraint. gen_args {
863
862
let gen_args_ctor = match gen_args {
864
863
GenericArgs :: AngleBracketed ( ref data) => {
865
864
self . lower_angle_bracketed_parameter_data ( data, ParamMode :: Explicit , itctx) . 0
866
865
}
867
866
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) ;
874
868
self . lower_angle_bracketed_parameter_data (
875
869
& data. as_angle_bracketed_args ( ) ,
876
870
ParamMode :: Explicit ,
@@ -893,7 +887,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
893
887
hir:: TypeBindingKind :: Equality { term }
894
888
}
895
889
AssocConstraintKind :: Bound { ref bounds } => {
896
- let mut parent_def_id = self . current_hir_id_owner ;
897
890
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
898
891
let ( desugar_to_impl_trait, itctx) = match itctx {
899
892
// We are in the return position:
@@ -913,10 +906,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
913
906
// so desugar to
914
907
//
915
908
// fn foo(x: dyn Iterator<Item = impl Debug>)
916
- ImplTraitContext :: Universal ( parent) if self . is_in_dyn_type => {
917
- parent_def_id = parent;
918
- ( true , itctx)
919
- }
909
+ ImplTraitContext :: Universal if self . is_in_dyn_type => ( true , itctx) ,
920
910
921
911
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to
922
912
// `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
@@ -942,6 +932,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
942
932
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
943
933
// constructing the HIR for `impl bounds...` and then lowering that.
944
934
935
+ let parent_def_id = self . current_hir_id_owner ;
945
936
let impl_trait_node_id = self . resolver . next_node_id ( ) ;
946
937
self . resolver . create_def (
947
938
parent_def_id,
@@ -984,6 +975,42 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
984
975
}
985
976
}
986
977
978
+ fn assoc_ty_contraint_param_error_emit ( & self , data : & ParenthesizedArgs ) -> ( ) {
979
+ let mut err = self . sess . struct_span_err (
980
+ data. span ,
981
+ "parenthesized generic arguments cannot be used in associated type constraints" ,
982
+ ) ;
983
+ // Suggest removing empty parentheses: "Trait()" -> "Trait"
984
+ if data. inputs . is_empty ( ) {
985
+ let parentheses_span =
986
+ data. inputs_span . shrink_to_lo ( ) . to ( data. inputs_span . shrink_to_hi ( ) ) ;
987
+ err. multipart_suggestion (
988
+ "remove these parentheses" ,
989
+ vec ! [ ( parentheses_span, String :: new( ) ) ] ,
990
+ Applicability :: MaybeIncorrect ,
991
+ ) ;
992
+ }
993
+ // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
994
+ else {
995
+ // Start of parameters to the 1st argument
996
+ let open_param = data. inputs_span . shrink_to_lo ( ) . to ( data
997
+ . inputs
998
+ . first ( )
999
+ . unwrap ( )
1000
+ . span
1001
+ . shrink_to_lo ( ) ) ;
1002
+ // End of last argument to end of parameters
1003
+ let close_param =
1004
+ data. inputs . last ( ) . unwrap ( ) . span . shrink_to_hi ( ) . to ( data. inputs_span . shrink_to_hi ( ) ) ;
1005
+ err. multipart_suggestion (
1006
+ & format ! ( "use angle brackets instead" , ) ,
1007
+ vec ! [ ( open_param, String :: from( "<" ) ) , ( close_param, String :: from( ">" ) ) ] ,
1008
+ Applicability :: MaybeIncorrect ,
1009
+ ) ;
1010
+ }
1011
+ err. emit ( ) ;
1012
+ }
1013
+
987
1014
fn lower_generic_arg (
988
1015
& mut self ,
989
1016
arg : & ast:: GenericArg ,
@@ -1184,12 +1211,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1184
1211
|this| this. lower_param_bounds ( bounds, nested_itctx) ,
1185
1212
)
1186
1213
}
1187
- ImplTraitContext :: Universal ( parent_def_id ) => {
1214
+ ImplTraitContext :: Universal => {
1188
1215
// Add a definition for the in-band `Param`.
1189
1216
let def_id = self . resolver . local_def_id ( def_node_id) ;
1190
1217
1191
- let hir_bounds = self
1192
- . lower_param_bounds ( bounds, ImplTraitContext :: Universal ( parent_def_id ) ) ;
1218
+ let hir_bounds =
1219
+ self . lower_param_bounds ( bounds, ImplTraitContext :: Universal ) ;
1193
1220
// Set the name to `impl Bound1 + Bound2`.
1194
1221
let ident = Ident :: from_str_and_span ( & pprust:: ty_to_string ( t) , span) ;
1195
1222
let param = hir:: GenericParam {
@@ -1399,10 +1426,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1399
1426
}
1400
1427
let inputs = self . arena . alloc_from_iter ( inputs. iter ( ) . map ( |param| {
1401
1428
if fn_node_id. is_some ( ) {
1402
- self . lower_ty_direct (
1403
- & param. ty ,
1404
- ImplTraitContext :: Universal ( self . current_hir_id_owner ) ,
1405
- )
1429
+ self . lower_ty_direct ( & param. ty , ImplTraitContext :: Universal )
1406
1430
} else {
1407
1431
self . lower_ty_direct (
1408
1432
& param. ty ,
0 commit comments