@@ -1606,6 +1606,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
1606
1606
_ => None ,
1607
1607
} ;
1608
1608
1609
+ enum Defaults {
1610
+ Allowed ,
1611
+ // See #36887
1612
+ FutureCompatDisallowed ,
1613
+ Deny ,
1614
+ }
1615
+
1609
1616
let no_generics = hir:: Generics :: empty ( ) ;
1610
1617
let ast_generics = node. generics ( ) . unwrap_or ( & no_generics) ;
1611
1618
let ( opt_self, allow_defaults) = match node {
@@ -1627,17 +1634,26 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
1627
1634
} ,
1628
1635
} ) ;
1629
1636
1630
- ( opt_self, true )
1637
+ ( opt_self, Defaults :: Allowed )
1631
1638
}
1632
1639
ItemKind :: TyAlias ( ..)
1633
1640
| ItemKind :: Enum ( ..)
1634
1641
| ItemKind :: Struct ( ..)
1635
1642
| ItemKind :: OpaqueTy ( ..)
1636
- | ItemKind :: Union ( ..) => ( None , true ) ,
1637
- _ => ( None , false ) ,
1643
+ | ItemKind :: Union ( ..) => ( None , Defaults :: Allowed ) ,
1644
+ _ => ( None , Defaults :: FutureCompatDisallowed ) ,
1638
1645
}
1639
1646
}
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 ) ,
1641
1657
} ;
1642
1658
1643
1659
let has_self = opt_self. is_some ( ) ;
@@ -1670,23 +1686,30 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
1670
1686
let type_start = own_start - has_self as u32 + params. len ( ) as u32 ;
1671
1687
let mut i = 0 ;
1672
1688
1689
+ const TYPE_DEFAULT_NOT_ALLOWED : & ' static str = "defaults for type parameters are only allowed in \
1690
+ `struct`, `enum`, `type`, or `trait` definitions";
1691
+
1673
1692
params. extend ( ast_generics. params . iter ( ) . filter_map ( |param| match param. kind {
1674
1693
GenericParamKind :: Lifetime { .. } => None ,
1675
1694
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
+ }
1690
1713
}
1691
1714
}
1692
1715
@@ -1703,7 +1726,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
1703
1726
Some ( param_def)
1704
1727
}
1705
1728
GenericParamKind :: Const { default, .. } => {
1706
- if !allow_defaults && default. is_some ( ) {
1729
+ if !matches ! ( allow_defaults, Defaults :: Allowed ) && default. is_some ( ) {
1707
1730
tcx. sess . span_err (
1708
1731
param. span ,
1709
1732
"defaults for const parameters are only allowed in \
0 commit comments