@@ -1604,6 +1604,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16041604 _ => None ,
16051605 } ;
16061606
1607+ enum Defaults {
1608+ Allowed ,
1609+ // See #36887
1610+ FutureCompatDisallowed ,
1611+ Deny ,
1612+ }
1613+
16071614 let no_generics = hir:: Generics :: empty ( ) ;
16081615 let ast_generics = node. generics ( ) . unwrap_or ( & no_generics) ;
16091616 let ( opt_self, allow_defaults) = match node {
@@ -1625,17 +1632,26 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16251632 } ,
16261633 } ) ;
16271634
1628- ( opt_self, true )
1635+ ( opt_self, Defaults :: Allowed )
16291636 }
16301637 ItemKind :: TyAlias ( ..)
16311638 | ItemKind :: Enum ( ..)
16321639 | ItemKind :: Struct ( ..)
16331640 | ItemKind :: OpaqueTy ( ..)
1634- | ItemKind :: Union ( ..) => ( None , true ) ,
1635- _ => ( None , false ) ,
1641+ | ItemKind :: Union ( ..) => ( None , Defaults :: Allowed ) ,
1642+ _ => ( None , Defaults :: FutureCompatDisallowed ) ,
16361643 }
16371644 }
1638- _ => ( None , false ) ,
1645+
1646+ // GATs
1647+ Node :: TraitItem ( item) if matches ! ( item. kind, TraitItemKind :: Type ( ..) ) => {
1648+ ( None , Defaults :: Deny )
1649+ }
1650+ Node :: ImplItem ( item) if matches ! ( item. kind, ImplItemKind :: TyAlias ( ..) ) => {
1651+ ( None , Defaults :: Deny )
1652+ }
1653+
1654+ _ => ( None , Defaults :: FutureCompatDisallowed ) ,
16391655 } ;
16401656
16411657 let has_self = opt_self. is_some ( ) ;
@@ -1668,23 +1684,30 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16681684 let type_start = own_start - has_self as u32 + params. len ( ) as u32 ;
16691685 let mut i = 0 ;
16701686
1687+ const TYPE_DEFAULT_NOT_ALLOWED : & ' static str = "defaults for type parameters are only allowed in \
1688+ `struct`, `enum`, `type`, or `trait` definitions";
1689+
16711690 params. extend ( ast_generics. params . iter ( ) . filter_map ( |param| match param. kind {
16721691 GenericParamKind :: Lifetime { .. } => None ,
16731692 GenericParamKind :: Type { ref default, synthetic, .. } => {
1674- if !allow_defaults && default. is_some ( ) {
1675- if !tcx. features ( ) . default_type_parameter_fallback {
1676- tcx. struct_span_lint_hir (
1677- lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1678- param. hir_id ,
1679- param. span ,
1680- |lint| {
1681- lint. build (
1682- "defaults for type parameters are only allowed in \
1683- `struct`, `enum`, `type`, or `trait` definitions",
1684- )
1685- . emit ( ) ;
1686- } ,
1687- ) ;
1693+ if default. is_some ( ) {
1694+ match allow_defaults {
1695+ Defaults :: Allowed => { }
1696+ Defaults :: FutureCompatDisallowed
1697+ if tcx. features ( ) . default_type_parameter_fallback => { }
1698+ Defaults :: FutureCompatDisallowed => {
1699+ tcx. struct_span_lint_hir (
1700+ lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1701+ param. hir_id ,
1702+ param. span ,
1703+ |lint| {
1704+ lint. build ( TYPE_DEFAULT_NOT_ALLOWED ) . emit ( ) ;
1705+ } ,
1706+ ) ;
1707+ }
1708+ Defaults :: Deny => {
1709+ tcx. sess . span_err ( param. span , TYPE_DEFAULT_NOT_ALLOWED ) ;
1710+ }
16881711 }
16891712 }
16901713
@@ -1701,7 +1724,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17011724 Some ( param_def)
17021725 }
17031726 GenericParamKind :: Const { default, .. } => {
1704- if !allow_defaults && default. is_some ( ) {
1727+ if !matches ! ( allow_defaults, Defaults :: Allowed ) && default. is_some ( ) {
17051728 tcx. sess . span_err (
17061729 param. span ,
17071730 "defaults for const parameters are only allowed in \
0 commit comments