Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

gccrs#4704: Add range_inclusive_new

Link: Rust-GCC/gccrs#4704

Definition:

#![allow(unused)]
fn main() {
#[lang = "RangeInclusive"]
#[doc(alias = "..=")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "inclusive_range", since = "1.26.0")]
pub struct RangeInclusive<Idx> {
    pub(crate) start: Idx,
    pub(crate) end: Idx,

    pub(crate) exhausted: bool,
}

impl<Idx> RangeInclusive<Idx> {
    #[lang = "range_inclusive_new"]
    #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
    #[inline]
    #[rustc_promotable]
    #[rustc_const_stable(feature = "const_range_new", since = "1.32.0")]
    pub const fn new(start: Idx, end: Idx) -> Self {
        Self { start, end, exhausted: false }
    }
}
}

Objective

This patch introduces the range_inclusive_new lang item to the compiler.

Changes Made

When the compiler encounters an inclusive range expression (..=), it now correctly desugars the operation into a function call targeting this lang item, rather than lowering it directly into a static struct.

As a result, the unnecessary HIR::RangeFromToInclExpr class and its associated visitors were removed across the compiler. Since inclusive ranges are now directly desugared into a CallExpr targeting range_inclusive_new during the AST -> HIR lowering phase, the old HIR node and its codegen/typecheck implementations became dead code and were cleaned up.

Why is this needed for alloc?

The alloc crate relies heavily on inclusive ranges for indexing, slicing, and iteration over heap-allocated collections like Vec and String.

Test Case

#![allow(unused)]
fn main() {
fn foo() {
    let _ = 0..=23;
    //      ^^^^^^ this will lower to this ─────┐
    // let _ = RangeInclusive::new(0, 23); <────┘
}
}