Skip to content

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

Open
@the8472

Description

@the8472
Member

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)
}

Activity

added
T-langRelevant to the language team
A-const-genericsArea: const generics (parameters and arguments)
C-discussionCategory: Discussion or questions that doesn't represent real issues.
on Mar 10, 2024
added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Mar 10, 2024
RalfJung

RalfJung commented on Mar 10, 2024

@RalfJung
Member

Cc @rust-lang/wg-const-eval

Ultimately this is a t-lang question though so might need a t-lang design meeting or some such thing.

RalfJung

RalfJung commented on Mar 10, 2024

@RalfJung
Member

In fact you don't need closures, this builds as well:

struct S<T>(T);
impl<T> S<T> {
    const C: () = panic!();
}

const fn bar<T>() { S::<T>::C }

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

impl<T, const N: usize> Invoke<T, N> {
    const FUN: () = if N != 0 {
        bar::<T>() // not called for N == 0, and hence not monomorphized
    } else {
        ()
    };
}

fn main() {
    let _val = Invoke::<(), 0>::FUN;
}
RalfJung

RalfJung commented on Mar 10, 2024

@RalfJung
Member

This is a useful property

Your example doesn't quite seem to have the right shape for that use-case; could you flesh out the example a bit more to make this more clear?

the8472

the8472 commented on Mar 10, 2024

@the8472
MemberAuthor

could you flesh out the example a bit more

Added it to the top post.

RalfJung

RalfJung commented on Mar 10, 2024

@RalfJung
Member

Makes sense, thanks!

Note that without generic_const_exprs such a const_if! macro will be very limited.

removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Mar 10, 2024
added a commit that references this issue on Mar 15, 2024

add test for rust-lang#122301 to cover behavior that's on stable

added a commit that references this issue on Mar 17, 2024

add test for rust-lang#122301 to cover behavior that's on stable

added a commit that references this issue on Mar 17, 2024

Rollup merge of rust-lang#122572 - the8472:test-const-deadness, r=Ral…

ce707de

32 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @RalfJung@the8472@traviscross@clubby789@scottmcm

        Issue actions

          What are the guarantees around which constants (and callees) in a function get monomorphized? · Issue #122301 · rust-lang/rust