Skip to content

Add const getter for Copy types #126

@helgoboss

Description

@helgoboss

I want to propose optionally adding a const getter method to newtypes that wrap a Copy value.

Motivation

Given the following newtype:

/// Represents a tempo measured in beats per minute.
#[nutype(
    new_unchecked,
    validate(finite, greater_or_equal = 1.0, less_or_equal = 960.0),
    derive(
        Copy,
        Clone,
        Eq,
        PartialEq,
        Ord,
        PartialOrd,
        Debug,
        Default,
        Display,
        FromStr,
        Into,
        TryFrom
    ),
    default = 1.0
)]
pub struct Bpm(f64);

impl Bpm {
    /// The minimum possible value.
    pub const MIN: Self = unsafe { Self::new_unchecked(1.0) };

    /// The maximum possible value.
    pub const MAX: Self = unsafe { Self::new_unchecked(960.0) };
}

(Side note: Being able to call Self::new_unchecked from a const context needs this)

Now I would like to do things like this:

const BPM_SPAN: f64 = Bpm::MAX.into_inner() - Bpm::MIN.into_inner();

Above code is currently not possible because into_inner() is not const:

            pub fn into_inner(self) -> #inner_type {
                self.0
            }

Thoughts

Just making it const in general unfortunately doesn't work. Because it takes self by value (which is the correct choice for a method of this name). And that fails to compile if the wrapped type is heap-allocated ("the destructor for this type cannot be evaluated in constant functions").

I see 2 possibilities.

a) Making into_inner const, but only for Copy types

            pub const fn into_inner(self) -> #inner_type {
                self.0
            }

b) Introducing a separate const get method, but only for Copy types

            pub const fn get(self) -> #inner_type {
                self.0
            }

Personally, I prefer b. There are quite many examples in the standard library where a wrapper exposes its wrapped Copy value in a get method, so it appears to be a good practice. But ultimately I don't mind.

Do you think it's somehow possible to do a or b? Just for Copy types? And if yes, would you consider it? I would be happy to write a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions