@@ -43,7 +43,7 @@ impl Parse for MhAttr {
4343/// Attributes of the top-level derive.
4444#[ derive( Debug ) ]
4545enum DeriveAttr {
46- AllocSize ( utils:: Attr < kw:: alloc_size , syn:: Type > ) ,
46+ AllocSize ( utils:: Attr < kw:: alloc_size , syn:: LitInt > ) ,
4747 NoAllocSizeErrors ( kw:: no_alloc_size_errors ) ,
4848}
4949
@@ -161,7 +161,7 @@ impl<'a> From<&'a VariantInfo<'a>> for Hash {
161161/// Parse top-level enum [#mh()] attributes.
162162///
163163/// Returns the `alloc_size` and whether errors regarding to `alloc_size` should be reported or not.
164- fn parse_code_enum_attrs ( ast : & syn:: DeriveInput ) -> ( syn:: Type , bool ) {
164+ fn parse_code_enum_attrs ( ast : & syn:: DeriveInput ) -> ( syn:: LitInt , bool ) {
165165 let mut alloc_size = None ;
166166 let mut no_alloc_size_errors = false ;
167167
@@ -226,33 +226,12 @@ fn error_code_duplicates(hashes: &[Hash]) {
226226#[ derive( Debug ) ]
227227struct ParseError ( proc_macro2:: Span ) ;
228228
229- /// Parse a path containing a `typenum` unsigned integer (e.g. `U64`) into a u64
230- fn parse_unsigned_typenum ( typenum_path : & syn:: Type ) -> Result < u64 , ParseError > {
231- match typenum_path {
232- syn:: Type :: Path ( type_path) => match type_path. path . segments . last ( ) {
233- Some ( path_segment) => {
234- let typenum_ident = & path_segment. ident ;
235- let typenum = typenum_ident. to_string ( ) ;
236- match typenum. as_str ( ) . split_at ( 1 ) {
237- ( "U" , byte_size) => byte_size
238- . parse :: < u64 > ( )
239- . map_err ( |_| ParseError ( typenum_ident. span ( ) ) ) ,
240- _ => Err ( ParseError ( typenum_ident. span ( ) ) ) ,
241- }
242- }
243- None => Err ( ParseError ( type_path. path . span ( ) ) ) ,
244- } ,
245- _ => Err ( ParseError ( typenum_path. span ( ) ) ) ,
246- }
247- }
248-
249229/// Returns the max size as u64.
250230///
251- /// Emits an error if the `#mh(alloc_size)` attribute doesn't contain a valid unsigned integer
252- /// `typenum`.
253- fn parse_alloc_size_attribute ( alloc_size : & syn:: Type ) -> u64 {
254- parse_unsigned_typenum ( & alloc_size) . unwrap_or_else ( |_| {
255- let msg = "`alloc_size` attribute must be a `typenum`, e.g. #[mh(alloc_size = U64)]" ;
231+ /// Emits an error if the `#mh(alloc_size)` attribute doesn't contain a valid unsigned integer.
232+ fn parse_alloc_size_attribute ( alloc_size : & syn:: LitInt ) -> u64 {
233+ alloc_size. base10_parse ( ) . unwrap_or_else ( |_| {
234+ let msg = "`alloc_size` attribute must be an integer, e.g. #[mh(alloc_size = 64)]" ;
256235 #[ cfg( test) ]
257236 panic ! ( msg) ;
258237 #[ cfg( not( test) ) ]
@@ -261,38 +240,39 @@ fn parse_alloc_size_attribute(alloc_size: &syn::Type) -> u64 {
261240}
262241
263242/// Return a warning/error if the specified alloc_size is smaller than the biggest digest
264- fn error_alloc_size ( hashes : & [ Hash ] , expected_alloc_size_type : & syn:: Type ) {
243+ fn error_alloc_size ( hashes : & [ Hash ] , expected_alloc_size_type : & syn:: LitInt ) {
265244 let expected_alloc_size = parse_alloc_size_attribute ( expected_alloc_size_type) ;
266245
267246 let maybe_error: Result < ( ) , ParseError > = hashes
268247 . iter ( )
269248 . try_for_each ( |hash| {
270- // The digest type must have a size parameter of the shape `U<number>` , else we error.
249+ // The digest type must have an integer as size parameter , else we error.
271250 match hash. digest . segments . last ( ) {
272251 Some ( path_segment) => match & path_segment. arguments {
273252 syn:: PathArguments :: AngleBracketed ( arguments) => match arguments. args . last ( ) {
274- Some ( syn:: GenericArgument :: Type ( path) ) => {
275- match parse_unsigned_typenum ( & path) {
276- Ok ( max_digest_size) => {
277- if max_digest_size > expected_alloc_size {
278- let msg = format ! ( "The `#mh(alloc_size) attribute must be bigger than the maximum defined digest size (U{})" ,
279- max_digest_size) ;
280- #[ cfg( test) ]
281- panic ! ( msg) ;
282- #[ cfg( not( test) ) ]
283- {
284- let digest = & hash. digest . to_token_stream ( ) . to_string ( ) . replace ( " " , "" ) ;
285- let line = & hash. digest . span ( ) . start ( ) . line ;
286- proc_macro_error:: emit_error!(
287- & expected_alloc_size_type, msg;
288- note = "the bigger digest is `{}` at line {}" , digest, line;
289- ) ;
290- }
291- }
292- Ok ( ( ) )
293- } ,
294- Err ( err) => Err ( err) ,
295- }
253+ Some ( syn:: GenericArgument :: Const ( syn:: Expr :: Lit ( expr_lit) ) ) => match & expr_lit. lit {
254+ syn:: Lit :: Int ( lit_int) => match lit_int. base10_parse :: < u64 > ( ) {
255+ Ok ( max_digest_size) => {
256+ if max_digest_size > expected_alloc_size {
257+ let msg = format ! ( "The `#mh(alloc_size) attribute must be bigger than the maximum defined digest size ({})" ,
258+ max_digest_size) ;
259+ #[ cfg( test) ]
260+ panic ! ( msg) ;
261+ #[ cfg( not( test) ) ]
262+ {
263+ let digest = & hash. digest . to_token_stream ( ) . to_string ( ) . replace ( " " , "" ) ;
264+ let line = & hash. digest . span ( ) . start ( ) . line ;
265+ proc_macro_error:: emit_error!(
266+ & expected_alloc_size_type, msg;
267+ note = "the bigger digest is `{}` at line {}" , digest, line;
268+ ) ;
269+ }
270+ }
271+ Ok ( ( ) )
272+ } ,
273+ _ => Err ( ParseError ( lit_int. span ( ) ) ) ,
274+ } ,
275+ _ => Err ( ParseError ( expr_lit. span ( ) ) ) ,
296276 } ,
297277 _ => Err ( ParseError ( arguments. args . span ( ) ) ) ,
298278 } ,
@@ -338,9 +318,7 @@ pub fn multihash(s: Structure) -> TokenStream {
338318 /// A Multihash with the same allocated size as the Multihashes produces by this derive.
339319 pub type Multihash = #mh_crate:: MultihashGeneric :: <#alloc_size>;
340320
341- impl #mh_crate:: MultihashDigest for #code_enum {
342- type AllocSize = #alloc_size;
343-
321+ impl #mh_crate:: MultihashDigest <#alloc_size> for #code_enum {
344322 fn digest( & self , input: & [ u8 ] ) -> Multihash {
345323 use #mh_crate:: Hasher ;
346324 match self {
@@ -349,10 +327,9 @@ pub fn multihash(s: Structure) -> TokenStream {
349327 }
350328 }
351329
352- fn multihash_from_digest<' a, S , D >( digest: & ' a D ) -> Multihash
330+ fn multihash_from_digest<' a, D >( digest: & ' a D ) -> Multihash
353331 where
354- S : #mh_crate:: Size ,
355- D : #mh_crate:: Digest <S >,
332+ D : #mh_crate:: Digest <#alloc_size>,
356333 Self : From <& ' a D >,
357334 {
358335 let code = Self :: from( & digest) ;
0 commit comments