@@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
814
814
debug ! ( "(resolving function) entering function" ) ;
815
815
let ( rib_kind, asyncness) = match function_kind {
816
816
FnKind :: ItemFn ( _, ref header, ..) =>
817
- ( ItemRibKind , header. asyncness . node ) ,
817
+ ( FnItemRibKind , header. asyncness . node ) ,
818
818
FnKind :: Method ( _, ref sig, _, _) =>
819
819
( TraitOrImplItemRibKind , sig. header . asyncness . node ) ,
820
820
FnKind :: Closure ( _) =>
@@ -950,6 +950,10 @@ enum RibKind<'a> {
950
950
/// upvars).
951
951
TraitOrImplItemRibKind ,
952
952
953
+ /// We passed through a function definition. Disallow upvars.
954
+ /// Permit only those const parameters specified in the function's generics.
955
+ FnItemRibKind ,
956
+
953
957
/// We passed through an item scope. Disallow upvars.
954
958
ItemRibKind ,
955
959
@@ -3863,7 +3867,7 @@ impl<'a> Resolver<'a> {
3863
3867
seen. insert ( node_id, depth) ;
3864
3868
}
3865
3869
}
3866
- ItemRibKind | TraitOrImplItemRibKind => {
3870
+ ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
3867
3871
// This was an attempt to access an upvar inside a
3868
3872
// named function item. This is not allowed, so we
3869
3873
// report an error.
@@ -3897,7 +3901,7 @@ impl<'a> Resolver<'a> {
3897
3901
ConstantItemRibKind => {
3898
3902
// Nothing to do. Continue.
3899
3903
}
3900
- ItemRibKind => {
3904
+ ItemRibKind | FnItemRibKind => {
3901
3905
// This was an attempt to use a type parameter outside its scope.
3902
3906
if record_used {
3903
3907
resolve_error (
@@ -3912,21 +3916,27 @@ impl<'a> Resolver<'a> {
3912
3916
}
3913
3917
}
3914
3918
Def :: ConstParam ( ..) => {
3915
- // A const param is always declared in a signature, which is always followed by
3916
- // some kind of function rib kind (specifically, ItemRibKind in the case of a
3917
- // normal function), so we can skip the first rib as it will be guaranteed to
3918
- // (spuriously) conflict with the const param.
3919
- for rib in & ribs[ 1 ..] {
3920
- if let ItemRibKind = rib. kind {
3921
- // This was an attempt to use a const parameter outside its scope.
3922
- if record_used {
3923
- resolve_error (
3924
- self ,
3925
- span,
3926
- ResolutionError :: GenericParamsFromOuterFunction ( def) ,
3927
- ) ;
3919
+ let mut ribs = ribs. iter ( ) . peekable ( ) ;
3920
+ if let Some ( Rib { kind : FnItemRibKind , .. } ) = ribs. peek ( ) {
3921
+ // When declaring const parameters inside function signatures, the first rib
3922
+ // is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
3923
+ // (spuriously) conflicting with the const param.
3924
+ ribs. next ( ) ;
3925
+ }
3926
+ for rib in ribs {
3927
+ match rib. kind {
3928
+ ItemRibKind | FnItemRibKind => {
3929
+ // This was an attempt to use a const parameter outside its scope.
3930
+ if record_used {
3931
+ resolve_error (
3932
+ self ,
3933
+ span,
3934
+ ResolutionError :: GenericParamsFromOuterFunction ( def) ,
3935
+ ) ;
3936
+ }
3937
+ return Def :: Err ;
3928
3938
}
3929
- return Def :: Err ;
3939
+ _ => { }
3930
3940
}
3931
3941
}
3932
3942
}
0 commit comments