@@ -142,8 +142,8 @@ impl Ord for BindingError {
142
142
}
143
143
144
144
enum 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 ) ,
147
147
/// error E0403: the name is already used for a type/const parameter in this list of
148
148
/// generic parameters
149
149
NameAlreadyUsedInParameterList ( Name , & ' a Span ) ,
@@ -196,13 +196,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
196
196
resolution_error : ResolutionError < ' a > )
197
197
-> DiagnosticBuilder < ' sess > {
198
198
match resolution_error {
199
- ResolutionError :: TypeParametersFromOuterFunction ( outer_def) => {
199
+ ResolutionError :: GenericParamsFromOuterFunction ( outer_def) => {
200
200
let mut err = struct_span_err ! ( resolver. session,
201
201
span,
202
202
E0401 ,
203
- "can't use type parameters from outer function" ,
203
+ "can't use generic parameters from outer function" ,
204
204
) ;
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" ) ) ;
206
206
207
207
let cm = resolver. session . source_map ( ) ;
208
208
match outer_def {
@@ -231,15 +231,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
231
231
err. span_label ( span, "type variable from outer function" ) ;
232
232
}
233
233
}
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
+ }
234
239
_ => {
235
- bug ! ( "TypeParametersFromOuterFunction should only be used with Def::SelfTy, \
240
+ bug ! ( "GenericParamsFromOuterFunction should only be used with Def::SelfTy, \
236
241
Def::TyParam") ;
237
242
}
238
243
}
239
244
240
245
// Try to retrieve the span of the function signature and generate a new message with
241
246
// 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" ) ;
243
248
if let Some ( ( sugg_span, new_snippet) ) = cm. generate_local_type_param_snippet ( span) {
244
249
// Suggest the modification to the user
245
250
err. span_suggestion (
@@ -250,9 +255,9 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
250
255
) ;
251
256
} else if let Some ( sp) = cm. generate_fn_name_span ( span) {
252
257
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" ) ) ;
254
259
} else {
255
- err. help ( & format ! ( "try using a local type parameter instead" ) ) ;
260
+ err. help ( & format ! ( "try using a local generic parameter instead" ) ) ;
256
261
}
257
262
258
263
err
@@ -549,8 +554,7 @@ impl<'a> PathSource<'a> {
549
554
Def :: Struct ( ..) | Def :: Union ( ..) | Def :: Enum ( ..) |
550
555
Def :: Trait ( ..) | Def :: TraitAlias ( ..) | Def :: TyAlias ( ..) |
551
556
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 ,
554
558
_ => false ,
555
559
} ,
556
560
PathSource :: Trait ( AliasPossibility :: No ) => match def {
@@ -803,6 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
803
807
_: Span ,
804
808
node_id : NodeId )
805
809
{
810
+ debug ! ( "(resolving function) entering function" ) ;
806
811
let ( rib_kind, asyncness) = match function_kind {
807
812
FnKind :: ItemFn ( _, ref header, ..) =>
808
813
( ItemRibKind , header. asyncness ) ,
@@ -2053,6 +2058,7 @@ impl<'a> Resolver<'a> {
2053
2058
let record_used = record_used_id. is_some ( ) ;
2054
2059
let mut module = self . graph_root ;
2055
2060
for i in ( 0 .. self . ribs [ ns] . len ( ) ) . rev ( ) {
2061
+ debug ! ( "walk rib\n {:?}" , self . ribs[ ns] [ i] . bindings) ;
2056
2062
if let Some ( def) = self . ribs [ ns] [ i] . bindings . get ( & ident) . cloned ( ) {
2057
2063
// The ident resolves to a type parameter or local variable.
2058
2064
return Some ( LexicalScopeBinding :: Def (
@@ -4223,14 +4229,33 @@ impl<'a> Resolver<'a> {
4223
4229
resolve_error (
4224
4230
self ,
4225
4231
span,
4226
- ResolutionError :: TypeParametersFromOuterFunction ( def) ,
4232
+ ResolutionError :: GenericParamsFromOuterFunction ( def) ,
4227
4233
) ;
4228
4234
}
4229
4235
return Def :: Err ;
4230
4236
}
4231
4237
}
4232
4238
}
4233
4239
}
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
+ }
4234
4259
_ => { }
4235
4260
}
4236
4261
def
0 commit comments