@@ -51,6 +51,7 @@ use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamKind, Generi
5151use syntax:: ast:: { Item , ItemKind , ImplItem , ImplItemKind } ;
5252use syntax:: ast:: { Label , Local , Mutability , Pat , PatKind , Path } ;
5353use syntax:: ast:: { QSelf , TraitItemKind , TraitRef , Ty , TyKind } ;
54+ use syntax:: ast:: ParamKindOrd ;
5455use syntax:: ptr:: P ;
5556use syntax:: { span_err, struct_span_err, unwrap_or, walk_list} ;
5657
@@ -142,10 +143,11 @@ impl Ord for BindingError {
142143}
143144
144145enum 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 ) ,
149151 /// error E0407: method is not a member of trait
150152 MethodNotMemberOfTrait ( Name , & ' a str ) ,
151153 /// error E0437: type is not a member of trait
@@ -177,7 +179,9 @@ enum ResolutionError<'a> {
177179 /// error E0530: X bindings cannot shadow Ys
178180 BindingShadowsSomethingUnacceptable ( & ' a str , Name , & ' a NameBinding < ' a > ) ,
179181 /// 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 ,
181185}
182186
183187/// Combines an error with provided span and emits it
@@ -195,12 +199,14 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
195199 resolution_error : ResolutionError < ' a > )
196200 -> DiagnosticBuilder < ' sess > {
197201 match resolution_error {
198- ResolutionError :: TypeParametersFromOuterFunction ( outer_def) => {
202+ ResolutionError :: ParametersFromOuterFunction ( outer_def, kind ) => {
199203 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) ) ;
204210
205211 let cm = resolver. session . source_map ( ) ;
206212 match outer_def {
@@ -224,20 +230,25 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
224230 }
225231 return err;
226232 } ,
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" ) ;
230236 }
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+ }
232243 _ => {
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" ) ;
235246 }
236247 }
237248
238249 // 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 ) ;
241252 if let Some ( ( sugg_span, new_snippet) ) = cm. generate_local_type_param_snippet ( span) {
242253 // Suggest the modification to the user
243254 err. span_suggestion (
@@ -247,19 +258,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
247258 Applicability :: MachineApplicable ,
248259 ) ;
249260 } 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) ) ;
251263 } else {
252- err. help ( "try using a local type parameter instead" ) ;
264+ err. help ( & format ! ( "try using a local {} parameter instead" , kind ) ) ;
253265 }
254266
255267 err
256268 }
257- ResolutionError :: NameAlreadyUsedInTypeParameterList ( name, first_use_span) => {
269+ ResolutionError :: NameAlreadyUsedInParameterList ( name, first_use_span) => {
258270 let mut err = struct_span_err ! ( resolver. session,
259271 span,
260272 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 ",
263275 name) ;
264276 err. span_label ( span, "already used" ) ;
265277 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<'_>,
416428 span, "defaulted type parameters cannot be forward declared" . to_string ( ) ) ;
417429 err
418430 }
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+ }
419437 }
420438}
421439
@@ -546,7 +564,7 @@ impl<'a> PathSource<'a> {
546564 Def :: Struct ( ..) | Def :: Union ( ..) | Def :: Enum ( ..) |
547565 Def :: Trait ( ..) | Def :: TraitAlias ( ..) | Def :: TyAlias ( ..) |
548566 Def :: AssociatedTy ( ..) | Def :: PrimTy ( ..) | Def :: TyParam ( ..) |
549- Def :: SelfTy ( ..) | Def :: Existential ( ..) |
567+ Def :: SelfTy ( ..) | Def :: Existential ( ..) | Def :: ConstParam ( .. ) |
550568 Def :: ForeignTy ( ..) => true ,
551569 _ => false ,
552570 } ,
@@ -564,7 +582,7 @@ impl<'a> PathSource<'a> {
564582 Def :: VariantCtor ( _, CtorKind :: Const ) | Def :: VariantCtor ( _, CtorKind :: Fn ) |
565583 Def :: Const ( ..) | Def :: Static ( ..) | Def :: Local ( ..) | Def :: Upvar ( ..) |
566584 Def :: Fn ( ..) | Def :: Method ( ..) | Def :: AssociatedConst ( ..) |
567- Def :: SelfCtor ( ..) => true ,
585+ Def :: SelfCtor ( ..) | Def :: ConstParam ( .. ) => true ,
568586 _ => false ,
569587 } ,
570588 PathSource :: Pat => match def {
@@ -855,6 +873,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
855873 self . label_ribs . pop ( ) ;
856874 self . ribs [ ValueNS ] . pop ( ) ;
857875 }
876+
858877 fn visit_generics ( & mut self , generics : & ' tcx Generics ) {
859878 // For type parameter defaults, we have to ban access
860879 // to following type parameters, as the Substs can only
@@ -865,6 +884,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
865884 let mut found_default = false ;
866885 default_ban_rib. bindings . extend ( generics. params . iter ( )
867886 . filter_map ( |param| match param. kind {
887+ GenericParamKind :: Const { .. } |
868888 GenericParamKind :: Lifetime { .. } => None ,
869889 GenericParamKind :: Type { ref default, .. } => {
870890 found_default |= default. is_some ( ) ;
@@ -876,6 +896,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
876896 }
877897 } ) ) ;
878898
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+
879909 for param in & generics. params {
880910 match param. kind {
881911 GenericParamKind :: Lifetime { .. } => self . visit_generic_param ( param) ,
@@ -893,6 +923,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
893923 // Allow all following defaults to refer to this type parameter.
894924 default_ban_rib. bindings . remove ( & Ident :: with_empty_ctxt ( param. ident . name ) ) ;
895925 }
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+ }
896937 }
897938 }
898939 for p in & generics. where_clause . predicates {
@@ -944,6 +985,9 @@ enum RibKind<'a> {
944985 /// from the default of a type parameter because they're not declared
945986 /// before said type parameter. Also see the `visit_generics` override.
946987 ForwardTyParamBanRibKind ,
988+
989+ /// We forbid the use of type parameters as the types of const parameters.
990+ TyParamAsConstParamTy ,
947991}
948992
949993/// One local scope.
@@ -2535,7 +2579,7 @@ impl<'a> Resolver<'a> {
25352579
25362580 if seen_bindings. contains_key ( & ident) {
25372581 let span = seen_bindings. get ( & ident) . unwrap ( ) ;
2538- let err = ResolutionError :: NameAlreadyUsedInTypeParameterList (
2582+ let err = ResolutionError :: NameAlreadyUsedInParameterList (
25392583 ident. name ,
25402584 span,
25412585 ) ;
@@ -2548,6 +2592,24 @@ impl<'a> Resolver<'a> {
25482592 function_type_rib. bindings . insert ( ident, def) ;
25492593 self . record_def ( param. id , PathResolution :: new ( def) ) ;
25502594 }
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+ }
25512613 }
25522614 }
25532615 self . ribs [ TypeNS ] . push ( function_type_rib) ;
@@ -4106,6 +4168,15 @@ impl<'a> Resolver<'a> {
41064168 return Def :: Err ;
41074169 }
41084170
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+
41094180 match def {
41104181 Def :: Upvar ( ..) => {
41114182 span_bug ! ( span, "unexpected {:?} in bindings" , def)
@@ -4114,7 +4185,7 @@ impl<'a> Resolver<'a> {
41144185 for rib in ribs {
41154186 match rib. kind {
41164187 NormalRibKind | ModuleRibKind ( ..) | MacroDefinition ( ..) |
4117- ForwardTyParamBanRibKind => {
4188+ ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
41184189 // Nothing to do. Continue.
41194190 }
41204191 ClosureRibKind ( function_id) => {
@@ -4167,21 +4238,44 @@ impl<'a> Resolver<'a> {
41674238 match rib. kind {
41684239 NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind ( ..) |
41694240 ModuleRibKind ( ..) | MacroDefinition ( ..) | ForwardTyParamBanRibKind |
4170- ConstantItemRibKind => {
4241+ ConstantItemRibKind | TyParamAsConstParamTy => {
41714242 // Nothing to do. Continue.
41724243 }
41734244 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.
41764246 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+ ) ;
41794255 }
41804256 return Def :: Err ;
41814257 }
41824258 }
41834259 }
41844260 }
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+ }
41854279 _ => { }
41864280 }
41874281 def
0 commit comments