Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use NonZero<T> instead of NonZeroT #13019

Open
sorairolake opened this issue Jun 29, 2024 · 4 comments
Open

Use NonZero<T> instead of NonZeroT #13019

sorairolake opened this issue Jun 29, 2024 · 4 comments
Assignees
Labels
A-lint Area: New lints

Comments

@sorairolake
Copy link

sorairolake commented Jun 29, 2024

What it does

NonZero<T> stabilized with Rust 1.79.0. This allows NonZeroI32 to be written as NonZero<i32>.

Advantage

  • More readable.
  • Reduce imports.
  • Can specify aliases for primitive integer types (e.g., NonZero<c_int>).

Drawbacks

MSRV is 1.79.0.

Example

let x = NonZeroI32::new(42).unwrap();

Could be written as:

let x = NonZero::<i32>::new(42).unwrap();
@sorairolake sorairolake added the A-lint Area: New lints label Jun 29, 2024
@TennyZhuang
Copy link
Contributor

@rustbot claim

@y21
Copy link
Member

y21 commented Jul 3, 2024

I'm struggling to see the advantage here.

NonZero being generic is definitely cool and it's nice that you can use c_int, but I don't see how this helps users when they've already got a NonZeroI32 and are only interested in that.
I don't think there's any readability difference or that it reduces imports when you specifically need NonZeroI32 and that only in a file; you either import NonZero or you import NonZeroI32.

Can you provide a use case for where this lint would have helped?

@sorairolake
Copy link
Author

@y21 I think it's useful when you need multiple types.

use core::num::{NonZeroI32, NonZeroU32, NonZeroU8};

let x = NonZeroU8::new(42).unwrap();
let x = NonZeroI32::new(42).unwrap();
let x = NonZeroU32::new(42).unwrap();

Could be written as:

use core::num::NonZero;

let x = NonZero::<u8>::new(42).unwrap();
let x = NonZero::<i32>::new(42).unwrap();
let x = NonZero::<u32>::new(42).unwrap();

@leonardo-m
Copy link

use core::num::NonZero;

let x = NonZero::::new(42).unwrap();
let x = NonZero::::new(42).unwrap();
let x = NonZero::::new(42).unwrap();

An alternative version is:

#![allow(unused_variables)]
#![feature(const_option)]

use core::num::NonZero;

fn main() {
    let x1 = const { NonZero::new(42_u8).unwrap() };
    let x2 = const { NonZero::new(42_i32).unwrap() };
    let x = const { NonZero::new(42_u32).unwrap() };
}

(By the way, sometimes I'd like a unwrap-less constructor for NonZero).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints
Projects
None yet
Development

No branches or pull requests

4 participants