@@ -51,6 +51,7 @@ use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamKind, Generi
51
51
use syntax:: ast:: { Item , ItemKind , ImplItem , ImplItemKind } ;
52
52
use syntax:: ast:: { Label , Local , Mutability , Pat , PatKind , Path } ;
53
53
use syntax:: ast:: { QSelf , TraitItemKind , TraitRef , Ty , TyKind } ;
54
+ use syntax:: ast:: ParamKindOrd ;
54
55
use syntax:: ptr:: P ;
55
56
use syntax:: { span_err, struct_span_err, unwrap_or, walk_list} ;
56
57
@@ -142,10 +143,11 @@ impl Ord for BindingError {
142
143
}
143
144
144
145
enum ResolutionError < ' a > {
145
- /// error E0401: can't use type parameters from outer function
146
- TypeParametersFromOuterFunction ( Def ) ,
147
- /// error E0403: the name is already used for a type parameter in this type parameter list
148
- NameAlreadyUsedInTypeParameterList ( Name , & ' a Span ) ,
146
+ /// error E0401: can't use type or const parameters from outer function
147
+ ParametersFromOuterFunction ( Def , ParamKindOrd ) ,
148
+ /// error E0403: the name is already used for a type/const parameter in this list of
149
+ /// generic parameters
150
+ NameAlreadyUsedInParameterList ( Name , & ' a Span ) ,
149
151
/// error E0407: method is not a member of trait
150
152
MethodNotMemberOfTrait ( Name , & ' a str ) ,
151
153
/// error E0437: type is not a member of trait
@@ -177,7 +179,9 @@ enum ResolutionError<'a> {
177
179
/// error E0530: X bindings cannot shadow Ys
178
180
BindingShadowsSomethingUnacceptable ( & ' a str , Name , & ' a NameBinding < ' a > ) ,
179
181
/// error E0128: type parameters with a default cannot use forward declared identifiers
180
- ForwardDeclaredTyParam ,
182
+ ForwardDeclaredTyParam , // FIXME(const_generics:defaults)
183
+ /// error E0670: const parameter cannot depend on type parameter
184
+ ConstParamDependentOnTypeParam ,
181
185
}
182
186
183
187
/// Combines an error with provided span and emits it
@@ -195,12 +199,14 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
195
199
resolution_error : ResolutionError < ' a > )
196
200
-> DiagnosticBuilder < ' sess > {
197
201
match resolution_error {
198
- ResolutionError :: TypeParametersFromOuterFunction ( outer_def) => {
202
+ ResolutionError :: ParametersFromOuterFunction ( outer_def, kind ) => {
199
203
let mut err = struct_span_err ! ( resolver. session,
200
- span,
201
- E0401 ,
202
- "can't use type parameters from outer function" ) ;
203
- err. span_label ( span, "use of type variable from outer function" ) ;
204
+ span,
205
+ E0401 ,
206
+ "can't use {} parameters from outer function" ,
207
+ kind,
208
+ ) ;
209
+ err. span_label ( span, format ! ( "use of {} variable from outer function" , kind) ) ;
204
210
205
211
let cm = resolver. session . source_map ( ) ;
206
212
match outer_def {
@@ -224,20 +230,25 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
224
230
}
225
231
return err;
226
232
} ,
227
- Def :: TyParam ( typaram_defid ) => {
228
- if let Some ( typaram_span ) = resolver. definitions . opt_span ( typaram_defid ) {
229
- err. span_label ( typaram_span , "type variable from outer function" ) ;
233
+ Def :: TyParam ( def_id ) => {
234
+ if let Some ( span ) = resolver. definitions . opt_span ( def_id ) {
235
+ err. span_label ( span , "type variable from outer function" ) ;
230
236
}
231
- } ,
237
+ }
238
+ Def :: ConstParam ( def_id) => {
239
+ if let Some ( span) = resolver. definitions . opt_span ( def_id) {
240
+ err. span_label ( span, "const variable from outer function" ) ;
241
+ }
242
+ }
232
243
_ => {
233
- bug ! ( "TypeParametersFromOuterFunction should only be used with Def::SelfTy or \
234
- Def::TyParam" )
244
+ bug ! ( "TypeParametersFromOuterFunction should only be used with Def::SelfTy, \
245
+ Def::TyParam or Def::ConstParam" ) ;
235
246
}
236
247
}
237
248
238
249
// Try to retrieve the span of the function signature and generate a new message with
239
- // a local type parameter
240
- let sugg_msg = "try using a local type parameter instead" ;
250
+ // a local type or const parameter.
251
+ let sugg_msg = & format ! ( "try using a local {} parameter instead" , kind ) ;
241
252
if let Some ( ( sugg_span, new_snippet) ) = cm. generate_local_type_param_snippet ( span) {
242
253
// Suggest the modification to the user
243
254
err. span_suggestion (
@@ -247,19 +258,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
247
258
Applicability :: MachineApplicable ,
248
259
) ;
249
260
} else if let Some ( sp) = cm. generate_fn_name_span ( span) {
250
- err. span_label ( sp, "try adding a local type parameter in this method instead" ) ;
261
+ err. span_label ( sp,
262
+ format ! ( "try adding a local {} parameter in this method instead" , kind) ) ;
251
263
} else {
252
- err. help ( "try using a local type parameter instead" ) ;
264
+ err. help ( & format ! ( "try using a local {} parameter instead" , kind ) ) ;
253
265
}
254
266
255
267
err
256
268
}
257
- ResolutionError :: NameAlreadyUsedInTypeParameterList ( name, first_use_span) => {
269
+ ResolutionError :: NameAlreadyUsedInParameterList ( name, first_use_span) => {
258
270
let mut err = struct_span_err ! ( resolver. session,
259
271
span,
260
272
E0403 ,
261
- "the name `{}` is already used for a type parameter \
262
- in this type parameter list ",
273
+ "the name `{}` is already used for a generic \
274
+ parameter in this list of generic parameters ",
263
275
name) ;
264
276
err. span_label ( span, "already used" ) ;
265
277
err. span_label ( first_use_span. clone ( ) , format ! ( "first use of `{}`" , name) ) ;
@@ -416,6 +428,12 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
416
428
span, "defaulted type parameters cannot be forward declared" . to_string ( ) ) ;
417
429
err
418
430
}
431
+ ResolutionError :: ConstParamDependentOnTypeParam => {
432
+ let mut err = struct_span_err ! ( resolver. session, span, E0670 ,
433
+ "const parameters cannot depend on type parameters" ) ;
434
+ err. span_label ( span, format ! ( "const parameter depends on type parameter" ) ) ;
435
+ err
436
+ }
419
437
}
420
438
}
421
439
@@ -546,7 +564,7 @@ impl<'a> PathSource<'a> {
546
564
Def :: Struct ( ..) | Def :: Union ( ..) | Def :: Enum ( ..) |
547
565
Def :: Trait ( ..) | Def :: TraitAlias ( ..) | Def :: TyAlias ( ..) |
548
566
Def :: AssociatedTy ( ..) | Def :: PrimTy ( ..) | Def :: TyParam ( ..) |
549
- Def :: SelfTy ( ..) | Def :: Existential ( ..) |
567
+ Def :: SelfTy ( ..) | Def :: Existential ( ..) | Def :: ConstParam ( .. ) |
550
568
Def :: ForeignTy ( ..) => true ,
551
569
_ => false ,
552
570
} ,
@@ -564,7 +582,7 @@ impl<'a> PathSource<'a> {
564
582
Def :: VariantCtor ( _, CtorKind :: Const ) | Def :: VariantCtor ( _, CtorKind :: Fn ) |
565
583
Def :: Const ( ..) | Def :: Static ( ..) | Def :: Local ( ..) | Def :: Upvar ( ..) |
566
584
Def :: Fn ( ..) | Def :: Method ( ..) | Def :: AssociatedConst ( ..) |
567
- Def :: SelfCtor ( ..) => true ,
585
+ Def :: SelfCtor ( ..) | Def :: ConstParam ( .. ) => true ,
568
586
_ => false ,
569
587
} ,
570
588
PathSource :: Pat => match def {
@@ -855,6 +873,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
855
873
self . label_ribs . pop ( ) ;
856
874
self . ribs [ ValueNS ] . pop ( ) ;
857
875
}
876
+
858
877
fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
859
878
// For type parameter defaults, we have to ban access
860
879
// to following type parameters, as the Substs can only
@@ -865,6 +884,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
865
884
let mut found_default = false ;
866
885
default_ban_rib. bindings . extend ( generics. params . iter ( )
867
886
. filter_map ( |param| match param. kind {
887
+ GenericParamKind :: Const { .. } |
868
888
GenericParamKind :: Lifetime { .. } => None ,
869
889
GenericParamKind :: Type { ref default, .. } => {
870
890
found_default |= default. is_some ( ) ;
@@ -876,6 +896,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
876
896
}
877
897
} ) ) ;
878
898
899
+ // We also ban access to type parameters for use as the types of const parameters.
900
+ let mut const_ty_param_ban_rib = Rib :: new ( TyParamAsConstParamTy ) ;
901
+ const_ty_param_ban_rib. bindings . extend ( generics. params . iter ( )
902
+ . filter ( |param| if let GenericParamKind :: Type { .. } = param. kind {
903
+ true
904
+ } else {
905
+ false
906
+ } )
907
+ . map ( |param| ( Ident :: with_empty_ctxt ( param. ident . name ) , Def :: Err ) ) ) ;
908
+
879
909
for param in & generics. params {
880
910
match param. kind {
881
911
GenericParamKind :: Lifetime { .. } => self . visit_generic_param ( param) ,
@@ -893,6 +923,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
893
923
// Allow all following defaults to refer to this type parameter.
894
924
default_ban_rib. bindings . remove ( & Ident :: with_empty_ctxt ( param. ident . name ) ) ;
895
925
}
926
+ GenericParamKind :: Const { ref ty } => {
927
+ self . ribs [ TypeNS ] . push ( const_ty_param_ban_rib) ;
928
+
929
+ for bound in & param. bounds {
930
+ self . visit_param_bound ( bound) ;
931
+ }
932
+
933
+ self . visit_ty ( ty) ;
934
+
935
+ const_ty_param_ban_rib = self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
936
+ }
896
937
}
897
938
}
898
939
for p in & generics. where_clause . predicates {
@@ -944,6 +985,9 @@ enum RibKind<'a> {
944
985
/// from the default of a type parameter because they're not declared
945
986
/// before said type parameter. Also see the `visit_generics` override.
946
987
ForwardTyParamBanRibKind ,
988
+
989
+ /// We forbid the use of type parameters as the types of const parameters.
990
+ TyParamAsConstParamTy ,
947
991
}
948
992
949
993
/// One local scope.
@@ -2535,7 +2579,7 @@ impl<'a> Resolver<'a> {
2535
2579
2536
2580
if seen_bindings. contains_key ( & ident) {
2537
2581
let span = seen_bindings. get ( & ident) . unwrap ( ) ;
2538
- let err = ResolutionError :: NameAlreadyUsedInTypeParameterList (
2582
+ let err = ResolutionError :: NameAlreadyUsedInParameterList (
2539
2583
ident. name ,
2540
2584
span,
2541
2585
) ;
@@ -2548,6 +2592,24 @@ impl<'a> Resolver<'a> {
2548
2592
function_type_rib. bindings . insert ( ident, def) ;
2549
2593
self . record_def ( param. id , PathResolution :: new ( def) ) ;
2550
2594
}
2595
+ GenericParamKind :: Const { .. } => {
2596
+ let ident = param. ident . modern ( ) ;
2597
+ debug ! ( "with_type_parameter_rib: {}" , param. id) ;
2598
+
2599
+ if seen_bindings. contains_key ( & ident) {
2600
+ let span = seen_bindings. get ( & ident) . unwrap ( ) ;
2601
+ let err = ResolutionError :: NameAlreadyUsedInParameterList (
2602
+ ident. name ,
2603
+ span,
2604
+ ) ;
2605
+ resolve_error ( self , param. ident . span , err) ;
2606
+ }
2607
+ seen_bindings. entry ( ident) . or_insert ( param. ident . span ) ;
2608
+
2609
+ let def = Def :: ConstParam ( self . definitions . local_def_id ( param. id ) ) ;
2610
+ function_type_rib. bindings . insert ( ident, def) ;
2611
+ self . record_def ( param. id , PathResolution :: new ( def) ) ;
2612
+ }
2551
2613
}
2552
2614
}
2553
2615
self . ribs [ TypeNS ] . push ( function_type_rib) ;
@@ -4106,6 +4168,15 @@ impl<'a> Resolver<'a> {
4106
4168
return Def :: Err ;
4107
4169
}
4108
4170
4171
+ // An invalid use of a type parameter as the type of a const parameter.
4172
+ if let TyParamAsConstParamTy = self . ribs [ ns] [ rib_index] . kind {
4173
+ if record_used {
4174
+ resolve_error ( self , span, ResolutionError :: ConstParamDependentOnTypeParam ) ;
4175
+ }
4176
+ assert_eq ! ( def, Def :: Err ) ;
4177
+ return Def :: Err ;
4178
+ }
4179
+
4109
4180
match def {
4110
4181
Def :: Upvar ( ..) => {
4111
4182
span_bug ! ( span, "unexpected {:?} in bindings" , def)
@@ -4114,7 +4185,7 @@ impl<'a> Resolver<'a> {
4114
4185
for rib in ribs {
4115
4186
match rib. kind {
4116
4187
NormalRibKind | ModuleRibKind ( ..) | MacroDefinition ( ..) |
4117
- ForwardTyParamBanRibKind => {
4188
+ ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
4118
4189
// Nothing to do. Continue.
4119
4190
}
4120
4191
ClosureRibKind ( function_id) => {
@@ -4167,21 +4238,44 @@ impl<'a> Resolver<'a> {
4167
4238
match rib. kind {
4168
4239
NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind ( ..) |
4169
4240
ModuleRibKind ( ..) | MacroDefinition ( ..) | ForwardTyParamBanRibKind |
4170
- ConstantItemRibKind => {
4241
+ ConstantItemRibKind | TyParamAsConstParamTy => {
4171
4242
// Nothing to do. Continue.
4172
4243
}
4173
4244
ItemRibKind => {
4174
- // This was an attempt to use a type parameter outside
4175
- // its scope.
4245
+ // This was an attempt to use a type parameter outside its scope.
4176
4246
if record_used {
4177
- resolve_error ( self , span,
4178
- ResolutionError :: TypeParametersFromOuterFunction ( def) ) ;
4247
+ resolve_error (
4248
+ self ,
4249
+ span,
4250
+ ResolutionError :: ParametersFromOuterFunction (
4251
+ def,
4252
+ ParamKindOrd :: Type ,
4253
+ ) ,
4254
+ ) ;
4179
4255
}
4180
4256
return Def :: Err ;
4181
4257
}
4182
4258
}
4183
4259
}
4184
4260
}
4261
+ Def :: ConstParam ( ..) => {
4262
+ for rib in ribs {
4263
+ if let ItemRibKind = rib. kind {
4264
+ // This was an attempt to use a const parameter outside its scope.
4265
+ if record_used {
4266
+ resolve_error (
4267
+ self ,
4268
+ span,
4269
+ ResolutionError :: ParametersFromOuterFunction (
4270
+ def,
4271
+ ParamKindOrd :: Const ,
4272
+ ) ,
4273
+ ) ;
4274
+ }
4275
+ return Def :: Err ;
4276
+ }
4277
+ }
4278
+ }
4185
4279
_ => { }
4186
4280
}
4187
4281
def
0 commit comments