Skip to content

Constancy broken by tuple indexing (newtypes may unwrap in the runtime) #19244

Closed
@mnemnion

Description

@mnemnion

I'm translating a VM, and make heavy use of struct NewType(u32) as an idiom to separate the logical uses of numbers. I was advised to use new_type.0 to unwrap/dereference the value of such a type.

Since the type is known at compile time, it is at least possible to infer the type of a new_type.0 statically. It seems this may not be happening, or at least not consistently.

Here is the breaking code:

#![feature(tuple_indexing)]

use std::default::Default;

const WORKS_CONST: uint = 23 ;
const ALSO_WORKS_CONST: uint = WORKS_CONST + 5 ;

struct Wrapper(uint);
const WRAPPED_CONST: Wrapper = Wrapper(42) ;
const BAD_CONST: uint = WRAPPED_CONST.0 ;

struct ConstCheck {
    broken_array: [int, ..BAD_CONST],
    works_array: [int, ..ALSO_WORKS_CONST],
}

fn main() {
    println!("Wrapped Constant is: {}", BAD_CONST);
}

The definition of broken_array breaks the compiler, with the following message:

/../src/main.rs:13:19: 13:37 error: expected constant expr for array length: unsupported constant expr
/../src/main.rs:13     broken_array: [int, ..BAD_CONST],
                                                                            ^~~~~~~~~~~~~~~~~~
Could not compile `rusty_sandbox`.

If that line is commented out, the code compiles, creating BAD_CONST and printing the correct value.

I infer from this that new_type.0 unwrapping is happening in the runtime. This is going to be terrible for my VMs performance. It would seem that a major use case for newtypes would be wrapping raw numbers for math-heavy applications, so your Kilos don't mix with your Meters.

I'm brand new here, so take this for the naive perspective that it is, but it seems to me the fix would involve reifying newtypes, at least somewhat. A type that's a simple synonym should disappear completely at compile time, with the syntax enforcing correct use. It's my old Perl side talking, I expect, but syntax such as newtype.$ for self could force the compiler to try and unwrap a single value from the tuple and fail if the struct isn't a single-field tuple.

I do feel that the code provided should compile. Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions