Repository navigation
refactor(analyser): type the literals in a generic body by the body alone ✂️ - #340
Merged
Merged
Conversation
…lone ✂️ Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A number literal in a generic function's body that the function's parameters reached became an extra type parameter, which each call settled:
fn pair(x) => [x, 1]madepair(2.5)[2.5, 1.0]. That needed its own machinery: literal type parameters with bounds in each scheme, per-instance literal types read by the compiler, and special Int rules for calls from an earlier REPL line and for function values. As a result the same code typed differently in a file and in the REPL. A review of the type checker found that no realistic program used it.A generic body's literals are now decided by the body alone, before the function is generalised, with the same look-ahead as literals anywhere else. They're never type parameters, so a file and the REPL type a program the same way.
Behaviour changes:
fn fact(n) => if n < 2 { 1 } else { n * fact(n - 1) }called asfact(5.0)is an analysis error pointing into the body. Writing1.0makes it work for Ints and Floats alike.fn pair(x) => [x, 1]only takes Ints,fn k(x) => [x, "b"]only Strings, andfn f(xs) { xs.push(1); xs }onlyList<Int>.fn inc(x) => x + 1still takes Floats, since+(Float, Int)exists, andfib(10.0)still works. A literal at the call still adapts:let r: Float = g(3)makes the3a Float.fn f(xs: List<Any>),fn f(x) => f([x])now makesxanAny, so it calls theList<Any>overload instead of reporting growing recursion.Removed:
Scheme.literalsandliteral_nodes,LiteralBounds,instantiate_literals,resolve_bounds,with_literals_named,literals_tied_to_parameters,number_literals, the Int rules for earlier batches and function values, the per-instanceliteral_typesin the analysis, layout and compiler, and the bound de-duplication only copied literals needed (−353 lines of Rust).A second commit sorts the unsettled literals by a key computed once, which was quadratic for a list of 20,000 values.
The manual's function and augmented-assignment pages are updated.
🤖 Generated with Claude Code