rust-lang/rust-analyzer · error
missing default crate root, specify a main.rs or lib.rs
Error message
missing default crate root, specify a main.rs or lib.rs
What it means
parse_with_proc_macros builds a CrateGraph from the fixture. If no crates were declared in the fixture, it falls back to a single default crate whose root file comes from default_crate_root; when that Option is None the expect panics. It means neither fixture-declared crates (with `-/-` crate root syntax) nor a default main.rs/lib.rs root were available.
Source
Thrown at crates/test-fixture/src/lib.rs:425
crate_ws_data.clone(),
);
(
move || {
DependencyBuilder::with_prelude(
CrateName::new("core").unwrap(),
core_crate,
true,
true,
)
},
core_crate,
)
});
if crates.is_empty() {
let crate_root = default_crate_root
.expect("missing default crate root, specify a main.rs or lib.rs");
let root = crate_graph.add_crate_root(
crate_root,
default_edition,
Some(CrateName::new("ra_test_fixture").unwrap().into()),
None,
default_cfg.clone(),
Some(default_cfg),
default_env,
CrateOrigin::Local { repo: None, name: None },
Vec::new(),
false,
proc_macro_cwd.clone(),
crate_ws_data.clone(),
);
if let Some((mini_core, _)) = mini_core {
crate_graph.add_dep(root, mini_core()).unwrap();
}
} else {View on GitHub (pinned to e8f7e90aa3)
Solutions
- Declare a crate root in the fixture using the `-/-` separator with lib.rs/main.rs, e.g. `"//- /lib.rs crate:main fn main() {}"`.
- Pass a default_crate_root (FileId pointing at your fixture's root file) when calling parse_with_proc_macros directly.
- Use TestDb::with_single_file-style helpers which supply a default root automatically.
- Check ChangeFixture::parse output: if your fixture text was consumed as a proc-macro/dependency directive, fix the directive syntax.
Example fix
// before
let db = TestDb::parse_with_proc_macros(fixture_text, /* no default root */ None);
// after
let db = TestDb::parse_with_proc_macros(
"//- /lib.rs crate:main deps:foo
fn main() {}",
Some(default_lib_file_id),
); Defensive patterns
Strategy: validation
Validate before calling
fn assert_fixture_declares_root(fixture: &str) {
let has_root = fixture.contains("-/-") || fixture.contains("lib.rs") || fixture.contains("main.rs");
assert!(has_root, "fixture must declare a crate root or provide a default one");
} Try / catch
// Avoid by construction; if calling parse_with_proc_macros directly:
match default_crate_root {
Some(root) => parse_with_proc_macros(text, Some(root)),
None => panic!("supply default_crate_root or declare `-/- /lib.rs` in the fixture"),
} Prevention
- When a fixture declares deps/proc-macros, always add the `-/-` crate-root section.
- Prefer TestDb::with_single_file* helpers which set a default root.
- Sanity-check ChangeFixture::parse output (crates non-empty) before further processing.
When it happens
Trigger: Calling parse_with_proc_macros (public API) with an empty crate list and without supplying default_crate_root — e.g. a fixture with proc-macro/dep declarations but no `-/-` root directive, or a fixture that parses to zero crates.
Common situations: Programmatically constructing fixtures with proc macros but forgetting the `-/-` crate-root annotation; calling the public fixture API directly rather than through TestDb helpers that set a default root; typos in the crate-root marker so it isn't recognized.
Related errors
- Could not find file position in fixture. Did you forget to a
- We explicitly do not provide canonicalization API, as that i
- bad kind {other}
- bad spacing {other}
- bad tag: {other}
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/0e811a461ce20ca3.
Report an issue: GitHub.