@@ -133,8 +133,8 @@ impl Ord for BindingError {
133
133
}
134
134
135
135
enum ResolutionError < ' a > {
136
- /// error E0401: can't use type parameters from outer function
137
- TypeParametersFromOuterFunction ( Def ) ,
136
+ /// error E0401: can't use type or const parameters from outer function
137
+ ParametersFromOuterFunction ( Def ) ,
138
138
/// error E0403: the name is already used for a type or const parameter in this type parameter list
139
139
NameAlreadyUsedInParameterList ( Name , & ' a Span ) ,
140
140
/// error E0407: method is not a member of trait
@@ -170,7 +170,9 @@ enum ResolutionError<'a> {
170
170
/// error E0530: X bindings cannot shadow Ys
171
171
BindingShadowsSomethingUnacceptable ( & ' a str , Name , & ' a NameBinding < ' a > ) ,
172
172
/// error E0128: type parameters with a default cannot use forward declared identifiers
173
- ForwardDeclaredTyParam ,
173
+ ForwardDeclaredTyParam , // FIXME(const_generics:defaults)
174
+ /// error E0668: const parameter cannot depend on type parameter
175
+ ConstParamDependentOnTypeParam ,
174
176
}
175
177
176
178
/// Combines an error with provided span and emits it
@@ -188,12 +190,12 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
188
190
resolution_error : ResolutionError < ' a > )
189
191
-> DiagnosticBuilder < ' sess > {
190
192
match resolution_error {
191
- ResolutionError :: TypeParametersFromOuterFunction ( outer_def) => {
193
+ ResolutionError :: ParametersFromOuterFunction ( outer_def) => {
192
194
let mut err = struct_span_err ! ( resolver. session,
193
- span,
194
- E0401 ,
195
- "can't use type parameters from outer function" ) ;
196
- err. span_label ( span, "use of type variable from outer function" ) ;
195
+ span,
196
+ E0401 ,
197
+ "can't use type or const parameters from outer function" ) ;
198
+ err. span_label ( span, "use of type or const variable from outer function" ) ;
197
199
198
200
let cm = resolver. session . source_map ( ) ;
199
201
match outer_def {
@@ -206,7 +208,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
206
208
}
207
209
Def :: TyParam ( typaram_defid) => {
208
210
if let Some ( typaram_span) = resolver. definitions . opt_span ( typaram_defid) {
209
- err. span_label ( typaram_span, "type variable from outer function" ) ;
211
+ err. span_label ( typaram_span, "type or const variable from outer function" ) ;
210
212
}
211
213
}
212
214
_ => {
@@ -217,16 +219,17 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
217
219
218
220
// Try to retrieve the span of the function signature and generate a new message with
219
221
// a local type parameter
220
- let sugg_msg = "try using a local type parameter instead" ;
222
+ let sugg_msg = "try using a local type or const parameter instead" ;
221
223
if let Some ( ( sugg_span, new_snippet) ) = cm. generate_local_type_param_snippet ( span) {
222
224
// Suggest the modification to the user
223
225
err. span_suggestion ( sugg_span,
224
226
sugg_msg,
225
227
new_snippet) ;
226
228
} else if let Some ( sp) = cm. generate_fn_name_span ( span) {
227
- err. span_label ( sp, "try adding a local type parameter in this method instead" ) ;
229
+ err. span_label ( sp,
230
+ "try adding a local type or const parameter in this method instead" ) ;
228
231
} else {
229
- err. help ( "try using a local type parameter instead" ) ;
232
+ err. help ( "try using a local type or const parameter instead" ) ;
230
233
}
231
234
232
235
err
@@ -405,6 +408,12 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
405
408
span, "defaulted type parameters cannot be forward declared" . to_string ( ) ) ;
406
409
err
407
410
}
411
+ ResolutionError :: ConstParamDependentOnTypeParam => {
412
+ let mut err = struct_span_err ! ( resolver. session, span, E0668 ,
413
+ "const parameters cannot depend on type parameters" ) ;
414
+ err. span_label ( span, format ! ( "const parameter depends on type parameter" ) ) ;
415
+ err
416
+ }
408
417
}
409
418
}
410
419
@@ -833,6 +842,16 @@ impl<'a, 'tcx, 'cl> Visitor<'tcx> for Resolver<'a, 'cl> {
833
842
}
834
843
} ) ) ;
835
844
845
+ // We also ban access to type parameters for use as the types of const parameters.
846
+ let mut const_ty_param_ban_rib = Rib :: new ( TyParamAsConstParamTy ) ;
847
+ const_ty_param_ban_rib. bindings . extend ( generics. params . iter ( )
848
+ . filter ( |param| if let GenericParamKind :: Type { .. } = param. kind {
849
+ true
850
+ } else {
851
+ false
852
+ } )
853
+ . map ( |param| ( Ident :: with_empty_ctxt ( param. ident . name ) , Def :: Err ) ) ) ;
854
+
836
855
for param in & generics. params {
837
856
match param. kind {
838
857
GenericParamKind :: Lifetime { .. } => self . visit_generic_param ( param) ,
@@ -851,13 +870,15 @@ impl<'a, 'tcx, 'cl> Visitor<'tcx> for Resolver<'a, 'cl> {
851
870
default_ban_rib. bindings . remove ( & Ident :: with_empty_ctxt ( param. ident . name ) ) ;
852
871
}
853
872
GenericParamKind :: Const { ref ty } => {
873
+ self . ribs [ TypeNS ] . push ( const_ty_param_ban_rib) ;
874
+
854
875
for bound in & param. bounds {
855
876
self . visit_param_bound ( bound) ;
856
877
}
857
878
858
879
self . visit_ty ( ty) ;
859
880
860
- // TODO(const_generics): do we need to do thing banning here too?
881
+ const_ty_param_ban_rib = self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
861
882
}
862
883
}
863
884
}
@@ -910,6 +931,9 @@ enum RibKind<'a> {
910
931
/// from the default of a type parameter because they're not declared
911
932
/// before said type parameter. Also see the `visit_generics` override.
912
933
ForwardTyParamBanRibKind ,
934
+
935
+ /// We forbid the use of type parameters as the types of const parameters.
936
+ TyParamAsConstParamTy ,
913
937
}
914
938
915
939
/// One local scope.
@@ -3739,6 +3763,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3739
3763
return Def :: Err ;
3740
3764
}
3741
3765
3766
+ // An invalid use of a type parameter as the type of a const parameter.
3767
+ if let TyParamAsConstParamTy = self . ribs [ ns] [ rib_index] . kind {
3768
+ if record_used {
3769
+ resolve_error ( self , span, ResolutionError :: ConstParamDependentOnTypeParam ) ;
3770
+ }
3771
+ assert_eq ! ( def, Def :: Err ) ;
3772
+ return Def :: Err ;
3773
+ }
3774
+
3742
3775
match def {
3743
3776
Def :: Upvar ( ..) => {
3744
3777
span_bug ! ( span, "unexpected {:?} in bindings" , def)
@@ -3747,7 +3780,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3747
3780
for rib in ribs {
3748
3781
match rib. kind {
3749
3782
NormalRibKind | ModuleRibKind ( ..) | MacroDefinition ( ..) |
3750
- ForwardTyParamBanRibKind => {
3783
+ ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
3751
3784
// Nothing to do. Continue.
3752
3785
}
3753
3786
ClosureRibKind ( function_id) => {
@@ -3800,15 +3833,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3800
3833
match rib. kind {
3801
3834
NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind ( ..) |
3802
3835
ModuleRibKind ( ..) | MacroDefinition ( ..) | ForwardTyParamBanRibKind |
3803
- ConstantItemRibKind => {
3836
+ ConstantItemRibKind | TyParamAsConstParamTy => {
3804
3837
// Nothing to do. Continue.
3805
3838
}
3806
3839
ItemRibKind => {
3807
3840
// This was an attempt to use a type parameter outside
3808
3841
// its scope.
3809
3842
if record_used {
3810
3843
resolve_error ( self , span,
3811
- ResolutionError :: TypeParametersFromOuterFunction ( def) ) ;
3844
+ ResolutionError :: ParametersFromOuterFunction ( def) ) ;
3812
3845
}
3813
3846
return Def :: Err ;
3814
3847
}
0 commit comments