Skip to content

Conversation

hvitved
Copy link
Contributor

@hvitved hvitved commented Sep 17, 2025

Before this PR, pub use was distinguished from use, but e.g. pub fn was not distinguished from fn in path resolution. Now, we only consider pub items to be externally accessible. However, even non-pub items may be visible when accessing a declaration from an ancestor module; we currently approximate this by requiring that the access and the item belong to the same crate.

This PR also fixes a bug where importing an already renamed item was not handled correctly (it would import under the original name instead of the rename).

DCA looks fine; a small increase in resolvable calls.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Sep 17, 2025
@hvitved hvitved force-pushed the rust/path-resolution-use-reexport branch 3 times, most recently from 053ac0e to 507bbf5 Compare September 18, 2025 08:58
@hvitved hvitved changed the title Rust: Do no distinguish pub use from use in path resolution Rust: Path resolution improvements Sep 19, 2025
@hvitved hvitved force-pushed the rust/path-resolution-use-reexport branch from 0216c76 to f6bdfba Compare September 19, 2025 07:59
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Sep 19, 2025
@hvitved hvitved marked this pull request as ready for review September 19, 2025 08:21
@hvitved hvitved requested a review from a team as a code owner September 19, 2025 08:21
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves Rust path resolution by properly handling visibility modifiers and fixing import-with-rename behavior. The key changes distinguish between pub and non-pub items in path resolution logic, while ensuring non-pub items remain visible within the same crate. Additionally, the PR fixes a bug where importing an already renamed item would import under the original name instead of the correct renamed identifier.

  • Better visibility handling for path resolution based on pub modifiers
  • Fixed import-with-rename bug to use correct names
  • Improved crate-local visibility for non-public items

Reviewed Changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
rust/ql/lib/codeql/rust/internal/PathResolution.qll Core logic changes for visibility handling and import name resolution
rust/ql/test/library-tests/path-resolution/main.rs Test case updates to verify fixed import behavior
rust/ql/test/library-tests/path-resolution/my2/mod.rs Test case for renamed imports and visibility
rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs Additional test for nested import resolution
rust/ql/test/library-tests/dataflow/sources/test.rs Comment updates reflecting improved resolution

ModuleLikeNode getSuper() {
result = any(ModuleItemNode mod | fileImport(mod, this)).getASuccessor("super")
}
ModuleLikeNode getSuper() { fileImport(result.getAnItemInScope(), this) }
Copy link
Preview

Copilot AI Sep 19, 2025

Choose a reason for hiding this comment

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

The logic change from using any(ModuleItemNode mod | fileImport(mod, this)).getASuccessor(\"super\") to fileImport(result.getAnItemInScope(), this) appears to invert the relationship. The original code finds a module that imports this file and gets its super, while the new code finds what this file imports. This could break super module resolution.

Suggested change
ModuleLikeNode getSuper() { fileImport(result.getAnItemInScope(), this) }
ModuleLikeNode getSuper() { any(ModuleItemNode mod | fileImport(mod, this)).getASuccessor("super") }

Copilot uses AI. Check for mistakes.

Comment on lines +1707 to +1710
exists(string pathName |
pathName = tree.getPath().getText() and
if pathName = "self" then name = item.getName() else name = pathName
)
Copy link
Preview

Copilot AI Sep 19, 2025

Choose a reason for hiding this comment

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

This logic assumes that when pathName is not "self", the path text should be used as the import name. However, for qualified paths like foo::bar::baz, this would use "baz" as the name, but the original logic used item.getName() which might be different if the item was already renamed in an intermediate import.

Suggested change
exists(string pathName |
pathName = tree.getPath().getText() and
if pathName = "self" then name = item.getName() else name = pathName
)
name = item.getName()

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@paldepind paldepind left a comment

Choose a reason for hiding this comment

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

Looks good. I have a few questions, but they're not blocking :)

let mut f1 = async_std::fs::OpenOptions::new().open("f1.txt").await?; // $ Alert[rust/summary/taint-sources]
let mut buffer = [0u8; 1024];
let _bytes = f1.read(&mut buffer).await?;
sink(&buffer); // $ MISSING: hasTaintFlow="f1.txt"
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice 🎉

// that information in `getASuccessor`. So, for simplicity, we allow for non-public
// items when the path and the item are in the same crate.
getCrate(path) = getCrate(result) and
not result instanceof TypeParam
Copy link
Contributor

Choose a reason for hiding this comment

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

This line is just because the case we're handling here never overlaps with type parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is to avoid the case that you originally fixed in #20096.

@hvitved hvitved merged commit 5d3b542 into github:main Sep 19, 2025
22 checks passed
@hvitved hvitved deleted the rust/path-resolution-use-reexport branch September 19, 2025 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-change-note-required This PR does not need a change note Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants