@@ -56,6 +56,33 @@ fn type_replacements(type_: &Type, error_exprs: &[Expr]) -> impl Iterator<Item =
5656 ]
5757 } else if path_is_nonzero_unsigned ( path) {
5858 vec ! [ quote! { 1 . try_into( ) . unwrap( ) } ]
59+ } else if let Some ( inner_type) = match_first_type_arg ( path, "NonZero" ) {
60+ // NonZero<T> generic form (stabilized in Rust 1.79)
61+ if let Type :: Path ( syn:: TypePath {
62+ path : inner_path, ..
63+ } ) = inner_type
64+ {
65+ if path_is_unsigned ( inner_path) {
66+ vec ! [ quote! { 1 . try_into( ) . unwrap( ) } ]
67+ } else if path_is_signed ( inner_path) {
68+ vec ! [
69+ quote! { 1 . try_into( ) . unwrap( ) } ,
70+ quote! { ( -1 ) . try_into( ) . unwrap( ) } ,
71+ ]
72+ } else {
73+ // Unknown T, assume it could be signed
74+ vec ! [
75+ quote! { 1 . try_into( ) . unwrap( ) } ,
76+ quote! { ( -1 ) . try_into( ) . unwrap( ) } ,
77+ ]
78+ }
79+ } else {
80+ // T is not a simple path, assume it could be signed
81+ vec ! [
82+ quote! { 1 . try_into( ) . unwrap( ) } ,
83+ quote! { ( -1 ) . try_into( ) . unwrap( ) } ,
84+ ]
85+ }
5986 } else if path_is_float ( path) {
6087 vec ! [ quote! { 0.0 } , quote! { 1.0 } , quote! { -1.0 } ]
6188 } else if path_ends_with ( path, "Result" ) {
@@ -393,7 +420,6 @@ fn path_is_nonzero_signed(path: &Path) -> bool {
393420}
394421
395422fn path_is_nonzero_unsigned ( path : & Path ) -> bool {
396- // TODO: Also NonZero<usize> etc.
397423 if let Some ( l) = path. segments . last ( ) . map ( |p| p. ident . to_string ( ) ) {
398424 matches ! (
399425 l. as_str( ) ,
@@ -494,6 +520,58 @@ mod test {
494520 ) ;
495521 }
496522
523+ #[ test]
524+ fn nonzero_generic_unsigned_replacements ( ) {
525+ check_replacements (
526+ & parse_quote ! { -> NonZero <u32 > } ,
527+ & [ ] ,
528+ & [ "1.try_into().unwrap()" ] ,
529+ ) ;
530+
531+ check_replacements (
532+ & parse_quote ! { -> NonZero <usize > } ,
533+ & [ ] ,
534+ & [ "1.try_into().unwrap()" ] ,
535+ ) ;
536+
537+ check_replacements (
538+ & parse_quote ! { -> std:: num:: NonZero <u8 > } ,
539+ & [ ] ,
540+ & [ "1.try_into().unwrap()" ] ,
541+ ) ;
542+ }
543+
544+ #[ test]
545+ fn nonzero_generic_signed_replacements ( ) {
546+ check_replacements (
547+ & parse_quote ! { -> NonZero <i32 > } ,
548+ & [ ] ,
549+ & [ "1.try_into().unwrap()" , "(-1).try_into().unwrap()" ] ,
550+ ) ;
551+
552+ check_replacements (
553+ & parse_quote ! { -> NonZero <isize > } ,
554+ & [ ] ,
555+ & [ "1.try_into().unwrap()" , "(-1).try_into().unwrap()" ] ,
556+ ) ;
557+
558+ check_replacements (
559+ & parse_quote ! { -> std:: num:: NonZero <i64 > } ,
560+ & [ ] ,
561+ & [ "1.try_into().unwrap()" , "(-1).try_into().unwrap()" ] ,
562+ ) ;
563+ }
564+
565+ #[ test]
566+ fn nonzero_generic_unknown_type_replacements ( ) {
567+ // When T is not a recognized integer type, assume it could be signed.
568+ check_replacements (
569+ & parse_quote ! { -> NonZero <T > } ,
570+ & [ ] ,
571+ & [ "1.try_into().unwrap()" , "(-1).try_into().unwrap()" ] ,
572+ ) ;
573+ }
574+
497575 #[ test]
498576 fn unit_replacement ( ) {
499577 check_replacements ( & parse_quote ! { -> ( ) } , & [ ] , & [ "()" ] ) ;
0 commit comments