Skip to content

Commit 07829e5

Browse files
authored
Merge pull request #19421 from github/aibaars/rust-builtin-types
Rust: extract declarations of builtin types
2 parents d1e769b + 778f46d commit 07829e5

21 files changed

+154
-23
lines changed

rust/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pkg_filegroup(
3636
srcs = [
3737
":tools-arch",
3838
"//rust/tools",
39+
"//rust/tools/builtins",
3940
],
4041
prefix = "tools",
4142
)

rust/extractor/src/main.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::{
1717
collections::HashMap,
1818
path::{Path, PathBuf},
1919
};
20+
use std::{env, fs};
2021
use tracing::{error, info, warn};
2122
use tracing_subscriber::layer::SubscriberExt;
2223
use tracing_subscriber::util::SubscriberInitExt;
@@ -77,17 +78,19 @@ impl<'a> Extractor<'a> {
7778
}
7879
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
7980
if let Err(reason) = semantics_info {
80-
let message = format!("semantic analyzer unavailable ({reason})");
81-
let full_message = format!(
82-
"{message}: macro expansion, call graph, and type inference will be skipped."
83-
);
84-
translator.emit_diagnostic(
85-
trap::DiagnosticSeverity::Warning,
86-
"semantics".to_owned(),
87-
message,
88-
full_message,
89-
no_location,
90-
);
81+
if !reason.is_empty() {
82+
let message = format!("semantic analyzer unavailable ({reason})");
83+
let full_message = format!(
84+
"{message}: macro expansion, call graph, and type inference will be skipped."
85+
);
86+
translator.emit_diagnostic(
87+
trap::DiagnosticSeverity::Warning,
88+
"semantics".to_owned(),
89+
message,
90+
full_message,
91+
no_location,
92+
);
93+
}
9194
}
9295
translator.emit_source_file(ast);
9396
translator.trap.commit().unwrap_or_else(|err| {
@@ -276,5 +279,16 @@ fn main() -> anyhow::Result<()> {
276279
}
277280
}
278281
}
282+
let builtins_dir = env::var("CODEQL_EXTRACTOR_RUST_ROOT")
283+
.map(|path| Path::new(&path).join("tools").join("builtins"))?;
284+
let builtins = fs::read_dir(builtins_dir).context("failed to read builtins directory")?;
285+
for entry in builtins {
286+
let entry = entry.context("failed to read builtins directory")?;
287+
let path = entry.path();
288+
if path.extension().is_some_and(|ext| ext == "rs") {
289+
extractor.extract_without_semantics(&path, "");
290+
}
291+
}
292+
279293
extractor.emit_extraction_diagnostics(start, &cfg)
280294
}

rust/ql/integration-tests/hello-project/diagnostics.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"pretty": "__REDACTED__"
3131
}
3232
},
33-
"numberOfFiles": 5,
33+
"numberOfFiles": 6,
3434
"numberOfManifests": 1
3535
},
3636
"severity": "note",

rust/ql/integration-tests/hello-project/steps.cargo.expected

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
| Cargo.toml:0:0:0:0 | LoadManifest(Cargo.toml) |
2+
| file:///types.rs:0:0:0:0 | Extract(/types.rs) |
3+
| file:///types.rs:0:0:0:0 | Parse(/types.rs) |
24
| file://:0:0:0:0 | CrateGraph |
35
| file://:0:0:0:0 | FindManifests |
46
| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) |
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
11
import codeql.rust.elements.internal.ExtractorStep
22

3-
from ExtractorStep step
3+
private class Step instanceof ExtractorStep {
4+
string toString() {
5+
result = super.getAction() + "(" + this.getFilePath() + ")"
6+
or
7+
not super.hasFile() and result = super.getAction()
8+
}
9+
10+
private string getFilePath() {
11+
exists(File file | file = super.getFile() |
12+
exists(file.getRelativePath()) and result = file.getAbsolutePath()
13+
or
14+
not exists(file.getRelativePath()) and result = "/" + file.getBaseName()
15+
)
16+
}
17+
18+
predicate hasLocationInfo(
19+
string filepath, int startline, int startcolumn, int endline, int endcolumn
20+
) {
21+
super.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
22+
filepath = this.getFilePath()
23+
}
24+
}
25+
26+
from Step step
427
select step

rust/ql/integration-tests/hello-project/steps.rust-project.expected

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
| file:///types.rs:0:0:0:0 | Extract(/types.rs) |
2+
| file:///types.rs:0:0:0:0 | Parse(/types.rs) |
13
| file://:0:0:0:0 | CrateGraph |
24
| file://:0:0:0:0 | FindManifests |
35
| rust-project.json:0:0:0:0 | LoadManifest(rust-project.json) |

rust/ql/integration-tests/hello-project/summary.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
| Inconsistencies - Path resolution | 0 |
1010
| Inconsistencies - SSA | 0 |
1111
| Inconsistencies - data flow | 0 |
12-
| Lines of code extracted | 6 |
12+
| Lines of code extracted | 23 |
1313
| Lines of user code extracted | 6 |
1414
| Macro calls - resolved | 2 |
1515
| Macro calls - total | 2 |

rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"pretty": "__REDACTED__"
3131
}
3232
},
33-
"numberOfFiles": 4,
33+
"numberOfFiles": 5,
3434
"numberOfManifests": 1
3535
},
3636
"severity": "note",

rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"pretty": "__REDACTED__"
3131
}
3232
},
33-
"numberOfFiles": 4,
33+
"numberOfFiles": 5,
3434
"numberOfManifests": 1
3535
},
3636
"severity": "note",

rust/ql/integration-tests/hello-workspace/steps.cargo.expected

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) |
66
| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) |
77
| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) |
8+
| file:///types.rs:0:0:0:0 | Extract(/types.rs) |
9+
| file:///types.rs:0:0:0:0 | Parse(/types.rs) |
810
| file://:0:0:0:0 | CrateGraph |
911
| file://:0:0:0:0 | FindManifests |
1012
| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) |
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
11
import codeql.rust.elements.internal.ExtractorStep
22

3-
from ExtractorStep step
3+
private class Step instanceof ExtractorStep {
4+
string toString() {
5+
result = super.getAction() + "(" + this.getFilePath() + ")"
6+
or
7+
not super.hasFile() and result = super.getAction()
8+
}
9+
10+
private string getFilePath() {
11+
exists(File file | file = super.getFile() |
12+
exists(file.getRelativePath()) and result = file.getAbsolutePath()
13+
or
14+
not exists(file.getRelativePath()) and result = "/" + file.getBaseName()
15+
)
16+
}
17+
18+
predicate hasLocationInfo(
19+
string filepath, int startline, int startcolumn, int endline, int endcolumn
20+
) {
21+
super.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
22+
filepath = this.getFilePath()
23+
}
24+
}
25+
26+
from Step step
427
select step

rust/ql/integration-tests/hello-workspace/steps.rust-project.expected

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) |
55
| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) |
66
| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) |
7+
| file:///types.rs:0:0:0:0 | Extract(/types.rs) |
8+
| file:///types.rs:0:0:0:0 | Parse(/types.rs) |
79
| file://:0:0:0:0 | CrateGraph |
810
| file://:0:0:0:0 | FindManifests |
911
| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) |

rust/ql/integration-tests/hello-workspace/summary.cargo.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
| Inconsistencies - Path resolution | 0 |
1010
| Inconsistencies - SSA | 0 |
1111
| Inconsistencies - data flow | 0 |
12-
| Lines of code extracted | 9 |
12+
| Lines of code extracted | 26 |
1313
| Lines of user code extracted | 9 |
1414
| Macro calls - resolved | 2 |
1515
| Macro calls - total | 2 |

rust/ql/integration-tests/hello-workspace/summary.rust-project.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
| Inconsistencies - Path resolution | 0 |
1010
| Inconsistencies - SSA | 0 |
1111
| Inconsistencies - data flow | 0 |
12-
| Lines of code extracted | 9 |
12+
| Lines of code extracted | 26 |
1313
| Lines of user code extracted | 9 |
1414
| Macro calls - resolved | 2 |
1515
| Macro calls - total | 2 |

rust/ql/integration-tests/workspace-with-glob/steps.expected

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
| Cargo.toml:0:0:0:0 | LoadManifest(Cargo.toml) |
22
| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) |
33
| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) |
4+
| file:///types.rs:0:0:0:0 | Extract(/types.rs) |
5+
| file:///types.rs:0:0:0:0 | Parse(/types.rs) |
46
| file://:0:0:0:0 | CrateGraph |
57
| file://:0:0:0:0 | FindManifests |
68
| lib/src/lib.rs:0:0:0:0 | Extract(lib/src/lib.rs) |
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
11
import codeql.rust.elements.internal.ExtractorStep
22

3-
from ExtractorStep step
3+
private class Step instanceof ExtractorStep {
4+
string toString() {
5+
result = super.getAction() + "(" + this.getFilePath() + ")"
6+
or
7+
not super.hasFile() and result = super.getAction()
8+
}
9+
10+
private string getFilePath() {
11+
exists(File file | file = super.getFile() |
12+
exists(file.getRelativePath()) and result = file.getAbsolutePath()
13+
or
14+
not exists(file.getRelativePath()) and result = "/" + file.getBaseName()
15+
)
16+
}
17+
18+
predicate hasLocationInfo(
19+
string filepath, int startline, int startcolumn, int endline, int endcolumn
20+
) {
21+
super.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
22+
filepath = this.getFilePath()
23+
}
24+
}
25+
26+
from Step step
427
select step

rust/ql/test/TestUtils.qll

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
private import rust
22

3-
predicate toBeTested(Element e) { not e instanceof CrateElement }
3+
predicate toBeTested(Element e) { not e instanceof CrateElement and not e instanceof Builtin }
44

55
class CrateElement extends Element {
66
CrateElement() {
@@ -9,3 +9,7 @@ class CrateElement extends Element {
99
any(Crate c).getModule() = this.(AstNode).getParentNode*()
1010
}
1111
}
12+
13+
class Builtin extends AstNode {
14+
Builtin() { this.getFile().getAbsolutePath().matches("%/builtins/%.rs") }
15+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| 60 |
1+
| 77 |

rust/ql/test/query-tests/diagnostics/SummaryStatsReduced.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
| Inconsistencies - Path resolution | 0 |
1010
| Inconsistencies - SSA | 0 |
1111
| Inconsistencies - data flow | 0 |
12-
| Lines of code extracted | 60 |
12+
| Lines of code extracted | 77 |
1313
| Lines of user code extracted | 60 |
1414
| Macro calls - resolved | 8 |
1515
| Macro calls - total | 9 |

rust/tools/builtins/BUILD.bazel

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
load("//misc/bazel:pkg.bzl", "codeql_pkg_files")
2+
3+
codeql_pkg_files(
4+
name = "builtins",
5+
srcs = glob(["*.rs"]),
6+
prefix = "builtins",
7+
visibility = ["//rust:__subpackages__"],
8+
)

rust/tools/builtins/types.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// The Language Prelude: https://doc.rust-lang.org/reference/names/preludes.html#language-prelude
2+
3+
// Type namespace
4+
// Boolean type
5+
pub struct bool;
6+
// Textual types
7+
pub struct char;
8+
pub struct str;
9+
// Integer types
10+
pub struct i8;
11+
pub struct i16;
12+
pub struct i32;
13+
pub struct i64;
14+
pub struct i128;
15+
pub struct u8;
16+
pub struct u16;
17+
pub struct u32;
18+
pub struct u64;
19+
pub struct u128;
20+
// Machine-dependent integer types
21+
pub struct usize;
22+
pub struct isize;
23+
// floating-point types
24+
pub struct f32;
25+
pub struct f64;

0 commit comments

Comments
 (0)