@@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
814814 debug ! ( "(resolving function) entering function" ) ;
815815 let ( rib_kind, asyncness) = match function_kind {
816816 FnKind :: ItemFn ( _, ref header, ..) =>
817- ( ItemRibKind , header. asyncness . node ) ,
817+ ( FnItemRibKind , header. asyncness . node ) ,
818818 FnKind :: Method ( _, ref sig, _, _) =>
819819 ( TraitOrImplItemRibKind , sig. header . asyncness . node ) ,
820820 FnKind :: Closure ( _) =>
@@ -950,6 +950,10 @@ enum RibKind<'a> {
950950 /// upvars).
951951 TraitOrImplItemRibKind ,
952952
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+
953957 /// We passed through an item scope. Disallow upvars.
954958 ItemRibKind ,
955959
@@ -3863,7 +3867,7 @@ impl<'a> Resolver<'a> {
38633867 seen. insert ( node_id, depth) ;
38643868 }
38653869 }
3866- ItemRibKind | TraitOrImplItemRibKind => {
3870+ ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
38673871 // This was an attempt to access an upvar inside a
38683872 // named function item. This is not allowed, so we
38693873 // report an error.
@@ -3897,7 +3901,7 @@ impl<'a> Resolver<'a> {
38973901 ConstantItemRibKind => {
38983902 // Nothing to do. Continue.
38993903 }
3900- ItemRibKind => {
3904+ ItemRibKind | FnItemRibKind => {
39013905 // This was an attempt to use a type parameter outside its scope.
39023906 if record_used {
39033907 resolve_error (
@@ -3912,12 +3916,15 @@ impl<'a> Resolver<'a> {
39123916 }
39133917 }
39143918 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 {
39213928 // This was an attempt to use a const parameter outside its scope.
39223929 if record_used {
39233930 resolve_error (
0 commit comments