@@ -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 that are 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,12 +3916,15 @@ 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 {
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
+ if let ItemRibKind | FnItemRibKind = rib. kind {
3921
3928
// This was an attempt to use a const parameter outside its scope.
3922
3929
if record_used {
3923
3930
resolve_error (
0 commit comments