Status: Superseded by ADR-286 — its D1-D3 are D28-D30 there
Date: September 15, 2026
Target Version: Nikaia 0.0.8
Related: ADR-078 (the trait declaration this makes reachable),
ADR-046 D2 (use brings no names in — which is why the program
cannot fix this itself), ADR-053 D1 (a package is its own crate,
which is what makes the trait foreign), ADR-011 D2 (the emitter
writes a name for a name, and here it had to write one nobody did)
use http
impl http::Handler for Fixed {
fn handle(&self) -> http::Response { … }
}
fn main() {
print(http::render(&f.handle()))
}
error: no method named `handle` found for struct `Fixed` in the current scope
= items from traits can only be used if the trait is in scope
= trait `Handler` which provides `handle` is implemented but not in scope;
perhaps you want to import it
Rust needs a trait in scope before its methods can be called, and
impl http::Handler for Fixed does not put it there. So a trait a package
publishes could be implemented and then not called.
That is Part III C.1’s class twice over. It is the
backend’s words about a file nobody wrote, and the remedy the message names —
“perhaps you want to import it” — is one the program cannot write:
ADR-046 D2 decided that use brings no names in, so Nikaia has no
import at all. A message asking for something the language does not have is
worse than a message in the wrong words.
The same shape in one file compiles and runs, because there the trait is in the same module and needs no import. That is what said this was one missing emitted line rather than a question about the language.
use for every trait an impl in this unit names with a package in front of it.Written as the path the program already wrote: impl http::Handler for Fixed
names the crate http, and so does the import. No table, no resolution — the
name is already the answer, which is ADR-011 D2’s rule applied to
one more place rather than an exception to it.
A trait of this program’s own is in the same module below and needs no import;
a :: in the name is exactly what says the declaration is in another crate. A
trait the compiler reads rather than a .nika file wrote — impl Error for
ConfigError (ADR-023 D3) — carries no :: either, so the same
test leaves it alone without needing to know about it.
allow(unused_imports), like the two lines above it.A program may implement a trait and never call the method, and a warning about a line nobody wrote is Part III C.1 one severity down — which is ADR-090’s whole subject. The preamble’s two existing imports carry the attribute for the same reason.
Needs gains a set and loses Copy, which is the only cost outside the one
loop that writes the lines. The preamble grows by two lines per foreign trait an
impl names, and by nothing at all for a program that names none — which is
every program in the tree today.
#234’s defect closes — a trait a package publishes is implemented and then not callable.
open-decisions.md. This record makes
the trait callable; what a package does with one it is handed is untouched.pub use at the top of the file is
what the preamble already does for std; a per-impl scope would be tidier
and would need the emitter to know where an impl ends, which it does not.emit::foreign_traits, the Needs::foreign_traits set it fills, its union in
Needs::join, and the loop in Needs::preamble. Exercised by
a_trait_a_package_publishes_can_be_implemented_and_called in
crates/nikaia/tests/project.rs — a real two-package project that builds and
runs, printing what the handler returned. It has to be two packages: the
one-file shape compiles either way, which is the fact that located the defect.
Without the loop the test fails with the message in §1, quoted from the run.