--- title: "Lang-docs office hours 2026-01-20" date: 2026-01-20 url: https://hackmd.io/hXAWQDOiS6eOgqV-BShWcQ --- # Lang-docs office hours 2026-01-20 People: TC, ehuss https://meet.jit.si/rust-t-lang-docs ## Unwrap more chapters #2134 https://github.com/rust-lang/reference/pull/2134 Easy. Merging. ## Rename the ".general" rules #2133 https://github.com/rust-lang/reference/pull/2133 Make sense. Rebased and merged. ## const-eval: explain the final-value-byte-provenance restriction #2138 https://github.com/rust-lang/reference/pull/2138 Decided to keep it in const-eval for now, in a separate section. Want to leave space, when doing a typed copy, we want to unintialize padding bytes in the destination. But we cannot do that right now (for perf or other reasons). We want to keep it unspecified how typed copies work. We don't want it observable. Eric doesn't understand why linkers care about this, or how they know that there are pointer fragments inside padding. The perf run (for making bytes uninit during the typed copies in consteval) was: https://github.com/rust-lang/rust/pull/149901 Opened https://github.com/rust-lang/mdBook/issues/3009 about `mdbook test --chapter` path confusion. ## fix field-less `repr(C)` enum docs #2018 https://github.com/rust-lang/reference/pull/2018 Eric: Could use a little wordsmithing, and style update (unwrapping, parentheticals, and such). Confused on layout.repr.c.enum, it says it's either int or unsigned int, but doesn't say why it would be one or the other? Dealer's choice? An example could maybe clear up why it is "crucial"? ## `cfg_select!` #2103 https://github.com/rust-lang/reference/pull/2103 Statement Item Expression Pattern Type Responded at https://github.com/rust-lang/reference/pull/2103#discussion_r2710591524 Stabilization itself is still blocked on: - unreachable_cfg_select_predicates lint https://github.com/rust-lang/rust/pull/149960 - rustfmt support https://github.com/rust-lang/rust/pull/144323 (though may want to move forward regardless) ```rust fn main() { let cfg_select! { any() => (0..=255, ..), // OK. _ => _, }: (u8, u8) = (0, 0); } ``` ```rust fn main() { let cfg_select! { any() => (x @ 0..=255, ..), // ERROR. _ => _, }: (u8, u8) = (0, 0); } ``` ```rust fn main() { let cfg_select! { any() => { (x @ 0..=255, ..) } // OK. _ => _, }: (u8, u8) = (0, 0); } ``` ### Token splitting Eric muses on the pain of how to model token splitting. Example is MacroRepSep cannot be `*=` or `+=` because it doesn't split. Splitting is somewhat hard-coded based on circumstance, and the compiler doesn't do it in that case. Wonders if the rule should be that rustc should always be splitting, and when it doesn't it's a bug. PEG section 2.1 https://bford.info/pub/lang/peg.pdf talks about how to unify lexical and cfg. ## Add a chapter on divergence #2067 https://github.com/rust-lang/reference/pull/2067 Question on LUBs: We have proposed text along the lines of: > r[expr.loop.block-labels.type] > The type of a labeled block expression is the [least upper bound] of all of the break operands, and the final operand. If the final operand is omitted, the type of the final operand defaults to the [unit type], unless the block [diverges][expr.block.diverging], in which case it is the [never type]. Is the following rule redundant: r[expr.loop.break-value.diverging] A `loop` with associated `break` expressions does not [diverge] if any of the break operands do not diverge. If all of the `break` operands diverge, then the `loop` expression also diverges. when compared with this rule: r[expr.loop.break-value.type] The type of a `loop` with associated `break` expressions is the [least upper bound] of all of the break operands. There's a difference between the type of an expression and whether it diverges, and that comes into play here. ```rust loop { break { panic!(); () }; } ``` So...do we need to have the same language for arrays? What about all other expressions? ```rust [{panic!(); ()}]; // This diverges? struct S { x: i32 } fn s() -> ! { let s = S{ // This diverges? x: panic!() }; } ``` That is an array of type `[(); 1]` that is a diverging expression. Is there a way to probe the compiler to determine if an expression diverges? If we write a function that returns type `!` and contains some expression: ```rust fn f() -> ! { //~ ERROR mismatched types { (panic!(), ()); () } // This is a diverging expression. } ``` We can say, I think, that "if this type checks, then the expression is diverging" but we can't say the inverse, "if the expression is diverging, then this type checks". We can do this, I think, by using the rules about reading from a diverging place: ```rust! struct W<T>(T); fn f() -> ! { let x = W({ // <-- This block is what we're testing. panic!(); () }); let _x = x.0; } ``` With a bit of code golf: ```rust fn f() -> ! { let _x = ({ panic!(); () },).0; } ``` This is a path expression that diverges: ```rust fn f(x: !) -> ! { x; } ``` To express that without nightly never, we can say, e.g.: ```rust fn phantom_call<T>(_: impl FnOnce(T) -> T) {} fn main() { phantom_call(|x /* : ! */| -> ! { x; }); } ``` ## Add cut operator (^) to grammar #2104 https://github.com/rust-lang/reference/pull/2104 ## Add a contributor guide #2097 https://github.com/rust-lang/reference/pull/2097 ## Rework the introduction and add a scope chapter https://github.com/rust-lang/reference/pull/2100