Skip to content

Commit

Permalink
Rust: implement Expr::getType for cases where rust-analyzer does not …
Browse files Browse the repository at this point in the history
…provide one
  • Loading branch information
aibaars committed Nov 25, 2024
1 parent 0a0af0d commit ebdf41b
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 8 deletions.
2 changes: 0 additions & 2 deletions rust/ql/.generated.list

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions rust/ql/.gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions rust/ql/lib/codeql/rust/elements/internal/BlockExprImpl.qll
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `BlockExpr`.
*
Expand All @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.BlockExpr
* be referenced directly.
*/
module Impl {
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A block expression. For example:
* ```rust
Expand All @@ -26,5 +26,16 @@ module Impl {
* }
* ```
*/
class BlockExpr extends Generated::BlockExpr { }
class BlockExpr extends Generated::BlockExpr {
override string getType() {
result = super.getType()
or
not exists(super.getType()) and
(
result = this.getStmtList().getTailExpr().getType()
or
not exists(this.getStmtList().getTailExpr()) and result = "()"
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ private import codeql.rust.elements.internal.generated.Synth
private import codeql.rust.elements.Format
private import codeql.rust.elements.NamedFormatArgument
private import codeql.Locations
private import codeql.rust.elements.Variable

/**
* INTERNAL: This module contains the customizable definition of `FormatTemplateVariableAccess` and should not
Expand All @@ -36,5 +37,9 @@ module Impl {

/** Gets the underlying `NamedFormatArgument` . */
NamedFormatArgument getArgument() { result = argument }

override string getType() {
result = any(Variable v | v.getAnAccess() = this).getPat().getType()
}
}
}
8 changes: 8 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,13 @@ module Impl {
or
index = 3 and this.hasElse() and result = "else {...}"
}

override string getType() {
result = super.getType()
or
// For some reason rust-analyzer does not return a type for a chained `if`, so we use the parent's type instead.
not exists(super.getType()) and
result = any(IfExpr parent | parent.getElse() = this).getType()
}
}
}
10 changes: 10 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/LiteralExprImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/

private import codeql.rust.elements.internal.generated.LiteralExpr
private import codeql.rust.elements.FormatArgsExpr
private import codeql.rust.elements.LiteralPat

/**
* INTERNAL: This module contains the customizable definition of `LiteralExpr` and should not
Expand Down Expand Up @@ -41,5 +43,13 @@ module Impl {
if v.length() > 30 then result = v.substring(0, 30) + "..." else result = v
)
}

override string getType() {
result = super.getType()
or
exists(FormatArgsExpr f | f.getTemplate() = this and result = "&str")
or
result = any(LiteralPat p | p.getLiteral() = this).getType()
}
}
}
21 changes: 19 additions & 2 deletions rust/ql/lib/codeql/rust/elements/internal/MacroExprImpl.qll
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `MacroExpr`.
*
* INTERNAL: Do not use.
*/

private import codeql.rust.elements.internal.generated.MacroExpr
private import codeql.rust.elements.MacroStmts

/**
* INTERNAL: This module contains the customizable definition of `MacroExpr` and should not
* be referenced directly.
*/
module Impl {
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A MacroExpr. For example:
* ```rust
* todo!()
* ```
*/
class MacroExpr extends Generated::MacroExpr { }
class MacroExpr extends Generated::MacroExpr {
override string getType() {
result = super.getType()
or
not exists(super.getType()) and
(
result = this.getMacroCall().getExpanded().(Expr).getType() or
result = typeOf(this.getMacroCall().getExpanded().(MacroStmts))
)
}
}

string typeOf(MacroStmts stmts) {
result = stmts.getExpr().getType()
or
not exists(stmts.getExpr()) and result = "()"
}
}
18 changes: 18 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

private import codeql.rust.elements.internal.generated.PathExpr
private import codeql.rust.elements.CallExpr

/**
* INTERNAL: This module contains the customizable definition of `PathExpr` and should not
Expand All @@ -25,5 +26,22 @@ module Impl {
override string toString() { result = this.toAbbreviatedString() }

override string toAbbreviatedString() { result = this.getPath().toString() }

override string getType() {
result = super.getType()
or
// Special case for `rustc_box`; these get translated to `box X` in the HIR layer.
// ```rust
// #[rustc_box]
// alloc.boxed::Box::new(X)
// ```
not exists(super.getType()) and
exists(CallExpr c, string tp |
c.getAnAttr().getMeta().getPath().getPart().getNameRef().getText() = "rustc_box" and
this = c.getExpr() and
tp = c.getArgList().getArg(0).getType() and
result = "fn new<T>(T) -> Box<T, Global>".replaceAll("T", tp)
)
}
}
}

0 comments on commit ebdf41b

Please sign in to comment.