@@ -142,8 +142,8 @@ impl Ord for BindingError {
142142}
143143
144144enum ResolutionError < ' a > {
145- /// error E0401: can't use type parameters from outer function
146- TypeParametersFromOuterFunction ( Def ) ,
145+ /// error E0401: can't use type or const parameters from outer function
146+ GenericParamsFromOuterFunction ( Def ) ,
147147 /// error E0403: the name is already used for a type/const parameter in this list of
148148 /// generic parameters
149149 NameAlreadyUsedInParameterList ( Name , & ' a Span ) ,
@@ -196,13 +196,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
196196 resolution_error : ResolutionError < ' a > )
197197 -> DiagnosticBuilder < ' sess > {
198198 match resolution_error {
199- ResolutionError :: TypeParametersFromOuterFunction ( outer_def) => {
199+ ResolutionError :: GenericParamsFromOuterFunction ( outer_def) => {
200200 let mut err = struct_span_err ! ( resolver. session,
201201 span,
202202 E0401 ,
203- "can't use type parameters from outer function" ,
203+ "can't use generic parameters from outer function" ,
204204 ) ;
205- err. span_label ( span, format ! ( "use of type variable from outer function" ) ) ;
205+ err. span_label ( span, format ! ( "use of generic parameter from outer function" ) ) ;
206206
207207 let cm = resolver. session . source_map ( ) ;
208208 match outer_def {
@@ -231,15 +231,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
231231 err. span_label ( span, "type variable from outer function" ) ;
232232 }
233233 }
234+ Def :: ConstParam ( def_id) => {
235+ if let Some ( span) = resolver. definitions . opt_span ( def_id) {
236+ err. span_label ( span, "const variable from outer function" ) ;
237+ }
238+ }
234239 _ => {
235- bug ! ( "TypeParametersFromOuterFunction should only be used with Def::SelfTy, \
240+ bug ! ( "GenericParamsFromOuterFunction should only be used with Def::SelfTy, \
236241 Def::TyParam") ;
237242 }
238243 }
239244
240245 // Try to retrieve the span of the function signature and generate a new message with
241246 // a local type or const parameter.
242- let sugg_msg = & format ! ( "try using a local type parameter instead" ) ;
247+ let sugg_msg = & format ! ( "try using a local generic parameter instead" ) ;
243248 if let Some ( ( sugg_span, new_snippet) ) = cm. generate_local_type_param_snippet ( span) {
244249 // Suggest the modification to the user
245250 err. span_suggestion (
@@ -250,9 +255,9 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
250255 ) ;
251256 } else if let Some ( sp) = cm. generate_fn_name_span ( span) {
252257 err. span_label ( sp,
253- format ! ( "try adding a local type parameter in this method instead" ) ) ;
258+ format ! ( "try adding a local generic parameter in this method instead" ) ) ;
254259 } else {
255- err. help ( & format ! ( "try using a local type parameter instead" ) ) ;
260+ err. help ( & format ! ( "try using a local generic parameter instead" ) ) ;
256261 }
257262
258263 err
@@ -549,8 +554,7 @@ impl<'a> PathSource<'a> {
549554 Def :: Struct ( ..) | Def :: Union ( ..) | Def :: Enum ( ..) |
550555 Def :: Trait ( ..) | Def :: TraitAlias ( ..) | Def :: TyAlias ( ..) |
551556 Def :: AssociatedTy ( ..) | Def :: PrimTy ( ..) | Def :: TyParam ( ..) |
552- Def :: SelfTy ( ..) | Def :: Existential ( ..) | Def :: ConstParam ( ..) |
553- Def :: ForeignTy ( ..) => true ,
557+ Def :: SelfTy ( ..) | Def :: Existential ( ..) | Def :: ForeignTy ( ..) => true ,
554558 _ => false ,
555559 } ,
556560 PathSource :: Trait ( AliasPossibility :: No ) => match def {
@@ -803,6 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
803807 _: Span ,
804808 node_id : NodeId )
805809 {
810+ debug ! ( "(resolving function) entering function" ) ;
806811 let ( rib_kind, asyncness) = match function_kind {
807812 FnKind :: ItemFn ( _, ref header, ..) =>
808813 ( ItemRibKind , header. asyncness ) ,
@@ -2053,6 +2058,7 @@ impl<'a> Resolver<'a> {
20532058 let record_used = record_used_id. is_some ( ) ;
20542059 let mut module = self . graph_root ;
20552060 for i in ( 0 .. self . ribs [ ns] . len ( ) ) . rev ( ) {
2061+ debug ! ( "walk rib\n {:?}" , self . ribs[ ns] [ i] . bindings) ;
20562062 if let Some ( def) = self . ribs [ ns] [ i] . bindings . get ( & ident) . cloned ( ) {
20572063 // The ident resolves to a type parameter or local variable.
20582064 return Some ( LexicalScopeBinding :: Def (
@@ -4223,14 +4229,33 @@ impl<'a> Resolver<'a> {
42234229 resolve_error (
42244230 self ,
42254231 span,
4226- ResolutionError :: TypeParametersFromOuterFunction ( def) ,
4232+ ResolutionError :: GenericParamsFromOuterFunction ( def) ,
42274233 ) ;
42284234 }
42294235 return Def :: Err ;
42304236 }
42314237 }
42324238 }
42334239 }
4240+ Def :: ConstParam ( ..) => {
4241+ // A const param is always declared in a signature, which is always followed by
4242+ // some kind of function rib kind (specifically, ItemRibKind in the case of a
4243+ // normal function), so we can skip the first rib as it will be guaranteed to
4244+ // (spuriously) conflict with the const param.
4245+ for rib in & ribs[ 1 ..] {
4246+ if let ItemRibKind = rib. kind {
4247+ // This was an attempt to use a const parameter outside its scope.
4248+ if record_used {
4249+ resolve_error (
4250+ self ,
4251+ span,
4252+ ResolutionError :: GenericParamsFromOuterFunction ( def) ,
4253+ ) ;
4254+ }
4255+ return Def :: Err ;
4256+ }
4257+ }
4258+ }
42344259 _ => { }
42354260 }
42364261 def
0 commit comments