Skip to content

Shared: Local name resolution library#21873

Draft
hvitved wants to merge 6 commits into
github:mainfrom
hvitved:local-name-resolution
Draft

Shared: Local name resolution library#21873
hvitved wants to merge 6 commits into
github:mainfrom
hvitved:local-name-resolution

Conversation

@hvitved
Copy link
Copy Markdown
Contributor

@hvitved hvitved commented May 20, 2026

This PR adds a new shared library for doing local name binding, and applies it to Ruby and Rust.

The interface to the library is inspired by a similar unreleased library created by @asgerf, but unlike that library, this library supports sibling-based shadowing as known from Rust:

let x = 1;
let x = x + 1;     // shadows `x` above, but `x` in the RHS still refers to the above
println!("{}", x); // refers to the shadowing `x`

The implementation handles sibling shadowing much simpler than the current Rust implementation (which also has a bug, see one of the added tests), by treating shadowing sibling declarations as defining a new scope, and then letting all subsequent statements be children of that scope. That is, when looking up names by going up the AST, we rewrite the AST above to (eliding leaf nodes):

      let x = 1;
       /      \
     x + 1   let x = x + 1
                   |
            println!("{}", x);

Note how the RHS is moved away from let x = x + 1 to ensure that it resolves to the preceding declaration.

@github-actions github-actions Bot added the Rust Pull requests that update Rust code label May 20, 2026
Comment thread rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/LocalNameBinding.qll Fixed
Comment thread shared/namebinding/codeql/namebinding/LocalNameBinding.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/LocalNameBinding.qll Fixed
Comment thread rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll Fixed
class NestedFunctionAccess extends LocalAccess {
private Function f;

NestedFunctionAccess() { nestedFunctionAccess(_, f, this) }
@hvitved hvitved force-pushed the local-name-resolution branch from 46e6643 to 78a5319 Compare May 21, 2026 12:58
Comment thread shared/namebinding/codeql/namebinding/LocalNameBinding.qll Fixed
Comment thread shared/namebinding/codeql/namebinding/LocalNameBinding.qll Fixed

/** Gets the name of this variable as a string. */
string getText() { result = text }
predicate accessCand(AstNode n, string name) {
Comment thread shared/namebinding/codeql/namebinding/LocalNameBinding.qll Fixed
Comment thread shared/namebinding/codeql/namebinding/LocalNameBinding.qll Fixed
@hvitved hvitved force-pushed the local-name-resolution branch from 0de851d to 35ff093 Compare May 21, 2026 14:46
Comment thread shared/namebinding/codeql/namebinding/LocalNameBinding.qll Fixed
@hvitved hvitved force-pushed the local-name-resolution branch from 35ff093 to cad848a Compare May 21, 2026 14:49
* We also move any `else` branch _before_ the condition to ensure that shadowing declarations
* inside the condition are not in scope.
*/
private AstNode getChildAdj(AstNode parent, int index) {
@hvitved hvitved force-pushed the local-name-resolution branch 3 times, most recently from 9ce2e74 to baef7eb Compare May 22, 2026 08:01

class Ranked = AstNode;

int getRank(C parent, Ranked child) {
@hvitved hvitved force-pushed the local-name-resolution branch 2 times, most recently from 59b8380 to 0f3ee22 Compare May 22, 2026 13:24
@hvitved
Copy link
Copy Markdown
Contributor Author

hvitved commented May 22, 2026

@hvitved
Copy link
Copy Markdown
Contributor Author

hvitved commented May 22, 2026

Rerun has been triggered: 1 restarted 🚀

@hvitved hvitved force-pushed the local-name-resolution branch from 0f3ee22 to b5586e5 Compare May 26, 2026 13:06
@github-actions github-actions Bot added the Ruby label May 26, 2026
)
}

predicate accessCand(AstNode n, string name) {
@hvitved hvitved force-pushed the local-name-resolution branch 4 times, most recently from da949b1 to 392fab1 Compare May 28, 2026 08:25
@hvitved hvitved force-pushed the local-name-resolution branch from 392fab1 to 128dd5d Compare May 28, 2026 08:50
/**
* Holds if `n` is a node that may access a local named `name`.
*/
predicate accessCand(AstNode n, string name);
@hvitved hvitved changed the title Rust: Move local name resolution logic into shared library Shared: Local name resolution library May 28, 2026
@hvitved
Copy link
Copy Markdown
Contributor Author

hvitved commented May 28, 2026

Rerun has been triggered: 2 restarted 🚀

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

Labels

Ruby Rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants