@@ -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 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,21 +3916,27 @@ 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 {
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 ;
39283938 }
3929- return Def :: Err ;
3939+ _ => { }
39303940 }
39313941 }
39323942 }
0 commit comments