Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion bootstrap/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23034,7 +23034,20 @@ fn collect_unresolved_types(
// rustc will later fail to find. That disagreement between the two
// resolvers is worth its own repair; this check works around it
// rather than pretending it is not there.
let emitter_knows = RustCodegen::t27_type_to_rust(&base) != base;
// The emitter answers for the spellings it REWRITES (`int` ->
// `i32`) and passes through the ones already valid in Rust -- so
// `usize`, `isize` and `char` came back unchanged and read as
// undeclared types. That was 565 of the 1045 remaining warnings,
// every one of them on `usize`, every one false.
//
// `int_value_bits(&base).is_some()` was tried here as a second
// oracle and REMOVED: it answers for `usize` and `isize` and not
// for `char`, so the explicit list below is needed anyway, and with
// the list present dropping `int_value_bits` changes nothing --
// measured, the test still passes and the corpus count is
// unchanged. Three names is the whole gap.
let emitter_knows = RustCodegen::t27_type_to_rust(&base) != base
|| matches!(base.as_str(), "char" | "usize" | "isize");
if !declared.contains(&base)
&& !type_params.contains(&base)
&& !emitter_knows
Expand Down
2 changes: 1 addition & 1 deletion bootstrap/stage0/FROZEN_HASH
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fa7f44546531946823206c2f9796e8ada32a3efb9ffaa7f150e92da623084a89 bootstrap/src/compiler.rs
9c910e4dfae29326a04b20dc9889ecdf33a42849d8bb754bfbebedcaff2e1efb bootstrap/src/compiler.rs
28 changes: 28 additions & 0 deletions bootstrap/tests/unknown_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,31 @@ fn a_type_that_arrives_through_an_import_is_not_unknown() {
warned.join("\n")
);
}

/// A spelling the emitter passes through unchanged is not an unknown type.
///
/// The first oracle was "does the Rust emitter REWRITE this name" -- true for
/// `int` -> `i32`, and false for `usize`, `isize` and `char`, which are already
/// valid Rust and come back unchanged. That read as undeclared: **565 of the
/// 1045 remaining warnings, every one of them on `usize`**.
///
/// `int_value_bits` answers the right question -- does this spelling have a
/// width -- regardless of which target it is spelled for.
#[test]
fn a_spelling_already_valid_in_the_target_is_not_unknown() {
let w = unknown_types(
"module m {\n struct S { a: usize, b: isize, c: char, }\n}\n",
);
assert!(w.is_empty(), "primitive spellings must not warn: {w:?}");
}

#[test]
fn a_genuinely_undeclared_name_still_warns_beside_them() {
// The control for the test above: widening the known set must not widen it
// to everything. `Nope` has no width, no rewrite and no declaration.
let w = unknown_types(
"module m {\n struct S { a: usize, b: Nope, }\n}\n",
);
assert_eq!(w.len(), 1, "exactly the undeclared one, got {w:?}");
assert!(w[0].contains("Nope"), "{}", w[0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# NOW -- The oracle answered only for names it rewrites (2026-09-08)

## The oracle answered only for names it rewrites (Refs #3412, #3408)

- My unknown-type check asked the Rust emitter "do you know this name", and the emitter answers by REWRITING (`int` -> `i32`). Spellings already valid in Rust -- `usize`, `isize`, `char` -- come back unchanged, so the test read them as undeclared. **565 of the 1045 remaining warnings, every one on `usize`, every one false.** Second false-positive class in my own check in as many passes, and again found by measuring my own output.
- Fixed by naming the three. Corpus: `unknown type` **1045 -> 478**, all warnings **1570 -> 1003**, exit codes unchanged at 573/78. Across both passes my own false positives fall **1283 -> 478**, a 63% cut, with the exit code of `check` never changing for any of 651 specs.
- `int_value_bits(&base).is_some()` was added as a second oracle and then **REMOVED**. Mutation showed why: dropping the explicit list makes `char` warn and the test fail; dropping `int_value_bits` changes nothing, because the list already covers `usize` and `isize`. Second redundant guard removed rather than shipped in as many passes, and by the same rule -- if I cannot make a test tell the difference, it is decoration.
- What remains is real: `Result` 69, `Float` 60, `String` 53, `Int` 32, `Trit` 26, `Bool` 23. Those names are declared by nothing.
- Sized for the next pass: only **6 specs** still warn on `Trit`, and **4 of them carry zero `use` lines**. One import line in `specs/ar/restraint.t27` takes its emitted Rust from 30 rustc errors to 19.
Loading