Skip to content

Letting the unlinked-file fix add missing parent modules recursively #20746

@smheidrich

Description

@smheidrich

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-featureCategory: feature request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions