Skip to content

Conversation

@seafoamteal
Copy link

@seafoamteal seafoamteal commented Nov 23, 2025

Description

This resolves #5145.

Three changes were made:

  1. When a module was aliased, the entity for the original name has to be placed in the Shadowed layer and not the Module layer. This prevents it from shadowing previous imports with the same module name.
  2. When registering a module reference from a module access site, the module_name_to_node map should not be checked. This map contains full original names of modules (e.g. wibble/wobble and wobble) and hence isn't guaranteed to point us to the correct node when we have limited information (e.g. just wobble). We skip this check and directly look up the entity in the Module layer. The module_name_to_node map is only needed/used when registering references from unqualified imports and aliases, since we are guaranteed to have information only about the original name of the module in those cases.
  3. This is not directly related to the bugfix, but the assert_no_warnings! macro was defined ambiguously. If src was any expr, then the compiler would not know whether a second module tuple was part of the repeated list of module tuples or src. Changing src to be a literal fixes this.

Example

Before

import wibble/wobble
import wobble as wob

pub fn main() {
  wobble.wimble()
  wob.womble()
}

Here, at wobble.wimble(), a lookup in the module_name_to_node map would return the top-level wobble module that is aliased to wob. Hence, no reference to wibble/wobble is registered and it is incorrectly marked unused.

A less visible problem is that wibble/wobble is added to the Module layer as entity with name wobble. Then, on the next line, wobble is once again added to the Module layer with the same name, shadowing the first import.

After

At wobble.wimble(), we look up the wobble entity in the Module layer instead. This gives us the correct wibble/wobble module.

The Module layer contains two entities: wobble and wob. The Shadowed layer contains one entity: wobble.

Also updated assert_no_warnings to avoid ambiguity in parsing
test cases with multiple extra modules
1. Modules with an alias had to be marked as shadowed
2. When registering module references from callsites, we can't look up
the module_name_to_node map as we have limited information about the
module name
Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I've left some questions inline.

}

pub fn register_module_reference(&mut self, name: EcoString) {
pub fn register_module_reference_for_unqualified_imports_and_aliases(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this new name. It seems to say something about the context in which it is used, but not name the function itself, and the meaning is unclear.

Could these two functions be given clearer names please, and documentation comments could be useful 🙏

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, sorry about that. I've given them both better names now, relating to the sort of module name they take as arguments.

}

pub fn register_module(
pub fn register_unaliased_module(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this new name mean? What distinguishes it from the new function with the previous name?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I was trying to work around making EntityLayer public and changing all the call sites of register_module, but it does seem cleaner to avoid the extra wrapper function. I've made the changes necessary to remove it.

Removed unnecessary register_unaliased_module function
Renamed both register_module_reference_* functions to be clearer about
intention
Added documentation for register_module_reference_* functions
@seafoamteal
Copy link
Author

Hey @lpil, I'm just bumping this because I'm not sure if the inline responses show up as notifications.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False positive This imported module is never used when aliasing

2 participants