Skip to content

Tracking Issue for inline const patterns (RFC 2920) #76001

Closed as not planned
Closed as not planned

Description

@nikomatsakis

This is a tracking issue for the RFC "Inline const expressions and patterns" (rust-lang/rfcs#2920).
Const expressions have been stabilized, but patterns have not
The feature gate for the issue is #![feature(inline_const_pat)].

This was originally a tracking issue for const blocks in both expression and pattern position. Inline const expressions have been stabilized in #104087 while patterns are still unstable.

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Unresolved Questions

Implementation history

Activity

  1. added
    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
    T-langRelevant to the language team
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)
    F-inline_constInline constants (aka: const blocks, const expressions, anonymous constants)
    on Aug 27, 2020
  2. jhpratt commented on Aug 28, 2020

    @jhpratt
    Member

    With regard to the lint, is there any semantic difference between the two? Intuitively I would expect them to behave identically (static lifetimes).

  3. RalfJung commented on Aug 29, 2020

    @RalfJung
    Member

    They behave identically. The point of the lint is to have a single "idiomatic" form.

    Naming: "inline const", "const block", or "anonymous const"?

    The issue title calls it "const expressons" so maybe that should also be on the list.

    I prefer "inline const" because it emphasizes that this is a totally separate body of code that is just written inline. That's much more like a closure than normal blocks.


    Also, is anyone up for implementing this? (I can't even mentor this I am afraid, this affects surface-level syntax and MIR building which is way outside what I know.^^)

  4. Lokathor commented on Aug 29, 2020

    @Lokathor
    Contributor

    "const block" is clearly correct.

    it matches "unsafe block" that way.

  5. RalfJung commented on Aug 29, 2020

    @RalfJung
    Member

    That false parallel with "unsafe block" is exactly why it is not correct. An unsafe block inherits scope, execution environment, everything from its parent block. An inline const does not.

  6. ecstatic-morse commented on Aug 29, 2020

    @ecstatic-morse
    Contributor

    I'm happy to mentor, although by no means am I an expert on all the parts of the compiler you'll need to touch. There's already an AnonConst type in the AST and the HIR that should for the most part have the same rules as an inline const (e.g. no outside generic parameters), which should make the lowering part of this pretty easy.

    If no one volunteers in the next few weeks, I'll try to set aside a day or two to implement this. However, I'm mostly in maintenance/review mode as far as Rust is concerned.

  7. workingjubilee commented on Sep 1, 2020

    @workingjubilee
    Member

    Does const { } differ from normal block expressions, however?
    I think either "inline const" or "const expression" should be favored. Everyone's going to call it a constexpr anyways because of C++ user bleedover, and I don't think it's worth offering that much pushback this time. :^)

    Hm... I need to fix my computer still. Guess I have a good reason today.

  8. memoryruins commented on Sep 1, 2020

    @memoryruins
    Contributor

    Does const { } differ from normal block expressions, however?

    const {} does not inherit the same scopes as block expressions do.

    Everyone's going to call it a constexpr anyways because of C++

    It can be a useful comparison when introducing C++ users to Rust's const and const fn, yet I have not seen most users conflate them. Additionally, C++ does not have constexpr { ... }.

    I don't think it's worth offering that much pushback this time.

    There are no mentions of constexpr or C++ on this issue before or the RFC. I find it unproductive to label it as pushback from that. The concerns about naming are mentioned in the RFC https://rust-lang.github.io/rfcs/2920-inline-const.html and the comments.

  9. workingjubilee commented on Sep 1, 2020

    @workingjubilee
  10. memoryruins commented on Sep 1, 2020

    @memoryruins
  11. 138 remaining items

  12. added 2 commits that reference this issue on Apr 1, 2025
  13. added a commit that references this issue on Apr 1, 2025
  14. zeroflaw commented on Apr 2, 2025

    @zeroflaw

    Anyone that is refactoring today, another way to get a const inline without the inline_const_pat feature is:

    fn main() {
        let x: usize = 1;
        match x {
             0 => println!("x is zero"),
             const{0+1}=> println!("x is one"),
             _ => println!("x is neither 0 or 1")
        }
    }

    becomes:

    fn main() {
        let x: usize = 1;
        match x {
             0 => println!("x is zero"),
             v if v == const{0+1}=> println!("x is one"),
             _ => println!("x is neither 0 or 1")
         }
    }

    The downside of the above is you can't "~const" PartialEq on a non-primitive type, like you could before. So you might need to implement a const_eq function so you can do:

    v if v.const_eq(const { &Self::const_zero() }) => println!("x is zero"),

    Hope this helps someone.

  15. Qix- commented on Apr 3, 2025

    @Qix-

    The downside to that is that you cannot generalize that to an expression form.

    const SOME_KEY = key!("...");
    
    match SOME_KEY {
        key!("...") => { ... },
        key!("???") => { ... },
    }

    There's no way to write key!() in a way where that's usable in all expression contexts without this feature :|

  16. RalfJung commented on Apr 3, 2025

    @RalfJung
    Member

    The LHS of => is not an expression, it's a pattern. So what you are asking is for the same term to work both as a pattern and as an expression.

    Yeah that does not work without const patterns, true.

  17. added a commit that references this issue on Apr 3, 2025
  18. added a commit that references this issue on Apr 3, 2025
  19. fmease commented on Dec 6, 2025

    @fmease
    Member

    The downside to that is that you cannot generalize that to an expression form.

    const SOME_KEY = key!("...");
    
    match SOME_KEY {
        key!("...") => { ... },
        key!("???") => { ... },
    }

    There's no way to write key!() in a way where that's usable in all expression contexts without this feature :|

    @Qix-, there is, thanks to adt const params. Well, the example below actually requires unsized const params for the &str parameter whose future is unclear but in most other cases you wouldn't need it. I'm using generic const items (GCI, #113521) for convenience but they're not strictly necessary.

    #![feature(const_trait_impl, const_cmp)]
    #![feature(adt_const_params, unsized_const_params)]
    #![feature(generic_const_items)]
    #![expect(incomplete_features, reason = "generic_const_items,unsized_const_params")]
    
    const KEY_OF<const STR: &'static str>: i32 = match STR {
        "..." => 0,
        "???" => 1,
        _ => panic!("unsupported"),
    };
    
    macro_rules! key { ($str:expr) => { KEY_OF::<{ $str }> } }
    
    const SOME_KEY: i32 = key!("...");
    
    const _: () = match SOME_KEY {
        key!("...") => {}
        key!("???") => {}
        _ => panic!("unsupported"),
    };

    It's more restricted, of course, but at least there is a way to express basic forms of this.

    Without GCI:

    #![feature(const_trait_impl, const_cmp)]
    #![feature(adt_const_params, unsized_const_params)]
    #![expect(incomplete_features, reason = "unsized_const_params")]
    
    struct Owner<const STR: &'static str>;
    
    impl<const STR: &'static str> Owner<STR> {
        const KEY_OF: i32 = match STR {
            "..." => 0,
            "???" => 1,
            _ => panic!("unsupported"),
        };
    }
    
    macro_rules! key { ($str:expr) => { Owner::<{ $str }>::KEY_OF } }
    
    // ...
  20. lcnr commented on Feb 14, 2026

    @lcnr
    Contributor

    Inline const patterns have been entirely removed from the compiler due to significant technical limitations. readding them should require a separate proposal. Closing

  21. added
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    on Feb 14, 2026
  22. added a commit that references this issue on Feb 27, 2026
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-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-inline_constInline constants (aka: const blocks, const expressions, anonymous constants)F-inline_const_pat#![feature(inline_const_pat)]S-tracking-needs-summaryStatus: It's hard to tell what's been done and what hasn't! Someone should do some investigation.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-typesRelevant to the types 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