@@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap;
2727use  rustc_data_structures:: sorted_map:: SortedIndexMultiMap ; 
2828use  rustc_data_structures:: stable_hasher:: { HashStable ,  StableHasher } ; 
2929use  rustc_data_structures:: sync:: { self ,  par_iter,  ParallelIterator } ; 
30+ use  rustc_data_structures:: tagged_ptr:: CopyTaggedPtr ; 
3031use  rustc_errors:: ErrorReported ; 
3132use  rustc_hir as  hir; 
3233use  rustc_hir:: def:: { CtorKind ,  CtorOf ,  DefKind ,  Namespace ,  Res } ; 
@@ -46,7 +47,6 @@ use std::cell::RefCell;
4647use  std:: cmp:: Ordering ; 
4748use  std:: fmt; 
4849use  std:: hash:: { Hash ,  Hasher } ; 
49- use  std:: marker:: PhantomData ; 
5050use  std:: ops:: Range ; 
5151use  std:: ptr; 
5252use  std:: str; 
@@ -1713,41 +1713,45 @@ impl WithOptConstParam<DefId> {
17131713/// When type checking, we use the `ParamEnv` to track 
17141714/// details about the set of where-clauses that are in scope at this 
17151715/// particular point. 
1716- #[ derive( Copy ,  Clone ) ]  
1716+ #[ derive( Copy ,  Clone ,   Hash ,   PartialEq ,   Eq ) ]  
17171717pub  struct  ParamEnv < ' tcx >  { 
1718-     // We pack the caller_bounds List pointer and a Reveal enum into this usize. 
1719-     // Specifically, the low bit represents Reveal, with 0 meaning `UserFacing` 
1720-     // and 1 meaning `All`. The rest is the pointer. 
1721-     // 
1722-     // This relies on the List<Predicate<'tcx>> type having at least 2-byte 
1723-     // alignment. Lists start with a usize and are repr(C) so this should be 
1724-     // fine; there is a debug_assert in the constructor as well. 
1725-     // 
1726-     // Note that the choice of 0 for UserFacing is intentional -- since it is the 
1727-     // first variant in Reveal this means that joining the pointer is a simple `or`. 
1728-     packed_data :  usize , 
1729- 
1730-     /// `Obligation`s that the caller must satisfy. This is basically 
1731- /// the set of bounds on the in-scope type parameters, translated 
1718+     /// This packs both caller bounds and the reveal enum into one pointer. 
1719+ /// 
1720+ /// Caller bounds are `Obligation`s that the caller must satisfy. This is 
1721+ /// basically the set of bounds on the in-scope type parameters, translated 
17321722/// into `Obligation`s, and elaborated and normalized. 
17331723/// 
1734- /// Note: This is packed into the `packed_data` usize above, use the 
1735- /// `caller_bounds()` method to access it. 
1736- caller_bounds :  PhantomData < & ' tcx  List < Predicate < ' tcx > > > , 
1737- 
1724+ /// Use the `caller_bounds()` method to access. 
1725+ /// 
17381726/// Typically, this is `Reveal::UserFacing`, but during codegen we 
17391727/// want `Reveal::All`. 
17401728/// 
1741- /// Note: This is packed into the caller_bounds usize above, use the reveal() 
1742- /// method to access it. 
1743- reveal :  PhantomData < traits:: Reveal > , 
1729+ /// Note: This is packed, use the reveal() method to access it. 
1730+ packed :  CopyTaggedPtr < & ' tcx  List < Predicate < ' tcx > > ,  traits:: Reveal ,  true > , 
17441731
17451732    /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`, 
17461733/// register that `def_id` (useful for transitioning to the chalk trait 
17471734/// solver). 
17481735pub  def_id :  Option < DefId > , 
17491736} 
17501737
1738+ unsafe  impl  rustc_data_structures:: tagged_ptr:: Tag  for  traits:: Reveal  { 
1739+     const  BITS :  usize  = 1 ; 
1740+     fn  into_usize ( self )  -> usize  { 
1741+         match  self  { 
1742+             traits:: Reveal :: UserFacing  => 0 , 
1743+             traits:: Reveal :: All  => 1 , 
1744+         } 
1745+     } 
1746+     unsafe  fn  from_usize ( ptr :  usize )  -> Self  { 
1747+         match  ptr { 
1748+             0  => traits:: Reveal :: UserFacing , 
1749+             1  => traits:: Reveal :: All , 
1750+             _ => std:: hint:: unreachable_unchecked ( ) , 
1751+         } 
1752+     } 
1753+ } 
1754+ 
17511755impl < ' tcx >  fmt:: Debug  for  ParamEnv < ' tcx >  { 
17521756    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
17531757        f. debug_struct ( "ParamEnv" ) 
@@ -1758,24 +1762,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
17581762    } 
17591763} 
17601764
1761- impl < ' tcx >  Hash  for  ParamEnv < ' tcx >  { 
1762-     fn  hash < H :  Hasher > ( & self ,  state :  & mut  H )  { 
1763-         // List hashes as the raw pointer, so we can skip splitting into the 
1764-         // pointer and the enum. 
1765-         self . packed_data . hash ( state) ; 
1766-         self . def_id . hash ( state) ; 
1767-     } 
1768- } 
1769- 
1770- impl < ' tcx >  PartialEq  for  ParamEnv < ' tcx >  { 
1771-     fn  eq ( & self ,  other :  & Self )  -> bool  { 
1772-         self . caller_bounds ( )  == other. caller_bounds ( ) 
1773-             && self . reveal ( )  == other. reveal ( ) 
1774-             && self . def_id  == other. def_id 
1775-     } 
1776- } 
1777- impl < ' tcx >  Eq  for  ParamEnv < ' tcx >  { } 
1778- 
17791765impl < ' a ,  ' tcx >  HashStable < StableHashingContext < ' a > >  for  ParamEnv < ' tcx >  { 
17801766    fn  hash_stable ( & self ,  hcx :  & mut  StableHashingContext < ' a > ,  hasher :  & mut  StableHasher )  { 
17811767        self . caller_bounds ( ) . hash_stable ( hcx,  hasher) ; 
@@ -1812,13 +1798,12 @@ impl<'tcx> ParamEnv<'tcx> {
18121798
18131799    #[ inline]  
18141800    pub  fn  caller_bounds ( self )  -> & ' tcx  List < Predicate < ' tcx > >  { 
1815-         // mask out bottom bit 
1816-         unsafe  {  & * ( ( self . packed_data  &  ( !1 ) )  as  * const  _ )  } 
1801+         self . packed . pointer ( ) 
18171802    } 
18181803
18191804    #[ inline]  
18201805    pub  fn  reveal ( self )  -> traits:: Reveal  { 
1821-         if   self . packed_data   &   1  ==  0   {  traits :: Reveal :: UserFacing   }   else   {  traits :: Reveal :: All   } 
1806+         self . packed . tag ( ) 
18221807    } 
18231808
18241809    /// Construct a trait environment with no where-clauses in scope 
@@ -1840,24 +1825,11 @@ impl<'tcx> ParamEnv<'tcx> {
18401825        reveal :  Reveal , 
18411826        def_id :  Option < DefId > , 
18421827    )  -> Self  { 
1843-         let  packed_data = caller_bounds as  * const  _  as  usize ; 
1844-         // Check that we can pack the reveal data into the pointer. 
1845-         debug_assert ! ( packed_data &  1  == 0 ) ; 
1846-         ty:: ParamEnv  { 
1847-             packed_data :  packed_data
1848-                 | match  reveal { 
1849-                     Reveal :: UserFacing  => 0 , 
1850-                     Reveal :: All  => 1 , 
1851-                 } , 
1852-             caller_bounds :  PhantomData , 
1853-             reveal :  PhantomData , 
1854-             def_id, 
1855-         } 
1828+         ty:: ParamEnv  {  packed :  CopyTaggedPtr :: new ( caller_bounds,  reveal) ,  def_id } 
18561829    } 
18571830
18581831    pub  fn  with_user_facing ( mut  self )  -> Self  { 
1859-         // clear bottom bit 
1860-         self . packed_data  &= !1 ; 
1832+         self . packed . set_tag ( Reveal :: UserFacing ) ; 
18611833        self 
18621834    } 
18631835
@@ -1871,7 +1843,7 @@ impl<'tcx> ParamEnv<'tcx> {
18711843/// will be normalized to their underlying types. 
18721844/// See PR #65989 and issue #65918 for more details 
18731845pub  fn  with_reveal_all_normalized ( self ,  tcx :  TyCtxt < ' tcx > )  -> Self  { 
1874-         if  self . packed_data   &   1   == 1  { 
1846+         if  self . packed . tag ( )   == traits :: Reveal :: All  { 
18751847            return  self ; 
18761848        } 
18771849
0 commit comments