@@ -1695,85 +1695,21 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1695
1695
/// Due to normalization being eager, this applies even if
1696
1696
/// the associated type is behind a pointer, e.g. issue #31299.
1697
1697
pub fn sized_constraint ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Ty < ' tcx > {
1698
- self . calculate_sized_constraint_inner ( tcx. global_tcx ( ) , & mut Vec :: new ( ) )
1699
- }
1700
-
1701
- /// Calculates the Sized-constraint.
1702
- ///
1703
- /// As the Sized-constraint of enums can be a *set* of types,
1704
- /// the Sized-constraint may need to be a set also. Because introducing
1705
- /// a new type of IVar is currently a complex affair, the Sized-constraint
1706
- /// may be a tuple.
1707
- ///
1708
- /// In fact, there are only a few options for the constraint:
1709
- /// - `bool`, if the type is always Sized
1710
- /// - an obviously-unsized type
1711
- /// - a type parameter or projection whose Sizedness can't be known
1712
- /// - a tuple of type parameters or projections, if there are multiple
1713
- /// such.
1714
- /// - a TyError, if a type contained itself. The representability
1715
- /// check should catch this case.
1716
- fn calculate_sized_constraint_inner ( & self ,
1717
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1718
- stack : & mut Vec < DefId > )
1719
- -> Ty < ' tcx >
1720
- {
1721
- if let Some ( ty) = tcx. maps . adt_sized_constraint . borrow ( ) . get ( & self . did ) {
1722
- return ty;
1723
- }
1724
-
1725
- // Follow the memoization pattern: push the computation of
1726
- // DepNode::SizedConstraint as our current task.
1727
- let _task = tcx. dep_graph . in_task ( DepNode :: SizedConstraint ( self . did ) ) ;
1728
-
1729
- if stack. contains ( & self . did ) {
1730
- debug ! ( "calculate_sized_constraint: {:?} is recursive" , self ) ;
1731
- // This should be reported as an error by `check_representable`.
1732
- //
1733
- // Consider the type as Sized in the meanwhile to avoid
1734
- // further errors.
1735
- tcx. maps . adt_sized_constraint . borrow_mut ( ) . insert ( self . did , tcx. types . err ) ;
1736
- return tcx. types . err ;
1737
- }
1738
-
1739
- stack. push ( self . did ) ;
1740
-
1741
- let tys : Vec < _ > =
1742
- self . variants . iter ( ) . flat_map ( |v| {
1743
- v. fields . last ( )
1744
- } ) . flat_map ( |f| {
1745
- let ty = tcx. item_type ( f. did ) ;
1746
- self . sized_constraint_for_ty ( tcx, stack, ty)
1747
- } ) . collect ( ) ;
1748
-
1749
- let self_ = stack. pop ( ) . unwrap ( ) ;
1750
- assert_eq ! ( self_, self . did) ;
1751
-
1752
- let ty = match tys. len ( ) {
1753
- _ if tys. references_error ( ) => tcx. types . err ,
1754
- 0 => tcx. types . bool ,
1755
- 1 => tys[ 0 ] ,
1756
- _ => tcx. intern_tup ( & tys[ ..] , false )
1757
- } ;
1758
-
1759
- let old = tcx. maps . adt_sized_constraint . borrow ( ) . get ( & self . did ) . cloned ( ) ;
1760
- match old {
1761
- Some ( old_ty) => {
1762
- debug ! ( "calculate_sized_constraint: {:?} recurred" , self ) ;
1763
- assert_eq ! ( old_ty, tcx. types. err) ;
1764
- old_ty
1765
- }
1766
- None => {
1767
- debug ! ( "calculate_sized_constraint: {:?} => {:?}" , self , ty) ;
1768
- tcx. maps . adt_sized_constraint . borrow_mut ( ) . insert ( self . did , ty) ;
1769
- ty
1698
+ match queries:: adt_sized_constraint:: try_get ( tcx, DUMMY_SP , self . did ) {
1699
+ Ok ( ty) => ty,
1700
+ Err ( _) => {
1701
+ debug ! ( "adt_sized_constraint: {:?} is recursive" , self ) ;
1702
+ // This should be reported as an error by `check_representable`.
1703
+ //
1704
+ // Consider the type as Sized in the meanwhile to avoid
1705
+ // further errors.
1706
+ tcx. types . err
1770
1707
}
1771
1708
}
1772
1709
}
1773
1710
1774
1711
fn sized_constraint_for_ty ( & self ,
1775
1712
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1776
- stack : & mut Vec < DefId > ,
1777
1713
ty : Ty < ' tcx > )
1778
1714
-> Vec < Ty < ' tcx > > {
1779
1715
let result = match ty. sty {
@@ -1791,23 +1727,23 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1791
1727
TyTuple ( ref tys, _) => {
1792
1728
match tys. last ( ) {
1793
1729
None => vec ! [ ] ,
1794
- Some ( ty) => self . sized_constraint_for_ty ( tcx, stack , ty)
1730
+ Some ( ty) => self . sized_constraint_for_ty ( tcx, ty)
1795
1731
}
1796
1732
}
1797
1733
1798
1734
TyAdt ( adt, substs) => {
1799
1735
// recursive case
1800
1736
let adt_ty =
1801
- adt. calculate_sized_constraint_inner ( tcx, stack )
1737
+ adt. sized_constraint ( tcx)
1802
1738
. subst ( tcx, substs) ;
1803
1739
debug ! ( "sized_constraint_for_ty({:?}) intermediate = {:?}" ,
1804
1740
ty, adt_ty) ;
1805
1741
if let ty:: TyTuple ( ref tys, _) = adt_ty. sty {
1806
1742
tys. iter ( ) . flat_map ( |ty| {
1807
- self . sized_constraint_for_ty ( tcx, stack , ty)
1743
+ self . sized_constraint_for_ty ( tcx, ty)
1808
1744
} ) . collect ( )
1809
1745
} else {
1810
- self . sized_constraint_for_ty ( tcx, stack , adt_ty)
1746
+ self . sized_constraint_for_ty ( tcx, adt_ty)
1811
1747
}
1812
1748
}
1813
1749
@@ -2703,9 +2639,56 @@ fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
2703
2639
panic ! ( "associated item not found for def_id: {:?}" , def_id) ;
2704
2640
}
2705
2641
2642
+ /// Calculates the Sized-constraint.
2643
+ ///
2644
+ /// As the Sized-constraint of enums can be a *set* of types,
2645
+ /// the Sized-constraint may need to be a set also. Because introducing
2646
+ /// a new type of IVar is currently a complex affair, the Sized-constraint
2647
+ /// may be a tuple.
2648
+ ///
2649
+ /// In fact, there are only a few options for the constraint:
2650
+ /// - `bool`, if the type is always Sized
2651
+ /// - an obviously-unsized type
2652
+ /// - a type parameter or projection whose Sizedness can't be known
2653
+ /// - a tuple of type parameters or projections, if there are multiple
2654
+ /// such.
2655
+ /// - a TyError, if a type contained itself. The representability
2656
+ /// check should catch this case.
2657
+ fn adt_sized_constraint < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
2658
+ def_id : DefId )
2659
+ -> Ty < ' tcx > {
2660
+ let def = tcx. lookup_adt_def ( def_id) ;
2661
+
2662
+ let tys: Vec < _ > = def. variants . iter ( ) . flat_map ( |v| {
2663
+ v. fields . last ( )
2664
+ } ) . flat_map ( |f| {
2665
+ let ty = tcx. item_type ( f. did ) ;
2666
+ def. sized_constraint_for_ty ( tcx, ty)
2667
+ } ) . collect ( ) ;
2668
+
2669
+ let ty = match tys. len ( ) {
2670
+ _ if tys. references_error ( ) => tcx. types . err ,
2671
+ 0 => tcx. types . bool ,
2672
+ 1 => tys[ 0 ] ,
2673
+ _ => tcx. intern_tup ( & tys[ ..] , false )
2674
+ } ;
2675
+
2676
+ debug ! ( "adt_sized_constraint: {:?} => {:?}" , def, ty) ;
2677
+
2678
+ ty
2679
+ }
2680
+
2706
2681
pub fn provide ( providers : & mut ty:: maps:: Providers ) {
2707
2682
* providers = ty:: maps:: Providers {
2708
2683
associated_item,
2684
+ adt_sized_constraint,
2685
+ ..* providers
2686
+ } ;
2687
+ }
2688
+
2689
+ pub fn provide_extern ( providers : & mut ty:: maps:: Providers ) {
2690
+ * providers = ty:: maps:: Providers {
2691
+ adt_sized_constraint,
2709
2692
..* providers
2710
2693
} ;
2711
2694
}
0 commit comments