Skip to content

Commit 1ee9924

Browse files
committed
Rust: Rework call resolution and type inference for calls
1 parent 6cd1550 commit 1ee9924

File tree

11 files changed

+2598
-1510
lines changed

11 files changed

+2598
-1510
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
1212
* the canonical path `path` and the method name `method`, and if it borrows its
1313
* first `borrows` arguments.
1414
*/
15-
private predicate isOverloaded(string op, int arity, string path, string method, int borrows) {
15+
predicate isOverloaded(string op, int arity, string path, string method, int borrows) {
1616
arity = 1 and
1717
(
1818
// Negation

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ module Impl {
4747
*/
4848
TypeBound getATypeBound() { result = this.getTypeBound(_) }
4949

50+
/** Holds if this type parameter has at least one type bound. */
51+
predicate hasTypeBound() { exists(this.getATypeBound()) }
52+
5053
override string toAbbreviatedString() { result = this.getName().getText() }
5154

5255
override string toStringImpl() { result = this.getName().getText() }

rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,95 @@ class StringStruct extends Struct {
213213
pragma[nomagic]
214214
StringStruct() { this.getCanonicalPath() = "alloc::string::String" }
215215
}
216+
217+
/**
218+
* The [`Deref` trait][1].
219+
*
220+
* [1]: https://doc.rust-lang.org/core/ops/trait.Deref.html
221+
*/
222+
class DerefTrait extends Trait {
223+
pragma[nomagic]
224+
DerefTrait() { this.getCanonicalPath() = "core::ops::deref::Deref" }
225+
226+
/** Gets the `deref` function. */
227+
Function getDerefFunction() { result = this.(TraitItemNode).getAssocItem("deref") }
228+
229+
/** Gets the `Target` associated type. */
230+
pragma[nomagic]
231+
TypeAlias getTargetType() {
232+
result = this.getAssocItemList().getAnAssocItem() and
233+
result.getName().getText() = "Target"
234+
}
235+
}
236+
237+
/**
238+
* The [`Index` trait][1].
239+
*
240+
* [1]: https://doc.rust-lang.org/std/ops/trait.Index.html
241+
*/
242+
class IndexTrait extends Trait {
243+
pragma[nomagic]
244+
IndexTrait() { this.getCanonicalPath() = "core::ops::index::Index" }
245+
246+
/** Gets the `index` function. */
247+
Function getIndexFunction() { result = this.(TraitItemNode).getAssocItem("index") }
248+
249+
/** Gets the `Output` associated type. */
250+
pragma[nomagic]
251+
TypeAlias getOutputType() {
252+
result = this.getAssocItemList().getAnAssocItem() and
253+
result.getName().getText() = "Output"
254+
}
255+
}
256+
257+
/**
258+
* The [`Box` struct][1].
259+
*
260+
* [1]: https://doc.rust-lang.org/std/boxed/struct.Box.html
261+
*/
262+
class BoxStruct extends Struct {
263+
pragma[nomagic]
264+
BoxStruct() { this.getCanonicalPath() = "alloc::boxed::Box" }
265+
}
266+
267+
/**
268+
* The [`Rc` struct][1].
269+
*
270+
* [1]: https://doc.rust-lang.org/std/rc/struct.Rc.html
271+
*/
272+
class RcStruct extends Struct {
273+
pragma[nomagic]
274+
RcStruct() { this.getCanonicalPath() = "alloc::rc::Rc" }
275+
}
276+
277+
/**
278+
* The [`Arc` struct][1].
279+
*
280+
* [1]: https://doc.rust-lang.org/std/sync/struct.Arc.html
281+
*/
282+
class ArcStruct extends Struct {
283+
pragma[nomagic]
284+
ArcStruct() { this.getCanonicalPath() = "alloc::sync::Arc" }
285+
}
286+
287+
/**
288+
* The [`Pin` struct][1].
289+
*
290+
* [1]: https://doc.rust-lang.org/std/pin/struct.Pin.html
291+
*/
292+
class PinStruct extends Struct {
293+
pragma[nomagic]
294+
PinStruct() { this.getCanonicalPath() = "core::pin::Pin" }
295+
}
296+
297+
/**
298+
* The [`Vec` struct][1].
299+
*
300+
* [1]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html
301+
*/
302+
class Vec extends Struct {
303+
pragma[nomagic]
304+
Vec() { this.getCanonicalPath() = "alloc::vec::Vec" }
305+
306+
TypeParam getElementTypeParam() { result = this.getGenericParamList().getTypeParam(0) }
307+
}

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
840840
}
841841
}
842842

843-
final private class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTraitTypeRepr {
843+
final class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTraitTypeRepr {
844844
pragma[nomagic]
845845
Path getABoundPath() {
846846
result = super.getTypeBoundList().getABound().getTypeRepr().(PathTypeRepr).getPath()
@@ -2091,7 +2091,7 @@ private predicate builtin(string name, ItemNode i) {
20912091

20922092
/** Provides predicates for debugging the path resolution implementation. */
20932093
private module Debug {
2094-
private Locatable getRelevantLocatable() {
2094+
Locatable getRelevantLocatable() {
20952095
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
20962096
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
20972097
filepath.matches("%/main.rs") and

rust/ql/lib/codeql/rust/internal/Type.qll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import TypeMention
66
private import codeql.rust.internal.CachedStages
77
private import codeql.rust.elements.internal.generated.Raw
88
private import codeql.rust.elements.internal.generated.Synth
9+
private import codeql.rust.frameworks.stdlib.Stdlib
910

1011
/**
1112
* Holds if a dyn trait type should have a type parameter associated with `n`. A
@@ -692,3 +693,27 @@ final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeR
692693
implTraitTypeParam(this, _, result.(TypeParamTypeParameter).getTypeParam())
693694
}
694695
}
696+
697+
/**
698+
* Holds if `root` is a valid complex [`self` root type][1], with type
699+
* parameter `tp`.
700+
*
701+
* [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html?highlight=self#r-items.associated.fn.method.self-ty
702+
*/
703+
pragma[nomagic]
704+
predicate complexSelfRoot(Type root, TypeParameter tp) {
705+
tp = root.(RefType).getPositionalTypeParameter(_)
706+
or
707+
exists(Struct s |
708+
root = TStruct(s) and
709+
tp = root.getPositionalTypeParameter(0)
710+
|
711+
s instanceof BoxStruct
712+
or
713+
s instanceof RcStruct
714+
or
715+
s instanceof ArcStruct
716+
or
717+
s instanceof PinStruct
718+
)
719+
}

0 commit comments

Comments
 (0)