Skip to content

Commit 4b70d20

Browse files
committed
Rust: Rework call resolution and type inference for calls
1 parent e12e904 commit 4b70d20

File tree

11 files changed

+2895
-1556
lines changed

11 files changed

+2895
-1556
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: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,96 @@ 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+
/** Gets the type parameter representing the element type. */
307+
TypeParam getElementTypeParam() { result = this.getGenericParamList().getTypeParam(0) }
308+
}

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

Lines changed: 5 additions & 3 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()
@@ -963,7 +963,9 @@ final class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof T
963963
Path getABoundPath() { result = super.getATypeBound().getTypeRepr().(PathTypeRepr).getPath() }
964964

965965
pragma[nomagic]
966-
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
966+
ItemNode resolveBound(Path path) { path = this.getABoundPath() and result = resolvePath(path) }
967+
968+
ItemNode resolveABound() { result = this.resolveBound(_) }
967969

968970
override AssocItemNode getAnAssocItem() { result = this.getADescendant() }
969971

@@ -2101,7 +2103,7 @@ private predicate builtin(string name, ItemNode i) {
21012103

21022104
/** Provides predicates for debugging the path resolution implementation. */
21032105
private module Debug {
2104-
private Locatable getRelevantLocatable() {
2106+
Locatable getRelevantLocatable() {
21052107
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
21062108
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
21072109
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
@@ -624,3 +625,27 @@ final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeR
624625
implTraitTypeParam(this, _, result.(TypeParamTypeParameter).getTypeParam())
625626
}
626627
}
628+
629+
/**
630+
* Holds if `root` is a valid complex [`self` root type][1], with type
631+
* parameter `tp`.
632+
*
633+
* [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html#r-items.associated.fn.method.self-ty
634+
*/
635+
pragma[nomagic]
636+
predicate complexSelfRoot(Type root, TypeParameter tp) {
637+
tp = root.(RefType).getPositionalTypeParameter(_)
638+
or
639+
exists(Struct s |
640+
root = TStruct(s) and
641+
tp = root.getPositionalTypeParameter(0)
642+
|
643+
s instanceof BoxStruct
644+
or
645+
s instanceof RcStruct
646+
or
647+
s instanceof ArcStruct
648+
or
649+
s instanceof PinStruct
650+
)
651+
}

0 commit comments

Comments
 (0)