Skip to content

Commit 64145ab

Browse files
authored
Merge pull request #19369 from hvitved/rust/crate-graph-self-param
Rust: Extract `SelfParam`s from crate graph
2 parents 6de38b1 + 7e20536 commit 64145ab

File tree

5 files changed

+61
-10
lines changed

5 files changed

+61
-10
lines changed

rust/extractor/src/crate_graph.rs

+37-8
Original file line numberDiff line numberDiff line change
@@ -383,25 +383,54 @@ fn emit_function(
383383
assert_eq!(sig.binders.len(Interner), parameters.len());
384384
let sig = sig.skip_binders();
385385
let ty_vars = &[parameters];
386+
let function_data = db.function_data(function);
387+
let mut self_param = None;
386388
let params = sig
387389
.params()
388390
.iter()
389-
.map(|p| {
391+
.enumerate()
392+
.filter_map(|(idx, p)| {
390393
let type_repr = emit_hir_ty(trap, db, ty_vars, p);
391-
trap.emit(generated::Param {
392-
id: trap::TrapId::Star,
393-
attrs: vec![],
394-
type_repr,
395-
pat: None,
396-
})
394+
395+
if idx == 0 && function_data.has_self_param() {
396+
// Check if the self parameter is a reference
397+
let (is_ref, is_mut) = match p.kind(Interner) {
398+
chalk_ir::TyKind::Ref(mutability, _, _) => {
399+
(true, matches!(mutability, chalk_ir::Mutability::Mut))
400+
}
401+
chalk_ir::TyKind::Raw(mutability, _) => {
402+
(false, matches!(mutability, chalk_ir::Mutability::Mut))
403+
}
404+
_ => (false, false),
405+
};
406+
407+
self_param = Some(trap.emit(generated::SelfParam {
408+
id: trap::TrapId::Star,
409+
attrs: vec![],
410+
type_repr,
411+
is_ref,
412+
is_mut,
413+
lifetime: None,
414+
name: None,
415+
}));
416+
None
417+
} else {
418+
Some(trap.emit(generated::Param {
419+
id: trap::TrapId::Star,
420+
attrs: vec![],
421+
type_repr,
422+
pat: None,
423+
}))
424+
}
397425
})
398426
.collect();
399427

400428
let ret_type = emit_hir_ty(trap, db, ty_vars, sig.ret());
429+
401430
let param_list = trap.emit(generated::ParamList {
402431
id: trap::TrapId::Star,
403432
params,
404-
self_param: None,
433+
self_param,
405434
});
406435
let ret_type = ret_type.map(|ret_type| {
407436
trap.emit(generated::RetTypeRepr {

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ final class CloneCallable extends SummarizedCallable::Range {
1818
final override predicate propagatesFlow(
1919
string input, string output, boolean preservesValue, string model
2020
) {
21-
input = "Argument[self]" and
21+
// The `clone` method takes a `&self` parameter and dereferences it;
22+
// make sure to not clone the reference itself
23+
input = ["Argument[self].Reference", "Argument[self].WithoutReference"] and
2224
output = "ReturnValue" and
2325
preservesValue = true and
2426
model = "generated"

rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected

+6
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@ models
88
| 7 | Summary: lang:core; crate::ptr::write; Argument[1]; Argument[0].Reference; value |
99
edges
1010
| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:19 | a.unwrap() | provenance | MaD:2 |
11+
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:13 | a [Some] | provenance | |
1112
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | MaD:1 |
1213
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | generated |
1314
| main.rs:12:13:12:28 | Some(...) [Some] | main.rs:12:9:12:9 | a [Some] | provenance | |
1415
| main.rs:12:18:12:27 | source(...) | main.rs:12:13:12:28 | Some(...) [Some] | provenance | |
1516
| main.rs:14:9:14:9 | b [Some] | main.rs:15:10:15:19 | b.unwrap() | provenance | MaD:2 |
17+
| main.rs:14:13:14:13 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | generated |
1618
| main.rs:14:13:14:21 | a.clone() [Some] | main.rs:14:9:14:9 | b [Some] | provenance | |
1719
| main.rs:19:9:19:9 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:5 |
20+
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:13 | a [Ok] | provenance | |
1821
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | MaD:4 |
1922
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | generated |
2023
| main.rs:19:31:19:44 | Ok(...) [Ok] | main.rs:19:9:19:9 | a [Ok] | provenance | |
2124
| main.rs:19:34:19:43 | source(...) | main.rs:19:31:19:44 | Ok(...) [Ok] | provenance | |
2225
| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:5 |
26+
| main.rs:21:13:21:13 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | generated |
2327
| main.rs:21:13:21:21 | a.clone() [Ok] | main.rs:21:9:21:9 | b [Ok] | provenance | |
2428
| main.rs:26:9:26:9 | a | main.rs:27:10:27:10 | a | provenance | |
2529
| main.rs:26:9:26:9 | a | main.rs:28:13:28:21 | a.clone() | provenance | generated |
@@ -57,13 +61,15 @@ nodes
5761
| main.rs:12:18:12:27 | source(...) | semmle.label | source(...) |
5862
| main.rs:13:10:13:19 | a.unwrap() | semmle.label | a.unwrap() |
5963
| main.rs:14:9:14:9 | b [Some] | semmle.label | b [Some] |
64+
| main.rs:14:13:14:13 | a [Some] | semmle.label | a [Some] |
6065
| main.rs:14:13:14:21 | a.clone() [Some] | semmle.label | a.clone() [Some] |
6166
| main.rs:15:10:15:19 | b.unwrap() | semmle.label | b.unwrap() |
6267
| main.rs:19:9:19:9 | a [Ok] | semmle.label | a [Ok] |
6368
| main.rs:19:31:19:44 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] |
6469
| main.rs:19:34:19:43 | source(...) | semmle.label | source(...) |
6570
| main.rs:20:10:20:19 | a.unwrap() | semmle.label | a.unwrap() |
6671
| main.rs:21:9:21:9 | b [Ok] | semmle.label | b [Ok] |
72+
| main.rs:21:13:21:13 | a [Ok] | semmle.label | a [Ok] |
6773
| main.rs:21:13:21:21 | a.clone() [Ok] | semmle.label | a.clone() [Ok] |
6874
| main.rs:22:10:22:19 | b.unwrap() | semmle.label | b.unwrap() |
6975
| main.rs:26:9:26:9 | a | semmle.label | a |

rust/ql/test/library-tests/type-inference/type-inference.ql

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import codeql.rust.internal.TypeInference as TypeInference
44
import TypeInference
55

66
query predicate inferType(AstNode n, TypePath path, Type t) {
7-
t = TypeInference::inferType(n, path)
7+
t = TypeInference::inferType(n, path) and
8+
n.fromSource()
89
}
910

1011
module ResolveTest implements TestSig {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
multipleMethodCallTargets
2+
| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
3+
| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
4+
| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
5+
| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
6+
| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
7+
| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
8+
| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
9+
| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
10+
| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
11+
| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
12+
| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |
13+
| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str() | file://:0:0:0:0 | fn as_str |

0 commit comments

Comments
 (0)