rust-lang / rust-lang/rust-analyzer

Letting the `unlinked-file` fix add missing parent modules recursively

Open
#20,746 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-feature
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

Short description

It would be great if the unlinked-file diagnostic also offered a fix if the unlinked file (e.g. parent/child.rs) is in a folder (parent/) that doesn't have an associated module file (parent.rs) yet and/or is itself unlinked.

The fix would just create the missing module files for all parent folders recursively and link the uppermost one from the first already-linked module it encounters on its way up to the crate root.

Minimal reproducible example

Just so we're on the same page about the current behavior, here is how to set up a minimal reproducible example project:

$ cd `$(mktemp -d tmp-XXXXX)`
$ cargo init
  Creating binary (application package)
$ mkdir src/parent
$ touch src/parent/child.rs

Then open src/parent/child.rs in an editor using rust-analyzer as its LSP server (and, if required, make a small change to let it show the diagnostic), which will show the familiar unlinked-file diagnostic:

This file is not included in any crates, so rust-analyzer can't offer IDE services. If you're intentionally working on unowned files, you can silence this warning by adding "unlinked-file" to rust-analyzer.diagnostics.disabled in your settings.

However, trying to open fixes for it yields no results.

This doesn't change if we merely create a parent.rs module for the folder without linking it:

$ touch src/parent.rs
# ... then re-open child.rs and try to open fixes for the unlinked-file diagnostic

Only if we link parent.rs from our main.rs will rust-analyzer offer fixes:

$ echo "mod parent" >> main.rs
# ... then re-open child.rs and try to open fixes for the unlinked-file diagnostic

Now the diagnostic for child.rs will suggest adding variants of mod child with different visibility levels (pub, pub(crate), normal) to parent.rs:

# Example output in Neovim, may look different in other editors:
Code actions:                                                                                                                                  
1: Insert `mod child;`                                                                                                                                 
2: Insert `pub mod child;`                                                                                                                             
3: Insert `pub(crate) mod child;`                                                                                                                      

Details

(I might add more items here if they come up in discussions in the comments.)

Visibility levels

Since the unlinked file may be nested arbitrarily deeply within ancestor folders, it wouldn't be sensible to offer all possible visibility configurations for each entry in the chain. Instead, rust-analyzer could either just go with non-public visibility (mod ancestor) or offer the 3 options it currently offers and apply the selected one to all ancestors.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the unlinked-file diagnostic with src/parent/child.rs, an optional src/parent.rs, and main.rs as described. Start by tracing the existing unlinked-file code action and how it links modules. Done means a fix recursively creates missing parent module files, links the uppermost module from the first linked ancestor, and applies a consistent visibility choice.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.