ADR-166: Cargo’s Target-Info Probe Is Given an Empty Standard Input

Status: Accepted Date: September 20, 2026 Related: ADR-002 D1 (the orchestrator and its rustc wrapper), ADR-003 D2 (the generic half knows nothing about .nika), Part III C.1

1. Context

nikaia build points RUSTC_WORKSPACE_WRAPPER at the nikaia binary itself, so every rustc command line Cargo produces arrives here first (ADR-002 D1). One of them is not a compile:

rustc - --crate-name ___ --print=file-names --crate-type bin … --print=cfg

Cargo runs it once per build to learn what the target looks like. The - means the program is on standard input, and Cargo writes nothing there — it wants the --print answers, not a compiled program.

Passed straight through, that invocation inherits the standard input of whoever started the build, and anything sitting in it is read as a Rust program. What the build says then is:

error: failed to run `rustc` to learn about target-specific information
  --- stderr
  error: unknown start of token: `
   --> <anon>:1:16
  1 | warning: trait `Foo` is never used

— a parse error about text nobody offered as source, at <anon>:1, in a build of a program that does not contain it. The contaminant is never the same, and under a test harness it is the harness’s stream, not the outer command’s.

2. Decisions

D1 — An invocation that names - and asks a --print is handed /dev/null.

Both halves are required, and neither alone is the probe: - is what makes rustc read standard input at all, and a --print is what says the answer is something other than a compiled program. A real compile names a file, so nothing that genuinely hands rustc a program this way loses one.

Every other invocation keeps the standard input it had.

Why the wrapper and not the caller. A build that fails because of what was in the terminal’s input is not reproducible, and a toolchain that is reproducible only when invoked carefully is not reproducible. The probe has one correct standard input — empty — and the process that knows that is the one holding the argument list.

And it is C.1’s class, one step further out than that section usually reaches: the message is about neither the program nor a generated file, but about text the user never offered to anything.

3. Consequences

4. What this does not decide

This site is open source. Improve this page.