Skip to content

Commit 27874ca

Browse files
authored
Merge pull request #20973 from hvitved/rust/type-inference-distinguish-mut-ref
Rust: Distinguish `&mut T` from `&T` in type inference
2 parents f169251 + aae6cd9 commit 27874ca

File tree

35 files changed

+542
-672
lines changed

35 files changed

+542
-672
lines changed

rust/ql/lib/codeql/rust/dataflow/internal/Node.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ final class ExprArgumentNode extends ArgumentNode, ExprNode {
230230
ExprArgumentNode() {
231231
isArgumentForCall(n, call_, pos_) and
232232
not TypeInference::implicitDeref(n) and
233-
not TypeInference::implicitBorrow(n)
233+
not TypeInference::implicitBorrow(n, _)
234234
}
235235

236236
override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
@@ -579,7 +579,7 @@ newtype TNode =
579579
TypeInference::implicitDeref(n) and
580580
borrow = false
581581
or
582-
TypeInference::implicitBorrow(n) and
582+
TypeInference::implicitBorrow(n, _) and
583583
borrow = true
584584
} or
585585
TDerefOutNode(DerefExpr de, Boolean isPost) or

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module Impl {
3030
op = "!" and path = "core::ops::bit::Not" and method = "not" and borrows = 0
3131
or
3232
// Dereference
33+
// todo: handle `core::ops::deref::DerefMut`
3334
op = "*" and path = "core::ops::deref::Deref" and method = "deref" and borrows = 1
3435
)
3536
or

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,20 @@ class ArrayType extends BuiltinType {
162162
override string getDisplayName() { result = "[;]" }
163163
}
164164

165-
/** The builtin reference type `&T`. */
166-
class RefType extends BuiltinType {
167-
RefType() { this.getName() = "Ref" }
165+
/** A builtin reference type `&T` or `&mut T`. */
166+
abstract private class RefTypeImpl extends BuiltinType { }
167+
168+
final class RefType = RefTypeImpl;
169+
170+
/** The builtin shared reference type `&T`. */
171+
class RefSharedType extends RefTypeImpl {
172+
RefSharedType() { this.getName() = "Ref" }
168173

169174
override string getDisplayName() { result = "&" }
170175
}
171176

172-
/** The builtin reference type `&mut T`. */
173-
class RefMutType extends BuiltinType {
177+
/** The builtin mutable reference type `&mut T`. */
178+
class RefMutType extends RefTypeImpl {
174179
RefMutType() { this.getName() = "RefMut" }
175180

176181
override string getDisplayName() { result = "&mut" }

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,12 @@ private TypeItemNode resolveBuiltin(TypeRepr tr) {
771771
tr instanceof ArrayTypeRepr and
772772
result instanceof Builtins::ArrayType
773773
or
774-
tr instanceof RefTypeRepr and
775-
result instanceof Builtins::RefType
774+
tr =
775+
any(RefTypeRepr rtr |
776+
if rtr.isMut()
777+
then result instanceof Builtins::RefMutType
778+
else result instanceof Builtins::RefSharedType
779+
)
776780
or
777781
tr.(PtrTypeRepr).isConst() and
778782
result instanceof Builtins::PtrConstType

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

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -224,21 +224,30 @@ TypeParamTypeParameter getArrayTypeParameter() {
224224
result = any(ArrayType t).getPositionalTypeParameter(0)
225225
}
226226

227-
/**
228-
* A reference type.
229-
*
230-
* Reference types like `& i64` are modeled as normal generic types
231-
* with a single type argument.
232-
*/
233-
class RefType extends StructType {
234-
RefType() { this.getStruct() instanceof Builtins::RefType }
227+
abstract class RefType extends StructType { }
228+
229+
class RefMutType extends RefType {
230+
RefMutType() { this.getStruct() instanceof Builtins::RefMutType }
231+
232+
override string toString() { result = "&mut" }
233+
}
234+
235+
class RefSharedType extends RefType {
236+
RefSharedType() { this.getStruct() instanceof Builtins::RefSharedType }
235237

236238
override string toString() { result = "&" }
237239
}
238240

239241
pragma[nomagic]
240-
TypeParamTypeParameter getRefTypeParameter() {
241-
result = any(RefType t).getPositionalTypeParameter(0)
242+
RefType getRefType(boolean isMutable) {
243+
isMutable = true and result instanceof RefMutType
244+
or
245+
isMutable = false and result instanceof RefSharedType
246+
}
247+
248+
pragma[nomagic]
249+
TypeParamTypeParameter getRefTypeParameter(boolean isMutable) {
250+
result = getRefType(isMutable).getPositionalTypeParameter(0)
242251
}
243252

244253
/**

0 commit comments

Comments
 (0)