Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions rust/ql/lib/codeql/rust/internal/Definitions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ abstract class Use extends Locatable {
* Gets the type of use.
*/
abstract string getUseType();

/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}

cached
Expand Down Expand Up @@ -166,6 +179,43 @@ private class MethodUse extends Use instanceof NameRef {
override string getUseType() { result = "method" }
}

private class OperationUse extends Use instanceof Operation {
override Definition getDefinition() { result.asItemNode() = this.(Call).getStaticTarget() }

override string getUseType() { result = "method" }

override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
// We don't have entities for the operator symbols, so approximate a location
this =
any(PrefixExpr pe |
pe.getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _) and
pe.getExpr().getLocation().hasLocationInfo(_, endline, endcolumn + 2, _, _)
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The location calculation appears to have the start and end columns inverted. For a prefix expression like -S on line 67, the expected output shows 67:5:67:4 (start column 5, end column 4), where the end column is before the start column. This will likely cause issues with jump-to-definition functionality.

Looking at the logic:

  • Line 193: pe.getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _) gets the prefix expression's start location
  • Line 194: pe.getExpr().getLocation().hasLocationInfo(_, endline, endcolumn + 2, _, _) gets the operand's end location

The issue is that for -S, the prefix expression location is the entire -S, and the operand S comes after the -. So using the prefix expression's start column and the operand's end column (which comes before it) results in inverted columns.

Consider calculating the operator location more directly, or ensure endcolumn >= startcolumn.

Suggested change
pe.getExpr().getLocation().hasLocationInfo(_, endline, endcolumn + 2, _, _)
endline = startline and
endcolumn = startcolumn + 1

Copilot uses AI. Check for mistakes.
)
or
this =
any(BinaryExpr be |
be.getLhs().getLocation().hasLocationInfo(filepath, _, _, startline, startcolumn - 2) and
be.getRhs().getLocation().hasLocationInfo(filepath, endline, endcolumn + 2, _, _)
)
}
}

private class IndexExprUse extends Use instanceof IndexExpr {
override Definition getDefinition() { result.asItemNode() = this.(Call).getStaticTarget() }

override string getUseType() { result = "method" }

override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
// We don't have entities for the brackets, so approximate a location
super.getIndex().getLocation().hasLocationInfo(filepath, _, _, startline, startcolumn - 2) and
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
super.getIndex().getLocation().hasLocationInfo(filepath, _, _, startline, startcolumn - 2) and
super.getIndex().getLocation().hasLocationInfo(filepath, _, _, startline, startcolumn - 1) and

?

this.getLocation().hasLocationInfo(_, _, _, endline, endcolumn)
Comment on lines +237 to +238
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The location calculation results in inverted columns where end column is before start column. For an index expression like S[0] on line 69, the expected test output shows 69:9:69:8 (start column 9, end column 8).

Looking at the logic:

  • Line 214: super.getIndex().getLocation().hasLocationInfo(filepath, _, _, startline, startcolumn - 2) - This tries to get a location where the index ends at startcolumn - 2, which would place startcolumn approximately at the opening bracket [
  • Line 215: this.getLocation().hasLocationInfo(_, _, _, endline, endcolumn) - This gets the end of the entire IndexExpr

The issue is that getIndex() returns the index expression (e.g., 0), and this code assumes its end location minus 2 gives the bracket position. However, the arithmetic appears incorrect, resulting in endcolumn < startcolumn.

Consider revising the location calculation to ensure endcolumn >= startcolumn, or compute the bracket positions more accurately.

Suggested change
super.getIndex().getLocation().hasLocationInfo(filepath, _, _, startline, startcolumn - 2) and
this.getLocation().hasLocationInfo(_, _, _, endline, endcolumn)
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)

Copilot uses AI. Check for mistakes.
}
}

private class FileUse extends Use instanceof Name {
override Definition getDefinition() {
exists(Module m |
Expand Down
3 changes: 3 additions & 0 deletions rust/ql/test/library-tests/definitions/Definitions.expected
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@
| main.rs:66:14:66:14 | S | main.rs:3:1:4:9 | struct S | path |
| main.rs:66:18:66:20 | new | main.rs:46:9:48:9 | fn new | path |
| main.rs:66:22:66:22 | S | main.rs:3:1:4:9 | struct S | path |
| main.rs:67:5:67:4 | - ... | main.rs:11:5:13:5 | fn neg | method |
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be main.rs:67:5:67:5? i.e. endcolumn + 2 in the logic should be endcolumn + 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's what I did initially, but that means putting the cursor between - and S will jump to both neg and S, and I want to avoid overlapping targets. With the above, only putting the cursor before - will jump to neg.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's odd - S is clearly (from the line below) character 6, while - is character 5.

I'm not sure what you mean about "putting the cursor between" two characters - surely the granularity here is which single character you're pointing at?

Copy link
Contributor

Choose a reason for hiding this comment

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

putting the cursor between - and S

I still don't know what you mean here. Surely your mouse is either over the - or over the S?

| main.rs:67:6:67:6 | S | main.rs:3:1:4:9 | struct S | path |
| main.rs:68:5:68:5 | S | main.rs:3:1:4:9 | struct S | path |
| main.rs:68:7:68:7 | ... + ... | main.rs:19:5:21:5 | fn add | method |
| main.rs:68:9:68:9 | S | main.rs:3:1:4:9 | struct S | path |
| main.rs:69:5:69:5 | S | main.rs:3:1:4:9 | struct S | path |
| main.rs:69:9:69:8 | S[0] | main.rs:27:5:29:5 | fn index | method |
Copy link
Contributor

Choose a reason for hiding this comment

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

... and shouldn't this be main.rs:69:6:69:8? I think the formula for brackets ought to be one character wider than the index, i.e. super.getIndex().getLocation().hasLocationInfo(filepath, startline, startcolumn + 1, endline, endcolumn - 1).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we do it like that, then putting the cursor between x and ] in a[x] will jump to both index and x.

Copy link
Contributor

Choose a reason for hiding this comment

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

So having it just cover ] is a compromise to avoid overlaps.

I still don't see why the range is backwards from character 9 to character 8 - shouldn't it just be character 8?