Skip to content

Commit e920a4c

Browse files
authored
Merge pull request github#17828 from hvitved/rust/enclosing-callable
Rust: Introduce `AstNode.getEnclosingCallable`
2 parents 7bbd4a1 + a3d8b8e commit e920a4c

File tree

6 files changed

+34
-33
lines changed

6 files changed

+34
-33
lines changed

rust/ql/.generated.list

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/.gitattributes

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ private module CfgInput implements InputSig<Location> {
2121
/** An AST node with an associated control-flow graph. */
2222
class CfgScope = Scope::CfgScope;
2323

24-
CfgScope getCfgScope(AstNode n) { result = Scope::scopeOfAst(n) }
24+
CfgScope getCfgScope(AstNode n) { result = n.getEnclosingCallable() }
2525

2626
class SuccessorType = Cfg::SuccessorType;
2727

rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,3 @@ class CfgScope extends Callable {
2424
result = this.(ClosureExpr).getBody()
2525
}
2626
}
27-
28-
/**
29-
* Gets the immediate parent of a non-`AstNode` element `e`.
30-
*
31-
* We restrict `e` to be a non-`AstNode` to skip past non-`AstNode` in
32-
* the transitive closure computation in `getParentOfAst`. This is
33-
* necessary because the parent of an `AstNode` is not necessarily an `AstNode`.
34-
*/
35-
private Element getParentOfAstStep(Element e) {
36-
not e instanceof AstNode and
37-
result = getImmediateParent(e)
38-
}
39-
40-
/** Gets the nearest enclosing parent of `ast` that is an `AstNode`. */
41-
private AstNode getParentOfAst(AstNode ast) {
42-
result = getParentOfAstStep*(getImmediateParent(ast))
43-
}
44-
45-
/** Gets the enclosing scope of a node */
46-
cached
47-
AstNode scopeOfAst(AstNode n) {
48-
exists(AstNode p | p = getParentOfAst(n) |
49-
if p instanceof CfgScope then p = result else result = scopeOfAst(p)
50-
)
51-
}

rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// generated by codegen, remove this comment if you wish to edit this file
21
/**
32
* This module provides a hand-modifiable wrapper around the generated class `AstNode`.
43
*
@@ -12,5 +11,36 @@ private import codeql.rust.elements.internal.generated.AstNode
1211
* be referenced directly.
1312
*/
1413
module Impl {
15-
class AstNode extends Generated::AstNode { }
14+
private import rust
15+
private import codeql.rust.elements.internal.generated.ParentChild
16+
17+
/**
18+
* Gets the immediate parent of a non-`AstNode` element `e`.
19+
*
20+
* We restrict `e` to be a non-`AstNode` to skip past non-`AstNode` in
21+
* the transitive closure computation in `getParentOfAst`. This is
22+
* necessary because the parent of an `AstNode` is not necessarily an `AstNode`.
23+
*/
24+
private Element getParentOfAstStep(Element e) {
25+
not e instanceof AstNode and
26+
result = getImmediateParent(e)
27+
}
28+
29+
/** Gets the nearest enclosing parent of `ast` that is an `AstNode`. */
30+
private AstNode getParentOfAst(AstNode ast) {
31+
result = getParentOfAstStep*(getImmediateParent(ast))
32+
}
33+
34+
class AstNode extends Generated::AstNode {
35+
/** Gets the immediately enclosing callable of this node, if any. */
36+
cached
37+
Callable getEnclosingCallable() {
38+
exists(AstNode p | p = getParentOfAst(this) |
39+
result = p
40+
or
41+
not p instanceof Callable and
42+
result = p.getEnclosingCallable()
43+
)
44+
}
45+
}
1646
}

rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,6 @@ module Impl {
421421
)
422422
}
423423

424-
private import codeql.rust.controlflow.internal.Scope
425-
426424
/** A variable access. */
427425
class VariableAccess extends PathExprImpl::PathExpr instanceof VariableAccessCand {
428426
private string name;
@@ -434,7 +432,7 @@ module Impl {
434432
Variable getVariable() { result = v }
435433

436434
/** Holds if this access is a capture. */
437-
predicate isCapture() { scopeOfAst(this) != scopeOfAst(v.getPat()) }
435+
predicate isCapture() { this.getEnclosingCallable() != v.getPat().getEnclosingCallable() }
438436

439437
override string toString() { result = name }
440438

0 commit comments

Comments
 (0)