@@ -16,7 +16,7 @@ use crate::require_c_abi_if_c_variadic;
16
16
use rustc_ast:: TraitObjectSyntax ;
17
17
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
18
18
use rustc_errors:: {
19
- struct_span_err, Applicability , DiagnosticBuilder , ErrorGuaranteed , FatalError ,
19
+ struct_span_err, Applicability , DiagnosticBuilder , ErrorGuaranteed , FatalError , MultiSpan ,
20
20
} ;
21
21
use rustc_hir as hir;
22
22
use rustc_hir:: def:: { CtorOf , DefKind , Namespace , Res } ;
@@ -653,7 +653,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
653
653
span, item_def_id, item_segment
654
654
) ;
655
655
if tcx. generics_of ( item_def_id) . params . is_empty ( ) {
656
- self . prohibit_generics ( slice:: from_ref ( item_segment) ) ;
656
+ self . prohibit_generics ( slice:: from_ref ( item_segment) . iter ( ) ) ;
657
657
658
658
parent_substs
659
659
} else {
@@ -681,7 +681,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
681
681
trait_ref : & hir:: TraitRef < ' _ > ,
682
682
self_ty : Ty < ' tcx > ,
683
683
) -> ty:: TraitRef < ' tcx > {
684
- self . prohibit_generics ( trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 ) ;
684
+ self . prohibit_generics ( trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ) ;
685
685
686
686
self . ast_path_to_mono_trait_ref (
687
687
trait_ref. path . span ,
@@ -784,7 +784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
784
784
let args = trait_segment. args ( ) ;
785
785
let infer_args = trait_segment. infer_args ;
786
786
787
- self . prohibit_generics ( trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 ) ;
787
+ self . prohibit_generics ( trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ) ;
788
788
self . complain_about_internal_fn_trait ( span, trait_def_id, trait_segment, false ) ;
789
789
790
790
self . instantiate_poly_trait_ref_inner (
@@ -1796,7 +1796,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1796
1796
if let Some ( variant_def) = variant_def {
1797
1797
if permit_variants {
1798
1798
tcx. check_stability ( variant_def. def_id , Some ( hir_ref_id) , span, None ) ;
1799
- self . prohibit_generics ( slice:: from_ref ( assoc_segment) ) ;
1799
+ self . prohibit_generics ( slice:: from_ref ( assoc_segment) . iter ( ) ) ;
1800
1800
return Ok ( ( qself_ty, DefKind :: Variant , variant_def. def_id ) ) ;
1801
1801
} else {
1802
1802
variant_resolution = Some ( variant_def. def_id ) ;
@@ -2017,69 +2017,79 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2017
2017
self . normalize_ty ( span, tcx. mk_projection ( item_def_id, item_substs) )
2018
2018
}
2019
2019
2020
- pub fn prohibit_generics < ' a , T : IntoIterator < Item = & ' a hir:: PathSegment < ' a > > > (
2020
+ pub fn prohibit_generics < ' a , T : Iterator < Item = & ' a hir:: PathSegment < ' a > > + Clone > (
2021
2021
& self ,
2022
2022
segments : T ,
2023
2023
) -> bool {
2024
- let mut has_err = false ;
2025
- for segment in segments {
2026
- let ( mut err_for_lt, mut err_for_ty, mut err_for_ct) = ( false , false , false ) ;
2027
- for arg in segment. args ( ) . args {
2028
- let ( span, kind) = match arg {
2029
- hir:: GenericArg :: Lifetime ( lt) => {
2030
- if err_for_lt {
2031
- continue ;
2032
- }
2033
- err_for_lt = true ;
2034
- has_err = true ;
2035
- ( lt. span , "lifetime" )
2036
- }
2037
- hir:: GenericArg :: Type ( ty) => {
2038
- if err_for_ty {
2039
- continue ;
2040
- }
2041
- err_for_ty = true ;
2042
- has_err = true ;
2043
- ( ty. span , "type" )
2044
- }
2045
- hir:: GenericArg :: Const ( ct) => {
2046
- if err_for_ct {
2047
- continue ;
2048
- }
2049
- err_for_ct = true ;
2050
- has_err = true ;
2051
- ( ct. span , "const" )
2052
- }
2053
- hir:: GenericArg :: Infer ( inf) => {
2054
- if err_for_ty {
2055
- continue ;
2056
- }
2057
- has_err = true ;
2058
- err_for_ty = true ;
2059
- ( inf. span , "generic" )
2060
- }
2061
- } ;
2062
- let mut err = struct_span_err ! (
2063
- self . tcx( ) . sess,
2064
- span,
2065
- E0109 ,
2066
- "{} arguments are not allowed for this type" ,
2067
- kind,
2068
- ) ;
2069
- err. span_label ( span, format ! ( "{} argument not allowed" , kind) ) ;
2070
- err. emit ( ) ;
2071
- if err_for_lt && err_for_ty && err_for_ct {
2072
- break ;
2073
- }
2024
+ let args = segments. clone ( ) . flat_map ( |segment| segment. args ( ) . args ) ;
2025
+
2026
+ let ( lt, ty, ct, inf) =
2027
+ args. clone ( ) . fold ( ( false , false , false , false ) , |( lt, ty, ct, inf) , arg| match arg {
2028
+ hir:: GenericArg :: Lifetime ( _) => ( true , ty, ct, inf) ,
2029
+ hir:: GenericArg :: Type ( _) => ( lt, true , ct, inf) ,
2030
+ hir:: GenericArg :: Const ( _) => ( lt, ty, true , inf) ,
2031
+ hir:: GenericArg :: Infer ( _) => ( lt, ty, ct, true ) ,
2032
+ } ) ;
2033
+ let mut emitted = false ;
2034
+ if lt || ty || ct || inf {
2035
+ let arg_spans: Vec < Span > = args
2036
+ . map ( |arg| match arg {
2037
+ hir:: GenericArg :: Lifetime ( lt) => lt. span ,
2038
+ hir:: GenericArg :: Type ( ty) => ty. span ,
2039
+ hir:: GenericArg :: Const ( ct) => ct. span ,
2040
+ hir:: GenericArg :: Infer ( inf) => inf. span ,
2041
+ } )
2042
+ . collect ( ) ;
2043
+
2044
+ let mut types = Vec :: with_capacity ( 4 ) ;
2045
+ if lt {
2046
+ types. push ( "lifetime" ) ;
2047
+ }
2048
+ if ty {
2049
+ types. push ( "type" ) ;
2050
+ }
2051
+ if ct {
2052
+ types. push ( "const" ) ;
2074
2053
}
2054
+ if inf {
2055
+ types. push ( "generic" ) ;
2056
+ }
2057
+ let ( kind, s) = match types[ ..] {
2058
+ [ .., _, last] => (
2059
+ format ! (
2060
+ "{} and `{last}`" ,
2061
+ types[ ..types. len( ) - 1 ]
2062
+ . iter( )
2063
+ . map( |& x| x)
2064
+ . intersperse( ", " )
2065
+ . collect:: <String >( )
2066
+ ) ,
2067
+ "s" ,
2068
+ ) ,
2069
+ [ only] => ( format ! ( "{only}" ) , "" ) ,
2070
+ [ ] => unreachable ! ( ) ,
2071
+ } ;
2072
+ let last_span = * arg_spans. last ( ) . unwrap ( ) ;
2073
+ let span: MultiSpan = arg_spans. into ( ) ;
2074
+ let mut err = struct_span_err ! (
2075
+ self . tcx( ) . sess,
2076
+ span,
2077
+ E0109 ,
2078
+ "{kind} arguments are not allowed for this type" ,
2079
+ ) ;
2080
+ err. span_label ( last_span, format ! ( "{kind} argument{s} not allowed" ) ) ;
2081
+ err. emit ( ) ;
2082
+ emitted = true ;
2083
+ }
2075
2084
2085
+ for segment in segments {
2076
2086
// Only emit the first error to avoid overloading the user with error messages.
2077
2087
if let [ binding, ..] = segment. args ( ) . bindings {
2078
- has_err = true ;
2079
2088
Self :: prohibit_assoc_ty_binding ( self . tcx ( ) , binding. span ) ;
2089
+ return true ;
2080
2090
}
2081
2091
}
2082
- has_err
2092
+ emitted
2083
2093
}
2084
2094
2085
2095
// FIXME(eddyb, varkor) handle type paths here too, not just value ones.
@@ -2229,7 +2239,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2229
2239
// Check for desugared `impl Trait`.
2230
2240
assert ! ( ty:: is_impl_trait_defn( tcx, did) . is_none( ) ) ;
2231
2241
let item_segment = path. segments . split_last ( ) . unwrap ( ) ;
2232
- self . prohibit_generics ( item_segment. 1 ) ;
2242
+ self . prohibit_generics ( item_segment. 1 . iter ( ) ) ;
2233
2243
let substs = self . ast_path_substs_for_ty ( span, did, item_segment. 0 ) ;
2234
2244
self . normalize_ty ( span, tcx. mk_opaque ( did, substs) )
2235
2245
}
@@ -2242,7 +2252,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2242
2252
did,
2243
2253
) => {
2244
2254
assert_eq ! ( opt_self_ty, None ) ;
2245
- self . prohibit_generics ( path. segments . split_last ( ) . unwrap ( ) . 1 ) ;
2255
+ self . prohibit_generics ( path. segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ) ;
2246
2256
self . ast_path_to_ty ( span, did, path. segments . last ( ) . unwrap ( ) )
2247
2257
}
2248
2258
Res :: Def ( kind @ DefKind :: Variant , def_id) if permit_variants => {
@@ -2265,7 +2275,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2265
2275
}
2266
2276
Res :: Def ( DefKind :: TyParam , def_id) => {
2267
2277
assert_eq ! ( opt_self_ty, None ) ;
2268
- self . prohibit_generics ( path. segments ) ;
2278
+ self . prohibit_generics ( path. segments . iter ( ) ) ;
2269
2279
2270
2280
let def_id = def_id. expect_local ( ) ;
2271
2281
let item_def_id = tcx. hir ( ) . ty_param_owner ( def_id) ;
@@ -2276,13 +2286,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2276
2286
Res :: SelfTy { trait_ : Some ( _) , alias_to : None } => {
2277
2287
// `Self` in trait or type alias.
2278
2288
assert_eq ! ( opt_self_ty, None ) ;
2279
- self . prohibit_generics ( path. segments ) ;
2289
+ self . prohibit_generics ( path. segments . iter ( ) ) ;
2280
2290
tcx. types . self_param
2281
2291
}
2282
2292
Res :: SelfTy { trait_ : _, alias_to : Some ( ( def_id, forbid_generic) ) } => {
2283
2293
// `Self` in impl (we know the concrete type).
2284
2294
assert_eq ! ( opt_self_ty, None ) ;
2285
- self . prohibit_generics ( path. segments ) ;
2295
+ self . prohibit_generics ( path. segments . iter ( ) ) ;
2286
2296
// Try to evaluate any array length constants.
2287
2297
let ty = tcx. at ( span) . type_of ( def_id) ;
2288
2298
// HACK(min_const_generics): Forbid generic `Self` types
@@ -2324,7 +2334,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2324
2334
}
2325
2335
Res :: Def ( DefKind :: AssocTy , def_id) => {
2326
2336
debug_assert ! ( path. segments. len( ) >= 2 ) ;
2327
- self . prohibit_generics ( & path. segments [ ..path. segments . len ( ) - 2 ] ) ;
2337
+ self . prohibit_generics ( path. segments [ ..path. segments . len ( ) - 2 ] . iter ( ) ) ;
2328
2338
self . qpath_to_ty (
2329
2339
span,
2330
2340
opt_self_ty,
@@ -2335,7 +2345,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2335
2345
}
2336
2346
Res :: PrimTy ( prim_ty) => {
2337
2347
assert_eq ! ( opt_self_ty, None ) ;
2338
- self . prohibit_generics ( path. segments ) ;
2348
+ self . prohibit_generics ( path. segments . iter ( ) ) ;
2339
2349
match prim_ty {
2340
2350
hir:: PrimTy :: Bool => tcx. types . bool ,
2341
2351
hir:: PrimTy :: Char => tcx. types . char ,
0 commit comments