@@ -1695,85 +1695,21 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16951695 /// Due to normalization being eager, this applies even if
16961696 /// the associated type is behind a pointer, e.g. issue #31299.
16971697 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
17701707 }
17711708 }
17721709 }
17731710
17741711 fn sized_constraint_for_ty ( & self ,
17751712 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1776- stack : & mut Vec < DefId > ,
17771713 ty : Ty < ' tcx > )
17781714 -> Vec < Ty < ' tcx > > {
17791715 let result = match ty. sty {
@@ -1791,23 +1727,23 @@ impl<'a, 'gcx, 'tcx> AdtDef {
17911727 TyTuple ( ref tys, _) => {
17921728 match tys. last ( ) {
17931729 None => vec ! [ ] ,
1794- Some ( ty) => self . sized_constraint_for_ty ( tcx, stack , ty)
1730+ Some ( ty) => self . sized_constraint_for_ty ( tcx, ty)
17951731 }
17961732 }
17971733
17981734 TyAdt ( adt, substs) => {
17991735 // recursive case
18001736 let adt_ty =
1801- adt. calculate_sized_constraint_inner ( tcx, stack )
1737+ adt. sized_constraint ( tcx)
18021738 . subst ( tcx, substs) ;
18031739 debug ! ( "sized_constraint_for_ty({:?}) intermediate = {:?}" ,
18041740 ty, adt_ty) ;
18051741 if let ty:: TyTuple ( ref tys, _) = adt_ty. sty {
18061742 tys. iter ( ) . flat_map ( |ty| {
1807- self . sized_constraint_for_ty ( tcx, stack , ty)
1743+ self . sized_constraint_for_ty ( tcx, ty)
18081744 } ) . collect ( )
18091745 } else {
1810- self . sized_constraint_for_ty ( tcx, stack , adt_ty)
1746+ self . sized_constraint_for_ty ( tcx, adt_ty)
18111747 }
18121748 }
18131749
@@ -2703,9 +2639,56 @@ fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
27032639 panic ! ( "associated item not found for def_id: {:?}" , def_id) ;
27042640}
27052641
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+
27062681pub fn provide ( providers : & mut ty:: maps:: Providers ) {
27072682 * providers = ty:: maps:: Providers {
27082683 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,
27092692 ..* providers
27102693 } ;
27112694}
0 commit comments