@@ -1606,6 +1606,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16061606 _ => None ,
16071607 } ;
16081608
1609+ enum Defaults {
1610+ Allowed ,
1611+ // See #36887
1612+ FutureCompatDisallowed ,
1613+ Deny ,
1614+ }
1615+
16091616 let no_generics = hir:: Generics :: empty ( ) ;
16101617 let ast_generics = node. generics ( ) . unwrap_or ( & no_generics) ;
16111618 let ( opt_self, allow_defaults) = match node {
@@ -1627,17 +1634,26 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16271634 } ,
16281635 } ) ;
16291636
1630- ( opt_self, true )
1637+ ( opt_self, Defaults :: Allowed )
16311638 }
16321639 ItemKind :: TyAlias ( ..)
16331640 | ItemKind :: Enum ( ..)
16341641 | ItemKind :: Struct ( ..)
16351642 | ItemKind :: OpaqueTy ( ..)
1636- | ItemKind :: Union ( ..) => ( None , true ) ,
1637- _ => ( None , false ) ,
1643+ | ItemKind :: Union ( ..) => ( None , Defaults :: Allowed ) ,
1644+ _ => ( None , Defaults :: FutureCompatDisallowed ) ,
16381645 }
16391646 }
1640- _ => ( None , false ) ,
1647+
1648+ // GATs
1649+ Node :: TraitItem ( item) if matches ! ( item. kind, TraitItemKind :: Type ( ..) ) => {
1650+ ( None , Defaults :: Deny )
1651+ }
1652+ Node :: ImplItem ( item) if matches ! ( item. kind, ImplItemKind :: TyAlias ( ..) ) => {
1653+ ( None , Defaults :: Deny )
1654+ }
1655+
1656+ _ => ( None , Defaults :: FutureCompatDisallowed ) ,
16411657 } ;
16421658
16431659 let has_self = opt_self. is_some ( ) ;
@@ -1670,23 +1686,30 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16701686 let type_start = own_start - has_self as u32 + params. len ( ) as u32 ;
16711687 let mut i = 0 ;
16721688
1689+ const TYPE_DEFAULT_NOT_ALLOWED : & ' static str = "defaults for type parameters are only allowed in \
1690+ `struct`, `enum`, `type`, or `trait` definitions";
1691+
16731692 params. extend ( ast_generics. params . iter ( ) . filter_map ( |param| match param. kind {
16741693 GenericParamKind :: Lifetime { .. } => None ,
16751694 GenericParamKind :: Type { ref default, synthetic, .. } => {
1676- if !allow_defaults && default. is_some ( ) {
1677- if !tcx. features ( ) . default_type_parameter_fallback {
1678- tcx. struct_span_lint_hir (
1679- lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1680- param. hir_id ,
1681- param. span ,
1682- |lint| {
1683- lint. build (
1684- "defaults for type parameters are only allowed in \
1685- `struct`, `enum`, `type`, or `trait` definitions",
1686- )
1687- . emit ( ) ;
1688- } ,
1689- ) ;
1695+ if default. is_some ( ) {
1696+ match allow_defaults {
1697+ Defaults :: Allowed => { }
1698+ Defaults :: FutureCompatDisallowed
1699+ if tcx. features ( ) . default_type_parameter_fallback => { }
1700+ Defaults :: FutureCompatDisallowed => {
1701+ tcx. struct_span_lint_hir (
1702+ lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1703+ param. hir_id ,
1704+ param. span ,
1705+ |lint| {
1706+ lint. build ( TYPE_DEFAULT_NOT_ALLOWED ) . emit ( ) ;
1707+ } ,
1708+ ) ;
1709+ }
1710+ Defaults :: Deny => {
1711+ tcx. sess . span_err ( param. span , TYPE_DEFAULT_NOT_ALLOWED ) ;
1712+ }
16901713 }
16911714 }
16921715
@@ -1703,7 +1726,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17031726 Some ( param_def)
17041727 }
17051728 GenericParamKind :: Const { default, .. } => {
1706- if !allow_defaults && default. is_some ( ) {
1729+ if !matches ! ( allow_defaults, Defaults :: Allowed ) && default. is_some ( ) {
17071730 tcx. sess . span_err (
17081731 param. span ,
17091732 "defaults for const parameters are only allowed in \
0 commit comments