@@ -1750,28 +1750,69 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
1750
1750
}
1751
1751
1752
1752
impl < ' tcx > AdtDefData < ' tcx , ' tcx > {
1753
- fn sized_constraint_for_tys < TYS > (
1754
- & ' tcx self ,
1755
- tcx : & ty:: TyCtxt < ' tcx > ,
1756
- stack : & mut Vec < AdtDefMaster < ' tcx > > ,
1757
- tys : TYS
1758
- ) -> Ty < ' tcx >
1759
- where TYS : IntoIterator < Item =Ty < ' tcx > >
1753
+ /// Calculates the Sized-constraint.
1754
+ ///
1755
+ /// As the Sized-constraint of enums can be a *set* of types,
1756
+ /// the Sized-constraint may need to be a set also. Because introducing
1757
+ /// a new type of IVar is currently a complex affair, the Sized-constraint
1758
+ /// may be a tuple.
1759
+ ///
1760
+ /// In fact, there are only a few options for the constraint:
1761
+ /// - `bool`, if the type is always Sized
1762
+ /// - an obviously-unsized type
1763
+ /// - a type parameter or projection whose Sizedness can't be known
1764
+ /// - a tuple of type parameters or projections, if there are multiple
1765
+ /// such.
1766
+ /// - a TyError, if a type contained itself. The representability
1767
+ /// check should catch this case.
1768
+ fn calculate_sized_constraint_inner ( & ' tcx self , tcx : & ty:: TyCtxt < ' tcx > ,
1769
+ stack : & mut Vec < AdtDefMaster < ' tcx > > )
1760
1770
{
1761
- let tys : Vec < _ > = tys. into_iter ( )
1762
- . map ( |ty| self . sized_constraint_for_ty ( tcx, stack, ty) )
1763
- . flat_map ( |ty| match ty. sty {
1764
- ty:: TyTuple ( ref tys) => tys. last ( ) . cloned ( ) ,
1765
- _ => Some ( ty)
1766
- } )
1767
- . filter ( |ty| * ty != tcx. types . bool )
1768
- . collect ( ) ;
1769
-
1770
- match tys. len ( ) {
1771
+
1772
+ let dep_node = DepNode :: SizedConstraint ( self . did ) ;
1773
+
1774
+ if self . sized_constraint . get ( dep_node) . is_some ( ) {
1775
+ return ;
1776
+ }
1777
+
1778
+ if stack. contains ( & self ) {
1779
+ debug ! ( "calculate_sized_constraint: {:?} is recursive" , self ) ;
1780
+ // This should be reported as an error by `check_representable`.
1781
+ //
1782
+ // Consider the type as Sized in the meanwhile to avoid
1783
+ // further errors.
1784
+ self . sized_constraint . fulfill ( dep_node, tcx. types . err ) ;
1785
+ return ;
1786
+ }
1787
+
1788
+ stack. push ( self ) ;
1789
+
1790
+ let tys : Vec < _ > =
1791
+ self . variants . iter ( ) . flat_map ( |v| {
1792
+ v. fields . last ( )
1793
+ } ) . flat_map ( |f| {
1794
+ self . sized_constraint_for_ty ( tcx, stack, f. unsubst_ty ( ) )
1795
+ } ) . collect ( ) ;
1796
+
1797
+ let self_ = stack. pop ( ) . unwrap ( ) ;
1798
+ assert_eq ! ( self_, self ) ;
1799
+
1800
+ let ty = match tys. len ( ) {
1771
1801
_ if tys. references_error ( ) => tcx. types . err ,
1772
1802
0 => tcx. types . bool ,
1773
1803
1 => tys[ 0 ] ,
1774
1804
_ => tcx. mk_tup ( tys)
1805
+ } ;
1806
+
1807
+ match self . sized_constraint . get ( dep_node) {
1808
+ Some ( old_ty) => {
1809
+ debug ! ( "calculate_sized_constraint: {:?} recurred" , self ) ;
1810
+ assert_eq ! ( old_ty, tcx. types. err)
1811
+ }
1812
+ None => {
1813
+ debug ! ( "calculate_sized_constraint: {:?} => {:?}" , self , ty) ;
1814
+ self . sized_constraint . fulfill ( dep_node, ty)
1815
+ }
1775
1816
}
1776
1817
}
1777
1818
@@ -1780,22 +1821,23 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
1780
1821
tcx : & ty:: TyCtxt < ' tcx > ,
1781
1822
stack : & mut Vec < AdtDefMaster < ' tcx > > ,
1782
1823
ty : Ty < ' tcx >
1783
- ) -> Ty < ' tcx > {
1824
+ ) -> Vec < Ty < ' tcx > > {
1784
1825
let result = match ty. sty {
1785
1826
TyBool | TyChar | TyInt ( ..) | TyUint ( ..) | TyFloat ( ..) |
1786
1827
TyBox ( ..) | TyRawPtr ( ..) | TyRef ( ..) | TyFnDef ( ..) | TyFnPtr ( _) |
1787
1828
TyArray ( ..) | TyClosure ( ..) => {
1788
- // these are always sized - return a primitive
1789
- tcx. types . bool
1829
+ vec ! [ ]
1790
1830
}
1791
1831
1792
1832
TyStr | TyTrait ( ..) | TySlice ( _) | TyError => {
1793
1833
// these are never sized - return the target type
1794
- ty
1834
+ vec ! [ ty ]
1795
1835
}
1796
1836
1797
1837
TyTuple ( ref tys) => {
1798
- self . sized_constraint_for_tys ( tcx, stack, tys. iter ( ) . cloned ( ) )
1838
+ tys. last ( ) . into_iter ( ) . flat_map ( |ty| {
1839
+ self . sized_constraint_for_ty ( tcx, stack, ty)
1840
+ } ) . collect ( )
1799
1841
}
1800
1842
1801
1843
TyEnum ( adt, substs) | TyStruct ( adt, substs) => {
@@ -1808,13 +1850,19 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
1808
1850
. subst ( tcx, substs) ;
1809
1851
debug ! ( "sized_constraint_for_ty({:?}) intermediate = {:?}" ,
1810
1852
ty, adt_ty) ;
1811
- self . sized_constraint_for_ty ( tcx, stack, adt_ty)
1853
+ if let ty:: TyTuple ( ref tys) = adt_ty. sty {
1854
+ tys. iter ( ) . flat_map ( |ty| {
1855
+ self . sized_constraint_for_ty ( tcx, stack, ty)
1856
+ } ) . collect ( )
1857
+ } else {
1858
+ self . sized_constraint_for_ty ( tcx, stack, adt_ty)
1859
+ }
1812
1860
}
1813
1861
1814
1862
TyProjection ( ..) => {
1815
1863
// must calculate explicitly.
1816
1864
// FIXME: consider special-casing always-Sized projections
1817
- ty
1865
+ vec ! [ ty ]
1818
1866
}
1819
1867
1820
1868
TyParam ( ..) => {
@@ -1824,7 +1872,7 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
1824
1872
1825
1873
let sized_trait = match tcx. lang_items . sized_trait ( ) {
1826
1874
Some ( x) => x,
1827
- _ => return ty
1875
+ _ => return vec ! [ ty ]
1828
1876
} ;
1829
1877
let sized_predicate = Binder ( TraitRef {
1830
1878
def_id : sized_trait,
@@ -1834,9 +1882,9 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
1834
1882
} ) . to_predicate ( ) ;
1835
1883
let predicates = tcx. lookup_predicates ( self . did ) . predicates ;
1836
1884
if predicates. into_iter ( ) . any ( |p| p == sized_predicate) {
1837
- tcx . types . bool
1885
+ vec ! [ ]
1838
1886
} else {
1839
- ty
1887
+ vec ! [ ty ]
1840
1888
}
1841
1889
}
1842
1890
@@ -1848,60 +1896,6 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
1848
1896
debug ! ( "sized_constraint_for_ty({:?}) = {:?}" , ty, result) ;
1849
1897
result
1850
1898
}
1851
-
1852
- /// Calculates the Sized-constraint.
1853
- ///
1854
- /// As the Sized-constraint of enums can be a *set* of types,
1855
- /// the Sized-constraint may need to be a set also. Because introducing
1856
- /// a new type of IVar is currently a complex affair, the Sized-constraint
1857
- /// may be a tuple.
1858
- ///
1859
- /// In fact, there are only a few options for the constraint:
1860
- /// - `bool`, if the type is always Sized
1861
- /// - an obviously-unsized type
1862
- /// - a type parameter or projection whose Sizedness can't be known
1863
- /// - a tuple of type parameters or projections, if there are multiple
1864
- /// such.
1865
- /// - a TyError, if a type contained itself. The representability
1866
- /// check should catch this case.
1867
- fn calculate_sized_constraint_inner ( & ' tcx self , tcx : & ty:: TyCtxt < ' tcx > ,
1868
- stack : & mut Vec < AdtDefMaster < ' tcx > > )
1869
- {
1870
-
1871
- let dep_node = DepNode :: SizedConstraint ( self . did ) ;
1872
-
1873
- if self . sized_constraint . get ( dep_node) . is_some ( ) {
1874
- return ;
1875
- }
1876
-
1877
- if stack. contains ( & self ) {
1878
- debug ! ( "calculate_sized_constraint: {:?} is recursive" , self ) ;
1879
- self . sized_constraint . fulfill ( dep_node, tcx. types . err ) ;
1880
- return ;
1881
- }
1882
-
1883
- stack. push ( self ) ;
1884
- let ty = self . sized_constraint_for_tys (
1885
- tcx, stack,
1886
- self . variants . iter ( ) . flat_map ( |v| {
1887
- v. fields . last ( )
1888
- } ) . map ( |f| f. unsubst_ty ( ) )
1889
- ) ;
1890
-
1891
- let self_ = stack. pop ( ) . unwrap ( ) ;
1892
- assert_eq ! ( self_, self ) ;
1893
-
1894
- match self . sized_constraint . get ( dep_node) {
1895
- Some ( old_ty) => {
1896
- debug ! ( "calculate_sized_constraint: {:?} recurred" , self ) ;
1897
- assert_eq ! ( old_ty, tcx. types. err)
1898
- }
1899
- None => {
1900
- debug ! ( "calculate_sized_constraint: {:?} => {:?}" , self , ty) ;
1901
- self . sized_constraint . fulfill ( dep_node, ty)
1902
- }
1903
- }
1904
- }
1905
1899
}
1906
1900
1907
1901
impl < ' tcx , ' container > VariantDefData < ' tcx , ' container > {
0 commit comments