@@ -18,12 +18,14 @@ impl Parse for Newtype {
1818 braced ! ( body in input) ;
1919
2020 // Any additional `#[derive]` macro paths to apply
21- let mut derive_paths: Vec < Path > = Vec :: new ( ) ;
2221 let mut debug_format: Option < Lit > = None ;
2322 let mut max = None ;
2423 let mut consts = Vec :: new ( ) ;
2524 let mut encodable = false ;
2625 let mut ord = false ;
26+ let mut stable_hash = false ;
27+ let mut stable_hash_generic = false ;
28+ let mut stable_hash_no_context = false ;
2729 let mut gate_rustc_only = quote ! { } ;
2830 let mut gate_rustc_only_cfg = quote ! { all( ) } ;
2931
@@ -42,6 +44,18 @@ impl Parse for Newtype {
4244 ord = true ;
4345 false
4446 }
47+ "stable_hash" => {
48+ stable_hash = true ;
49+ false
50+ }
51+ "stable_hash_generic" => {
52+ stable_hash_generic = true ;
53+ false
54+ }
55+ "stable_hash_no_context" => {
56+ stable_hash_no_context = true ;
57+ false
58+ }
4559 "max" => {
4660 let Meta :: NameValue ( MetaNameValue { value : Expr :: Lit ( lit) , .. } ) = & attr. meta
4761 else {
@@ -111,12 +125,6 @@ impl Parse for Newtype {
111125 } else {
112126 quote ! { }
113127 } ;
114-
115- if ord {
116- derive_paths. push ( parse_quote ! ( Ord ) ) ;
117- derive_paths. push ( parse_quote ! ( PartialOrd ) ) ;
118- }
119-
120128 let step = if ord {
121129 quote ! {
122130 #gate_rustc_only
@@ -139,6 +147,38 @@ impl Parse for Newtype {
139147 Self :: index( start) . checked_sub( u) . map( Self :: from_usize)
140148 }
141149 }
150+ impl :: std:: cmp:: Ord for #name {
151+ fn cmp( & self , other: & Self ) -> std:: cmp:: Ordering {
152+ self . as_u32( ) . cmp( & other. as_u32( ) )
153+ }
154+ }
155+ impl :: std:: cmp:: PartialOrd for #name {
156+ fn partial_cmp( & self , other: & Self ) -> Option <std:: cmp:: Ordering > {
157+ self . as_u32( ) . partial_cmp( & other. as_u32( ) )
158+ }
159+ }
160+ }
161+ } else {
162+ quote ! { }
163+ } ;
164+
165+ let hash_stable = if stable_hash {
166+ quote ! {
167+ #gate_rustc_only
168+ impl <' __ctx> :: rustc_data_structures:: stable_hasher:: HashStable <:: rustc_middle:: ich:: StableHashingContext <' __ctx>> for #name {
169+ fn hash_stable( & self , hcx: & mut :: rustc_middle:: ich:: StableHashingContext <' __ctx>, hasher: & mut :: rustc_data_structures:: stable_hasher:: StableHasher ) {
170+ self . as_u32( ) . hash_stable( hcx, hasher)
171+ }
172+ }
173+ }
174+ } else if stable_hash_generic || stable_hash_no_context {
175+ quote ! {
176+ #gate_rustc_only
177+ impl <CTX > :: rustc_data_structures:: stable_hasher:: HashStable <CTX > for #name {
178+ fn hash_stable( & self , hcx: & mut CTX , hasher: & mut :: rustc_data_structures:: stable_hasher:: StableHasher ) {
179+ self . as_u32( ) . hash_stable( hcx, hasher)
180+ }
181+ }
142182 }
143183 } else {
144184 quote ! { }
@@ -154,11 +194,13 @@ impl Parse for Newtype {
154194
155195 Ok ( Self ( quote ! {
156196 #( #attrs) *
157- #[ derive( Clone , Copy , PartialEq , Eq , Hash , #( #derive_paths) , * ) ]
158- #[ cfg_attr( #gate_rustc_only_cfg, rustc_layout_scalar_valid_range_end( #max) ) ]
197+ #[ derive( Clone , Copy ) ]
159198 #[ cfg_attr( #gate_rustc_only_cfg, rustc_pass_by_value) ]
160199 #vis struct #name {
200+ #[ cfg( not( #gate_rustc_only_cfg) ) ]
161201 private_use_as_methods_instead: u32 ,
202+ #[ cfg( #gate_rustc_only_cfg) ]
203+ private_use_as_methods_instead: pattern_type!( u32 is 0 ..=#max) ,
162204 }
163205
164206 #( #consts) *
@@ -226,7 +268,7 @@ impl Parse for Newtype {
226268 /// Prefer using `from_u32`.
227269 #[ inline]
228270 #vis const unsafe fn from_u32_unchecked( value: u32 ) -> Self {
229- Self { private_use_as_methods_instead: value }
271+ Self { private_use_as_methods_instead: unsafe { std :: mem :: transmute ( value) } }
230272 }
231273
232274 /// Extracts the value of this index as a `usize`.
@@ -238,7 +280,7 @@ impl Parse for Newtype {
238280 /// Extracts the value of this index as a `u32`.
239281 #[ inline]
240282 #vis const fn as_u32( self ) -> u32 {
241- self . private_use_as_methods_instead
283+ unsafe { std :: mem :: transmute ( self . private_use_as_methods_instead) }
242284 }
243285
244286 /// Extracts the value of this index as a `usize`.
@@ -278,6 +320,8 @@ impl Parse for Newtype {
278320
279321 #step
280322
323+ #hash_stable
324+
281325 impl From <#name> for u32 {
282326 #[ inline]
283327 fn from( v: #name) -> u32 {
@@ -306,6 +350,23 @@ impl Parse for Newtype {
306350 }
307351 }
308352
353+ impl :: std:: cmp:: Eq for #name { }
354+
355+ impl :: std:: cmp:: PartialEq for #name {
356+ fn eq( & self , other: & Self ) -> bool {
357+ self . as_u32( ) . eq( & other. as_u32( ) )
358+ }
359+ }
360+
361+ #gate_rustc_only
362+ impl :: std:: marker:: StructuralPartialEq for #name { }
363+
364+ impl :: std:: hash:: Hash for #name {
365+ fn hash<H : :: std:: hash:: Hasher >( & self , state: & mut H ) {
366+ self . as_u32( ) . hash( state)
367+ }
368+ }
369+
309370 #encodable_impls
310371 #debug_impl
311372 } ) )
0 commit comments