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