@@ -185,6 +185,8 @@ enum ResolutionError<'a> {
185
185
BindingShadowsSomethingUnacceptable ( & ' a str , Name , & ' a NameBinding < ' a > ) ,
186
186
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
187
187
ForwardDeclaredTyParam , // FIXME(const_generics:defaults)
188
+ /// Error E0671: const parameter cannot depend on type parameter.
189
+ ConstParamDependentOnTypeParam ,
188
190
}
189
191
190
192
/// Combines an error with provided span and emits it.
@@ -440,6 +442,16 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
440
442
span, "defaulted type parameters cannot be forward declared" . to_string ( ) ) ;
441
443
err
442
444
}
445
+ ResolutionError :: ConstParamDependentOnTypeParam => {
446
+ let mut err = struct_span_err ! (
447
+ resolver. session,
448
+ span,
449
+ E0671 ,
450
+ "const parameters cannot depend on type parameters"
451
+ ) ;
452
+ err. span_label ( span, format ! ( "const parameter depends on type parameter" ) ) ;
453
+ err
454
+ }
443
455
}
444
456
}
445
457
@@ -915,6 +927,18 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
915
927
}
916
928
} ) ) ;
917
929
930
+ // We also ban access to type parameters for use as the types of const parameters.
931
+ let mut const_ty_param_ban_rib = Rib :: new ( TyParamAsConstParamTy ) ;
932
+ const_ty_param_ban_rib. bindings . extend ( generics. params . iter ( )
933
+ . filter ( |param| {
934
+ if let GenericParamKind :: Type { .. } = param. kind {
935
+ true
936
+ } else {
937
+ false
938
+ }
939
+ } )
940
+ . map ( |param| ( Ident :: with_empty_ctxt ( param. ident . name ) , Def :: Err ) ) ) ;
941
+
918
942
for param in & generics. params {
919
943
match param. kind {
920
944
GenericParamKind :: Lifetime { .. } => self . visit_generic_param ( param) ,
@@ -933,11 +957,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
933
957
default_ban_rib. bindings . remove ( & Ident :: with_empty_ctxt ( param. ident . name ) ) ;
934
958
}
935
959
GenericParamKind :: Const { ref ty } => {
960
+ self . ribs [ TypeNS ] . push ( const_ty_param_ban_rib) ;
961
+
936
962
for bound in & param. bounds {
937
963
self . visit_param_bound ( bound) ;
938
964
}
939
965
940
966
self . visit_ty ( ty) ;
967
+
968
+ const_ty_param_ban_rib = self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
941
969
}
942
970
}
943
971
}
@@ -994,6 +1022,9 @@ enum RibKind<'a> {
994
1022
/// from the default of a type parameter because they're not declared
995
1023
/// before said type parameter. Also see the `visit_generics` override.
996
1024
ForwardTyParamBanRibKind ,
1025
+
1026
+ /// We forbid the use of type parameters as the types of const parameters.
1027
+ TyParamAsConstParamTy ,
997
1028
}
998
1029
999
1030
/// A single local scope.
@@ -3944,6 +3975,15 @@ impl<'a> Resolver<'a> {
3944
3975
return Def :: Err ;
3945
3976
}
3946
3977
3978
+ // An invalid use of a type parameter as the type of a const parameter.
3979
+ if let TyParamAsConstParamTy = self . ribs [ ns] [ rib_index] . kind {
3980
+ if record_used {
3981
+ resolve_error ( self , span, ResolutionError :: ConstParamDependentOnTypeParam ) ;
3982
+ }
3983
+ assert_eq ! ( def, Def :: Err ) ;
3984
+ return Def :: Err ;
3985
+ }
3986
+
3947
3987
match def {
3948
3988
Def :: Upvar ( ..) => {
3949
3989
span_bug ! ( span, "unexpected {:?} in bindings" , def)
@@ -3955,7 +3995,7 @@ impl<'a> Resolver<'a> {
3955
3995
for rib in ribs {
3956
3996
match rib. kind {
3957
3997
NormalRibKind | ModuleRibKind ( ..) | MacroDefinition ( ..) |
3958
- ForwardTyParamBanRibKind => {
3998
+ ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
3959
3999
// Nothing to do. Continue.
3960
4000
}
3961
4001
ClosureRibKind ( function_id) => {
@@ -4013,7 +4053,7 @@ impl<'a> Resolver<'a> {
4013
4053
match rib. kind {
4014
4054
NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind ( ..) |
4015
4055
ModuleRibKind ( ..) | MacroDefinition ( ..) | ForwardTyParamBanRibKind |
4016
- ConstantItemRibKind => {
4056
+ ConstantItemRibKind | TyParamAsConstParamTy => {
4017
4057
// Nothing to do. Continue.
4018
4058
}
4019
4059
ItemRibKind | FnItemRibKind => {
0 commit comments