@@ -1701,33 +1701,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1701
1701
}
1702
1702
Ok ( Some ( ct) ) => {
1703
1703
if ct. unify_failure_kind ( self . tcx ) == FailureKind :: Concrete {
1704
- substs = self . tcx . mk_substs ( substs. iter ( ) . enumerate ( ) . map ( |( idx, arg) | {
1705
- let needs_replacement =
1706
- arg. has_param_types_or_consts ( ) || arg. has_infer_types_or_consts ( ) ;
1707
- match arg. unpack ( ) {
1708
- GenericArgKind :: Type ( _) if needs_replacement => self
1709
- . tcx
1710
- . mk_ty ( ty:: Placeholder ( ty:: PlaceholderType {
1711
- universe : ty:: UniverseIndex :: ROOT ,
1712
- name : ty:: BoundVar :: from_usize ( idx) ,
1713
- } ) )
1714
- . into ( ) ,
1715
- GenericArgKind :: Const ( ct) if needs_replacement => self
1716
- . tcx
1717
- . mk_const ( ty:: ConstS {
1718
- ty : ct. ty ( ) ,
1719
- kind : ty:: ConstKind :: Placeholder ( ty:: PlaceholderConst {
1720
- universe : ty:: UniverseIndex :: ROOT ,
1721
- name : ty:: BoundConst {
1722
- var : ty:: BoundVar :: from_usize ( idx) ,
1723
- ty : ct. ty ( ) ,
1724
- } ,
1725
- } ) ,
1726
- } )
1727
- . into ( ) ,
1728
- _ => arg,
1729
- }
1730
- } ) ) ;
1704
+ substs = replace_param_and_infer_substs_with_placeholder ( self . tcx , substs) ;
1731
1705
} else {
1732
1706
return Err ( ErrorHandled :: TooGeneric ) ;
1733
1707
}
@@ -2052,3 +2026,43 @@ impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
2052
2026
)
2053
2027
}
2054
2028
}
2029
+
2030
+ /// Replaces substs that reference param or infer variables with suitable
2031
+ /// placeholders. This function is meant to remove these param and infer
2032
+ /// substs when they're not actually needed to evaluate a constant.
2033
+ fn replace_param_and_infer_substs_with_placeholder < ' tcx > (
2034
+ tcx : TyCtxt < ' tcx > ,
2035
+ substs : SubstsRef < ' tcx > ,
2036
+ ) -> SubstsRef < ' tcx > {
2037
+ tcx. mk_substs ( substs. iter ( ) . enumerate ( ) . map ( |( idx, arg) | {
2038
+ match arg. unpack ( ) {
2039
+ GenericArgKind :: Type ( _)
2040
+ if arg. has_param_types_or_consts ( ) || arg. has_infer_types_or_consts ( ) =>
2041
+ {
2042
+ tcx. mk_ty ( ty:: Placeholder ( ty:: PlaceholderType {
2043
+ universe : ty:: UniverseIndex :: ROOT ,
2044
+ name : ty:: BoundVar :: from_usize ( idx) ,
2045
+ } ) )
2046
+ . into ( )
2047
+ }
2048
+ GenericArgKind :: Const ( ct)
2049
+ if ct. has_infer_types_or_consts ( ) || ct. has_param_types_or_consts ( ) =>
2050
+ {
2051
+ let ty = ct. ty ( ) ;
2052
+ // If the type references param or infer, replace that too...
2053
+ if ty. has_param_types_or_consts ( ) || ty. has_infer_types_or_consts ( ) {
2054
+ bug ! ( "const `{ct}`'s type should not reference params or types" ) ;
2055
+ }
2056
+ tcx. mk_const ( ty:: ConstS {
2057
+ ty,
2058
+ kind : ty:: ConstKind :: Placeholder ( ty:: PlaceholderConst {
2059
+ universe : ty:: UniverseIndex :: ROOT ,
2060
+ name : ty:: BoundConst { ty, var : ty:: BoundVar :: from_usize ( idx) } ,
2061
+ } ) ,
2062
+ } )
2063
+ . into ( )
2064
+ }
2065
+ _ => arg,
2066
+ }
2067
+ } ) )
2068
+ }
0 commit comments