Skip to content

What are the guarantees around which constants (and callees) in a function get monomorphized? #122301

Open
@the8472

Description

@the8472

Currently this compiles in stable.

struct Foo<T, const N: usize>(T);

impl<T, const N: usize> Foo<T, N> {
    const BAR: () = if N == 0 {
        panic!()
    };
}

struct Invoke<T, const N: usize>(T);

impl<T, const N: usize> Invoke<T, N> {
    const FUN: fn() = if N != 0 {
        || Foo::<T, N>::BAR
    } else {
        || {}
    };
}

fn main() {
    Invoke::<(), 0>::FUN();
}

This is a useful property¹ but if the panic path were not completely excluded this could lead to monomorphization-time errors which are undesirable since they only show up in cargo build and not in cargo check. But not as undesirable as #107503 where the errors are optimization-dependent.

Still, @RalfJung indicated that the current behavior might not be intentional so I'm filing this issue for clarification.

(Also see rust-lang/rfcs#3582 for more discussion of the same question.)


¹actual use could look like this:

// library-provided function:

/// Fails to compile if N == 0
fn chunks<const N: usize>(foo: Foo) -> &[[u8; N]] {
   const {
       assert!(N > 0)!
   }

   todo!()
}

// user-code, generic over all N
fn library_user_code<const N: usize>(foo: Foo) ->  {

   // this could be generated by a `const_if!()` macro or use inline const blocks
   struct ConstIf< const N: usize>;

   impl<const N: usize> ConstIf<N> {
     const FUN: fn() = if N != 0 {
         |foo| chunks::<N>(foo)
     } else {
         |foo| { /* fallback code here */ }
     };
   }
   
   ConstIf::<N>::FUN(foo)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)C-discussionCategory: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions