rust-lang / rust-lang/rust

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

Open
#122,301 17 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-const-generics C-discussion I-lang-radar T-lang
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

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 https://github.com/rust-lang/rfcs/issues/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)
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproducer in this issue, then read RFC issue #3582, the referenced rust-lang/rust PR #112879 discussion, and issue #107503. Done means the guarantees around monomorphized constants and callees, including excluded branches, are clarified and documented with the intended cargo check/build behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.