RIR/driver: stop dropping stray intrinsic type-args; renumber merged Path patterns; dedup symbol detection#930
Merged
steveklabnik merged 1 commit intoJun 11, 2026
Conversation
…mber merged Path patterns; one dup-symbol helper Three driver-layer fixes from the CLI-hardening epic: Stray intrinsic type arguments (item 8, silent miscompile): AstGen dropped IntrinsicArg::Type when lowering args for expression intrinsics, so @syscall(a, (), b) silently deleted the middle argument and shifted b into the wrong syscall register. The stray arg now lowers to a TypeConst placeholder and sema reports E0702 (intrinsic argument type mismatch) instead of miscompiling. CLI cases in intrinsic_args.toml. Rir::merge Path patterns (item 9): merge renumbered every InstRef except the module ref inside Path match-arm patterns, leaving refs from the second file onward pointing into the wrong file's instruction space. Now renumbered like everything else (preserving the u32::MAX None sentinel), with unit tests for both. The corruption is latent today — sema's enum resolution ignores the module ref — so a pinning multi-file CLI case documents current behavior rather than a user-visible repro. Duplicate-symbol detection (item 6): the same check was hand-written three times (merge_symbols, the parallel RIR path, and CompilationUnit::parse) and reported duplicate FUNCTIONS with DuplicateTypeDefinition. One detect_duplicate_symbols helper now serves all three sites, and functions get their own DuplicateFunctionDefinition error kind. Full test.sh green. Part of RUE-130 (items 6, 8, 9; remaining: 2-5, 7). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
steveklabnik
added a commit
to steveklabnik/rue
that referenced
this pull request
Jun 11, 2026
Two move-checking holes from the soundness epic, both verified by repro
before and after:
Projected by-ref arguments (item 3): passing a struct field as a borrow or
inout argument (peek(borrow o.f)) sailed through sema and panicked codegen
("by-ref argument must be a variable", cfg_lower.rs:1798). By-ref arguments
must now be plain variables — new E0438 with a "passing a field is not yet
supported" note. Covers function calls, method calls, and array elements,
on both sema implementations. Place-address lowering is the long-term fix
and stays in the epic.
Moves out of inout parameters (item 4): a callee could move out of an
inout param (fn steal(inout o: D) -> i32 { consume(o) }) with no
reinitialize-before-exit requirement, leaving the CALLER's variable
moved-from — a use-after-free shape that returned garbage today (observed
exit 127 for a 7+7 program). Any move out of an inout param is now
rejected flatly with E0437; the diagnostic documents the deliberately
conservative rule (reinitialization tracking may relax it later).
Field-level moves out of borrow params now also get the whole-var E0429
treatment. Inout forwarding (g(inout v) inside f(inout v)) keeps working
via an explicit byref-arg flag that replaces the old mark-then-unmove
hack — and composes with the loop re-move machinery (move-out in a loop
body errors; inout args in loops still compile).
Item 6 of the epic (Copy reads through a moved ancestor) was re-verified
still broken and remains tracked — the fix needs ancestor-moved checks on
Copy reads plus FieldSet auditing, too invasive to bundle here.
Fifteen CLI cases in byref_params.toml: the E0438/E0437/E0429 rejections
(including in-loop and reinit-then-return variants and a multi-file @import
case pinning the lazy path), plus controls for whole-var borrow/inout,
forwarding, reassign-only inout, and Copy field reads. Note E0438 was
renumbered from the worker's E0436 at integration: PR rue-language#930 takes E0436 for
DuplicateFunctionDefinition. Full test.sh green.
Part of RUE-127 (items 3, 4; remaining: 5, 6).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
50d6f2b to
57e19b3
Compare
steveklabnik
added a commit
to steveklabnik/rue
that referenced
this pull request
Jun 11, 2026
…le), panic-hook ICE banner, full benchmark metrics The --emit pipeline diverged from normal builds in four user-visible ways (driver-hardening epic, items 2-5 and 7): - Module programs failed E0704 only under --emit: the emit path called the frontend without sema's file_id->path mapping. A new compile_frontend_from_ast_with_file_paths threads it through (the old entry point delegates with an empty map), so @import programs emit IR exactly like they build. - Warnings were silently dropped in every --emit mode: the frontend state's warnings were computed and discarded. They now print to stderr via the multi-file formatter, same as a normal build. - Multi-file --emit was impossible: with no -o, the legacy two-positional parse claimed the second FILE as the output path ("refusing to use 'b.rue' as the output path") — but --emit produces no executable. Under --emit every positional is now a source file. One parse_args unit test pinned the old dead-output behavior and is updated. - --benchmark-json source metrics measured only the first file; bytes, lines, and tokens now sum across all files. Also installs a panic hook (item 5): a compiler panic now prints an "internal compiler error: this is a bug in rue" banner with the version and the issue-tracker URL after the standard panic output, instead of ending on a bare backtrace pointer. Item 2's reported lex-error misattribution under --emit tokens no longer reproduces (file ids ride the tokens since the FileId threading fixes); covered by the multifile_errors cases. CLI: new emit_pipeline.toml cases pin warnings-under-emit and modules-under-emit; the harness gains compile_stderr_contains (positive mirror of the existing not_contains) to assert warnings on a successful compile. Full test.sh green. Part of RUE-130 (items 2-5, 7; remaining: item 6 landed in rue-language#930). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
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.
Three driver-layer fixes from the CLI-hardening epic:
Stray intrinsic type arguments (item 8, silent miscompile): AstGen dropped
IntrinsicArg::Type when lowering args for expression intrinsics, so
@syscall(a, (), b) silently deleted the middle argument and shifted b into
the wrong syscall register. The stray arg now lowers to a TypeConst
placeholder and sema reports E0702 (intrinsic argument type mismatch)
instead of miscompiling. CLI cases in intrinsic_args.toml.
Rir::merge Path patterns (item 9): merge renumbered every InstRef except
the module ref inside Path match-arm patterns, leaving refs from the second
file onward pointing into the wrong file's instruction space. Now
renumbered like everything else (preserving the u32::MAX None sentinel),
with unit tests for both. The corruption is latent today — sema's enum
resolution ignores the module ref — so a pinning multi-file CLI case
documents current behavior rather than a user-visible repro.
Duplicate-symbol detection (item 6): the same check was hand-written three
times (merge_symbols, the parallel RIR path, and CompilationUnit::parse)
and reported duplicate FUNCTIONS with DuplicateTypeDefinition. One
detect_duplicate_symbols helper now serves all three sites, and functions
get their own DuplicateFunctionDefinition error kind.
Full test.sh green.
Part of RUE-130 (items 6, 8, 9; remaining: 2-5, 7).
🤖 Generated with Claude Code