@@ -555,18 +555,23 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
555555 // provide previous type parameters as they're built. We
556556 // put all the parameters on the ban list and then remove
557557 // them one by one as they are processed and become available.
558- let mut default_ban_rib = Rib :: new ( ForwardGenericParamBanRibKind ) ;
559- let mut found_default = false ;
560- default_ban_rib . bindings . extend ( generics. params . iter ( ) . filter_map (
561- |param| match param. kind {
562- GenericParamKind :: Type { default : Some ( _ ) , .. }
563- | GenericParamKind :: Const { default : Some ( _ ) , .. } => {
564- found_default = true ;
565- Some ( ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) )
558+ let mut forward_ty_ban_rib = Rib :: new ( ForwardGenericParamBanRibKind ) ;
559+ let mut forward_const_ban_rib = Rib :: new ( ForwardGenericParamBanRibKind ) ;
560+ for param in generics. params . iter ( ) {
561+ match param. kind {
562+ GenericParamKind :: Type { .. } => {
563+ forward_ty_ban_rib
564+ . bindings
565+ . insert ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) ;
566566 }
567- _ => None ,
568- } ,
569- ) ) ;
567+ GenericParamKind :: Const { .. } => {
568+ forward_const_ban_rib
569+ . bindings
570+ . insert ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) ;
571+ }
572+ GenericParamKind :: Lifetime => { }
573+ }
574+ }
570575
571576 // rust-lang/rust#61631: The type `Self` is essentially
572577 // another type parameter. For ADTs, we consider it
@@ -579,7 +584,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
579584 // such as in the case of `trait Add<Rhs = Self>`.)
580585 if self . diagnostic_metadata . current_self_item . is_some ( ) {
581586 // (`Some` if + only if we are in ADT's generics.)
582- default_ban_rib . bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
587+ forward_ty_ban_rib . bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
583588 }
584589
585590 for param in & generics. params {
@@ -591,32 +596,38 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
591596 }
592597
593598 if let Some ( ref ty) = default {
594- self . ribs [ TypeNS ] . push ( default_ban_rib) ;
595- self . with_rib ( ValueNS , ForwardGenericParamBanRibKind , |this| {
596- // HACK: We use an empty `ForwardGenericParamBanRibKind` here which
597- // is only used to forbid the use of const parameters inside of
598- // type defaults.
599- //
600- // While the rib name doesn't really fit here, it does allow us to use the same
601- // code for both const and type parameters.
602- this. visit_ty ( ty) ;
603- } ) ;
604- default_ban_rib = self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
599+ self . ribs [ TypeNS ] . push ( forward_ty_ban_rib) ;
600+ self . ribs [ ValueNS ] . push ( forward_const_ban_rib) ;
601+ self . visit_ty ( ty) ;
602+ forward_const_ban_rib = self . ribs [ ValueNS ] . pop ( ) . unwrap ( ) ;
603+ forward_ty_ban_rib = self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
605604 }
606605
607606 // Allow all following defaults to refer to this type parameter.
608- default_ban_rib . bindings . remove ( & Ident :: with_dummy_span ( param. ident . name ) ) ;
607+ forward_ty_ban_rib . bindings . remove ( & Ident :: with_dummy_span ( param. ident . name ) ) ;
609608 }
610- GenericParamKind :: Const { ref ty, kw_span : _, default : _ } => {
611- // FIXME(const_generics_defaults): handle `default` value here
612- for bound in & param. bounds {
613- self . visit_param_bound ( bound) ;
614- }
609+ GenericParamKind :: Const { ref ty, kw_span : _, ref default } => {
610+ // Const parameters can't have param bounds.
611+ assert ! ( param. bounds. is_empty( ) ) ;
612+
615613 self . ribs [ TypeNS ] . push ( Rib :: new ( ConstParamTyRibKind ) ) ;
616614 self . ribs [ ValueNS ] . push ( Rib :: new ( ConstParamTyRibKind ) ) ;
617615 self . visit_ty ( ty) ;
618616 self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
619617 self . ribs [ ValueNS ] . pop ( ) . unwrap ( ) ;
618+
619+ if let Some ( ref expr) = default {
620+ self . ribs [ TypeNS ] . push ( forward_ty_ban_rib) ;
621+ self . ribs [ ValueNS ] . push ( forward_const_ban_rib) ;
622+ self . visit_anon_const ( expr) ;
623+ forward_const_ban_rib = self . ribs [ ValueNS ] . pop ( ) . unwrap ( ) ;
624+ forward_ty_ban_rib = self . ribs [ TypeNS ] . pop ( ) . unwrap ( ) ;
625+ }
626+
627+ // Allow all following defaults to refer to this const parameter.
628+ forward_const_ban_rib
629+ . bindings
630+ . remove ( & Ident :: with_dummy_span ( param. ident . name ) ) ;
620631 }
621632 }
622633 }
0 commit comments