Skip to content

A first-party module cannot name a build output through #[path] #42

Description

@jackmarsh

Split out of #19, which fixed the idiomatic form and left this.

The case

test/bindgen/bindings_test.rs names a file rust_bindgen generates at build time:

#[path = "bindings.rs"]
mod bindings;

The file exists at build time and rust-analyzer cannot find it. This is the last remaining source of diagnostics in the repo, three of the four.

Why #19 does not cover it

Rust resolves modules relative to the containing file. #[path = "bindings.rs"] means "the file beside this one", and that is a language rule rather than a lookup rust-analyzer performs on our behalf. No field in the project file redirects it:

  • env is only read by env!, which #[path] does not go through
  • source.include_dirs says which directories may be loaded, not where a module lives

The OUT_DIR fix works because include!(concat!(env!("OUT_DIR"), ..)) builds a path at expansion time out of something we control. #[path] takes a literal.

Why go-rules does not hit this

A Go package is a directory of files, so a generated file dropped into the package directory is part of the package. A Rust crate is a tree rooted at one file, and every other file is reached by a mod declaration whose location is fixed relative to its parent.

What would have to change

This needs a decision about how rust_bindgen output is meant to be consumed, not a fix in the IDE tool. Options, none obviously right:

  1. Generate beside the source. Have rust_bindgen write into the package directory rather than plz-out. Breaks the rule that the source tree is never written to, and puts a build output where plz query input will find it.
  2. Recommend the include form. Document include!(concat!(env!("OUT_DIR"), "/bindings.rs")) as the way to consume rust_bindgen output, which rust-analyzer: generated sources are not described #19 makes work. Costs users the module namespace: the generated items land in the including module rather than a mod bindings, though mod bindings { include!(..) } gets it back.
  3. Symlink at project-file generation time. The tool could place a link beside the source. Writes to the source tree from a read-only operation.

Option 2 is the cheapest and matches what a Cargo user writes, so the first step is probably to change test/bindgen to it and see whether anything is lost. That also tells us whether option 1 is worth the cost for the ergonomics of a bare mod.

Done when

test/bindgen resolves in the editor, and the README documents the supported way to consume generated Rust.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    where:rulesProvable here with a test

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions