Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
35 changes: 21 additions & 14 deletions rust/ql/lib/codeql/rust/frameworks/stdlib/Builtins.qll
Original file line number Diff line number Diff line change
Expand Up @@ -46,72 +46,79 @@ class Str extends BuiltinType {
Str() { this.getName() = "str" }
}

/**
* A numeric type.
*
* See: https://doc.rust-lang.org/reference/types/numeric.html
*/
abstract class NumericType extends BuiltinType { }

/** The builtin `i8` type. */
class I8 extends BuiltinType {
class I8 extends NumericType {
I8() { this.getName() = "i8" }
}

/** The builtin `i16` type. */
class I16 extends BuiltinType {
class I16 extends NumericType {
I16() { this.getName() = "i16" }
}

/** The builtin `i32` type. */
class I32 extends BuiltinType {
class I32 extends NumericType {
I32() { this.getName() = "i32" }
}

/** The builtin `i64` type. */
class I64 extends BuiltinType {
class I64 extends NumericType {
I64() { this.getName() = "i64" }
}

/** The builtin `i128` type. */
class I128 extends BuiltinType {
class I128 extends NumericType {
I128() { this.getName() = "i128" }
}

/** The builtin `u8` type. */
class U8 extends BuiltinType {
class U8 extends NumericType {
U8() { this.getName() = "u8" }
}

/** The builtin `u16` type. */
class U16 extends BuiltinType {
class U16 extends NumericType {
U16() { this.getName() = "u16" }
}

/** The builtin `u32` type. */
class U32 extends BuiltinType {
class U32 extends NumericType {
U32() { this.getName() = "u32" }
}

/** The builtin `u64` type. */
class U64 extends BuiltinType {
class U64 extends NumericType {
U64() { this.getName() = "u64" }
}

/** The builtin `u128` type. */
class U128 extends BuiltinType {
class U128 extends NumericType {
U128() { this.getName() = "u128" }
}

/** The builtin `usize` type. */
class Usize extends BuiltinType {
class Usize extends NumericType {
Usize() { this.getName() = "usize" }
}

/** The builtin `isize` type. */
class Isize extends BuiltinType {
class Isize extends NumericType {
Isize() { this.getName() = "isize" }
}

/** The builtin `f32` type. */
class F32 extends BuiltinType {
class F32 extends NumericType {
F32() { this.getName() = "f32" }
}

/** The builtin `f64` type. */
class F64 extends BuiltinType {
class F64 extends NumericType {
F64() { this.getName() = "f64" }
}
2 changes: 2 additions & 0 deletions rust/ql/lib/codeql/rust/internal/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class StructType extends StructOrEnumType, TStruct {

StructType() { this = TStruct(struct) }

Struct asStruct() { result = struct }

override ItemNode asItemNode() { result = struct }

override StructField getStructField(string name) { result = struct.getStructField(name) }
Expand Down
15 changes: 13 additions & 2 deletions rust/ql/lib/codeql/rust/internal/TypeInference.qll
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,10 @@ module CertainTypeInference {
}

private Type inferLogicalOperationType(AstNode n, TypePath path) {
exists(Builtins::Bool t, BinaryLogicalOperation be |
exists(BinaryLogicalOperation be |
n = [be, be.getLhs(), be.getRhs()] and
path.isEmpty() and
result = TStruct(t)
result.(StructType).asStruct() instanceof Builtins::Bool
)
}

Expand Down Expand Up @@ -1467,6 +1467,11 @@ private Type inferLiteralType(LiteralExpr le, TypePath path, boolean certain) {
certain = true
}

predicate uncertainNumberLiteral(LiteralExpr le) {
le instanceof NumberLiteralExpr and
not CertainTypeInference::hasInferredCertainType(le)
}

pragma[nomagic]
private TraitType getFutureTraitType() { result.getTrait() instanceof FutureTrait }

Expand Down Expand Up @@ -2433,6 +2438,12 @@ private module Cached {
then not CertainTypeInference::certainTypeConflict(n, path, result)
else any()
) and
// Don't infer non-numerical types for number literals.
(
if uncertainNumberLiteral(n)
then result.(StructType).asStruct() instanceof Builtins::NumericType and path.isEmpty()
else any()
) and
(
result = inferAssignmentOperationType(n, path)
or
Expand Down