nandi/rustnimpublic Fork
⑂ dee1a76
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/rustnim.git
git clone ssh://git@rickub.com/nandi/rustnim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

Count what an item writes, not what kind of item it is

`emitted` was incremented for any item that was not a `use`, `mod`, `extern
crate` or type alias -- which includes a `macro_rules!` definition. A
`macro_rules!` emits nothing of its own; it is expanded at each call site. So
a crate that is nothing but macros passed the "nothing was translated" guard
while producing a file containing only the prelude.

Four crates I had counted as working are that: `arrayref`, `cfg-if`,
`cpufeatures` and `ctor` each produced exactly 367 lines, and the prelude
alone is 367 lines. They now fail, which is correct, and the message says
which kinds of item emit nothing rather than leaving it to be guessed.

This is the exact failure the project was founded to refuse -- a transpiler
reporting success for an empty file -- and the guard against it was measuring
the wrong thing. It counts bytes written now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandithebull committed 2026-09-20T13:57:02-07:00 Browse files
dee1a76 parent: 5d49ce5
modified src/lower.rs +16 -4
@@ -836,9 +836,10 @@ impl Lowerer {
836836 // the output file looks. The prelude alone is not a translation.
837837 if self.emitted == 0 {
838838 return Err(format!(
839- "nothing was translated: the input has no items this lowering \
840- emits{}. Writing a file containing only the prelude would \
841- report success for work that was not done",
839+ "nothing was translated: every item in the input either emits \
840+ nothing of its own -- a `macro_rules!` definition, a `use`, a \
841+ `mod` -- or was dropped{}. Writing a file containing only the \
842+ prelude would report success for work that was not done",
842843 if self.dropped_by_cfg > 0 {
843844 format!(
844845 " ({} item(s) were dropped by `#[cfg]`; enable them with \
@@ -3100,9 +3101,20 @@ impl Lowerer {
31003101 }
31013102
31023103 fn item_inner(&mut self, item: &Item) -> Result<(), String> {
3103- if !matches!(item, Item::Use(_) | Item::ExternCrate(_) | Item::Mod(_) | Item::Type(_)) {
3104+ // Counted by what it actually writes, not by what kind of item it is.
3105+ // A `macro_rules!` definition is an item and emits nothing -- it is
3106+ // expanded at each call site -- so a crate that is nothing but macros
3107+ // was reporting success while producing a file containing only the
3108+ // prelude. That is the failure this project exists to refuse.
3109+ let before = self.out.len() + self.hoisted.len() + self.forwards.len();
3110+ let r = self.item_inner_at(item);
3111+ if self.out.len() + self.hoisted.len() + self.forwards.len() > before {
31043112 self.emitted += 1;
31053113 }
3114+ r
3115+ }
3116+
3117+ fn item_inner_at(&mut self, item: &Item) -> Result<(), String> {
31063118 match item {
31073119 Item::Fn(f) => {
31083120 let nim = self.fn_name(&self.cur_mod, &f.sig.ident.to_string());
@@ -836,9 +836,10 @@ impl Lowerer {
836 // the output file looks. The prelude alone is not a translation.836 // the output file looks. The prelude alone is not a translation.
837 if self.emitted == 0 {837 if self.emitted == 0 {
838 return Err(format!(838 return Err(format!(
839- "nothing was translated: the input has no items this lowering \839+ "nothing was translated: every item in the input either emits \
840- emits{}. Writing a file containing only the prelude would \840+ nothing of its own -- a `macro_rules!` definition, a `use`, a \
841- report success for work that was not done",841+ `mod` -- or was dropped{}. Writing a file containing only the \
842+ prelude would report success for work that was not done",
842 if self.dropped_by_cfg > 0 {843 if self.dropped_by_cfg > 0 {
843 format!(844 format!(
844 " ({} item(s) were dropped by `#[cfg]`; enable them with \845 " ({} item(s) were dropped by `#[cfg]`; enable them with \
@@ -3100,9 +3101,20 @@ impl Lowerer {
3100 }3101 }
3101 3102
3102 fn item_inner(&mut self, item: &Item) -> Result<(), String> {3103 fn item_inner(&mut self, item: &Item) -> Result<(), String> {
3103- if !matches!(item, Item::Use(_) | Item::ExternCrate(_) | Item::Mod(_) | Item::Type(_)) {3104+ // Counted by what it actually writes, not by what kind of item it is.
3105+ // A `macro_rules!` definition is an item and emits nothing -- it is
3106+ // expanded at each call site -- so a crate that is nothing but macros
3107+ // was reporting success while producing a file containing only the
3108+ // prelude. That is the failure this project exists to refuse.
3109+ let before = self.out.len() + self.hoisted.len() + self.forwards.len();
3110+ let r = self.item_inner_at(item);
3111+ if self.out.len() + self.hoisted.len() + self.forwards.len() > before {
3104 self.emitted += 1;3112 self.emitted += 1;
3105 }3113 }
3114+ r
3115+ }
3116+
3117+ fn item_inner_at(&mut self, item: &Item) -> Result<(), String> {
3106 match item {3118 match item {
3107 Item::Fn(f) => {3119 Item::Fn(f) => {
3108 let nim = self.fn_name(&self.cur_mod, &f.sig.ident.to_string());3120 let nim = self.fn_name(&self.cur_mod, &f.sig.ident.to_string());