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

Add const initializers #181

Open
XAMPPRocky opened this issue Dec 17, 2020 · 9 comments
Open

Add const initializers #181

XAMPPRocky opened this issue Dec 17, 2020 · 9 comments

Comments

@XAMPPRocky
Copy link
Contributor

Hello, I've been using num-bigint for rasn. I've been working on adding static information about ASN.1's constrained types, and one of things I need for this is having a const Range<BigInt> for allowing users to be able to specify arbitrary integer ranges for their type, however I was surprised that there is no const initializer for BigInt.

It would be nice if new was made const so that you could provide BigInt types in a const context like you can with builtin integers.

@cuviper
Copy link
Member

cuviper commented Dec 18, 2020

Only zero() could be a const constructor, because anything else requires an allocation. Even that would have to be a new inherent method, not Zero, because trait implementations can't be const yet AFAIK.

@hjiayz
Copy link

hjiayz commented Nov 25, 2021

https://crates.io/crates/const_num_bigint

@cuviper
Copy link
Member

cuviper commented Dec 3, 2021

@hjiayz -- your use of transmute is unsound. The layout of repr(Rust) types is not specified, and may not be the same even for similarly shaped types. Even if they did have a specified layout, you're relying on private implementation details that could change.

@cuviper
Copy link
Member

cuviper commented Dec 3, 2021

The current proposal about const allocations is here: rust-lang/lang-team#129

@hjiayz
Copy link

hjiayz commented Dec 5, 2021

@cuviper
need pub fn biguint_from_vec(digits: Vec<usize>) -> BigUint
like
#https://github.com/rust-num/num-bigint/issues/181#issuecomment-985698108
but this is pub(crate)

@cuviper
Copy link
Member

cuviper commented Dec 5, 2021

No, that takes Vec<BigDigit>, and BigDigit is intentionally an internal implementation detail, subject to change. Right now it's either u32 or u64 in a way that does correspond to usize, but it used to just be u32, and in the future we might yet make different decisions if it makes sense for a particular target.

Even if we made that public, it's also invalid to convert your ConstVec<T> to Vec<T>.

https://doc.rust-lang.org/std/vec/struct.Vec.html#guarantees

Most fundamentally, Vec is and always will be a (pointer, capacity, length) triplet. No more, no less. The order of these fields is completely unspecified, and you should use the appropriate methods to modify these. The pointer will never be null, so this type is null-pointer-optimized.

@hjiayz
Copy link

hjiayz commented Dec 5, 2021

@cuviper
convert &'static ConstVec<T> to &'static Vec<T> by Vec::from_raw_parts
and convert &'static ConstBigUint to &'static BigUint by Vec::from_raw_parts and biguint_from_vec

@cuviper
Copy link
Member

cuviper commented Dec 5, 2021

Vec::from_raw_parts is not const, only the empty Vec::new.

@hjiayz
Copy link

hjiayz commented Dec 6, 2021

@cuviper

use std::mem::ManuallyDrop;

#[derive(Debug)]
struct ConstFoo(&'static [u8]);

#[derive(Debug)]
struct Foo(Vec<u8>);

impl ConstFoo {
    #[inline]
    pub fn get(&'static self)->ManuallyDrop<Foo>{
        ManuallyDrop::new(unsafe{Foo(
            Vec::from_raw_parts(self.0.as_ptr() as *mut u8,self.0.len(),self.0.len())
        )})
    }
    
}

const FOO : ConstFoo = ConstFoo(&[1,2,3,4,5,6]);

fn print_foo_ref(foo:&Foo){
    println!("{:?}",foo);
}

fn print_foo(){
    print_foo_ref(&*FOO.get());
}

fn main(){
    print_foo();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants