Skip to content

Commit 79e0615

Browse files
authored
Merge pull request #18813 from github/redsun82/rust-turn-off-ra-resolution
Rust: add flag to turn off extractor path resolution
2 parents 08c9f6f + ee61fdc commit 79e0615

File tree

10 files changed

+218
-5
lines changed

10 files changed

+218
-5
lines changed

rust/codeql-extractor.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,7 @@ options:
7878
Collect flame graph data using the `tracing-flame` crate. To render a flame graph
7979
or chart, run the `inferno-flamegraph` command. See also: https://crates.io/crates/tracing-flame
8080
type: string
81+
skip_path_resolution:
82+
title: Skip path resolution
83+
description: >
84+
Skip path resolution. This is experimental, while we move path resolution from the extractor to the QL library.

rust/extractor/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub struct Config {
6666
pub build_script_command: Vec<String>,
6767
pub extra_includes: Vec<PathBuf>,
6868
pub proc_macro_server: Option<PathBuf>,
69+
pub skip_path_resolution: bool,
6970
}
7071

7172
impl Config {

rust/extractor/src/main.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::diagnostics::{ExtractionStep, emit_extraction_diagnostics};
22
use crate::rust_analyzer::path_to_file_id;
3+
use crate::translate::ResolvePaths;
34
use crate::trap::TrapId;
45
use anyhow::Context;
56
use archive::Archiver;
@@ -44,7 +45,7 @@ impl<'a> Extractor<'a> {
4445
}
4546
}
4647

47-
fn extract(&mut self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) {
48+
fn extract(&mut self, rust_analyzer: &RustAnalyzer, file: &Path, resolve_paths: ResolvePaths) {
4849
self.archiver.archive(file);
4950

5051
let before_parse = Instant::now();
@@ -67,6 +68,7 @@ impl<'a> Extractor<'a> {
6768
label,
6869
line_index,
6970
semantics_info.as_ref().ok(),
71+
resolve_paths,
7072
);
7173

7274
for err in errors {
@@ -103,12 +105,17 @@ impl<'a> Extractor<'a> {
103105
file: &Path,
104106
semantics: &Semantics<'_, RootDatabase>,
105107
vfs: &Vfs,
108+
resolve_paths: ResolvePaths,
106109
) {
107-
self.extract(&RustAnalyzer::new(vfs, semantics), file);
110+
self.extract(&RustAnalyzer::new(vfs, semantics), file, resolve_paths);
108111
}
109112

110113
pub fn extract_without_semantics(&mut self, file: &Path, reason: &str) {
111-
self.extract(&RustAnalyzer::WithoutSemantics { reason }, file);
114+
self.extract(
115+
&RustAnalyzer::WithoutSemantics { reason },
116+
file,
117+
ResolvePaths::No,
118+
);
112119
}
113120

114121
pub fn load_manifest(
@@ -239,14 +246,21 @@ fn main() -> anyhow::Result<()> {
239246
}
240247
let cwd = cwd()?;
241248
let (cargo_config, load_cargo_config) = cfg.to_cargo_config(&cwd);
249+
let resolve_paths = if cfg.skip_path_resolution {
250+
ResolvePaths::No
251+
} else {
252+
ResolvePaths::Yes
253+
};
242254
for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) {
243255
if let Some((ref db, ref vfs)) =
244256
extractor.load_manifest(manifest, &cargo_config, &load_cargo_config)
245257
{
246258
let semantics = Semantics::new(db);
247259
for file in files {
248260
match extractor.load_source(file, &semantics, vfs) {
249-
Ok(()) => extractor.extract_with_semantics(file, &semantics, vfs),
261+
Ok(()) => {
262+
extractor.extract_with_semantics(file, &semantics, vfs, resolve_paths)
263+
}
250264
Err(reason) => extractor.extract_without_semantics(file, &reason),
251265
};
252266
}

rust/extractor/src/translate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ mod base;
22
mod generated;
33
mod mappings;
44

5-
pub use base::Translator;
5+
pub use base::{ResolvePaths, Translator};

rust/extractor/src/translate/base.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,20 @@ macro_rules! dispatch_to_tracing {
8686
};
8787
}
8888

89+
#[derive(Copy, Clone, PartialEq, Eq)]
90+
pub enum ResolvePaths {
91+
Yes,
92+
No,
93+
}
94+
8995
pub struct Translator<'a> {
9096
pub trap: TrapFile,
9197
path: &'a str,
9298
label: Label<generated::File>,
9399
line_index: LineIndex,
94100
file_id: Option<EditionedFileId>,
95101
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
102+
resolve_paths: ResolvePaths,
96103
}
97104

98105
const UNKNOWN_LOCATION: (LineCol, LineCol) =
@@ -105,6 +112,7 @@ impl<'a> Translator<'a> {
105112
label: Label<generated::File>,
106113
line_index: LineIndex,
107114
semantic_info: Option<&FileSemanticInformation<'a>>,
115+
resolve_paths: ResolvePaths,
108116
) -> Translator<'a> {
109117
Translator {
110118
trap,
@@ -113,6 +121,7 @@ impl<'a> Translator<'a> {
113121
line_index,
114122
file_id: semantic_info.map(|i| i.file_id),
115123
semantics: semantic_info.map(|i| i.semantics),
124+
resolve_paths,
116125
}
117126
}
118127
fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> {
@@ -500,6 +509,9 @@ impl<'a> Translator<'a> {
500509
item: &T,
501510
label: Label<generated::Addressable>,
502511
) {
512+
if self.resolve_paths == ResolvePaths::No {
513+
return;
514+
}
503515
(|| {
504516
let sema = self.semantics.as_ref()?;
505517
let def = T::Hir::try_from_source(item, sema)?;
@@ -520,6 +532,9 @@ impl<'a> Translator<'a> {
520532
item: &ast::Variant,
521533
label: Label<generated::Variant>,
522534
) {
535+
if self.resolve_paths == ResolvePaths::No {
536+
return;
537+
}
523538
(|| {
524539
let sema = self.semantics.as_ref()?;
525540
let def = sema.to_enum_variant_def(item)?;
@@ -540,6 +555,9 @@ impl<'a> Translator<'a> {
540555
item: &impl PathAst,
541556
label: Label<generated::Resolvable>,
542557
) {
558+
if self.resolve_paths == ResolvePaths::No {
559+
return;
560+
}
543561
(|| {
544562
let path = item.path()?;
545563
let sema = self.semantics.as_ref()?;
@@ -560,6 +578,9 @@ impl<'a> Translator<'a> {
560578
item: &ast::MethodCallExpr,
561579
label: Label<generated::MethodCallExpr>,
562580
) {
581+
if self.resolve_paths == ResolvePaths::No {
582+
return;
583+
}
563584
(|| {
564585
let sema = self.semantics.as_ref()?;
565586
let resolved = sema.resolve_method_call_fallback(item)?;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// would prefer to write `include!("../canonical_paths/anonymous.rs");`
2+
// but `include!` does not work with out-of-dir files
3+
4+
use super::regular::Trait;
5+
6+
fn canonicals() {
7+
struct OtherStruct;
8+
9+
trait OtherTrait {
10+
fn g(&self);
11+
}
12+
13+
impl OtherTrait for OtherStruct {
14+
fn g(&self) {}
15+
}
16+
17+
impl OtherTrait for crate::regular::Struct {
18+
fn g(&self) {}
19+
}
20+
21+
impl crate::regular::Trait for OtherStruct {
22+
fn f(&self) {}
23+
}
24+
25+
fn nested() {
26+
struct OtherStruct;
27+
}
28+
29+
fn usage() {
30+
let s = OtherStruct {};
31+
s.f();
32+
s.g();
33+
nested();
34+
}
35+
}
36+
37+
fn other() {
38+
struct OtherStruct;
39+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
canonicalPaths
2+
| anonymous.rs:4:1:4:26 | Use | None | None |
3+
| anonymous.rs:6:1:35:1 | fn canonicals | None | None |
4+
| anonymous.rs:7:5:7:23 | struct OtherStruct | None | None |
5+
| anonymous.rs:9:5:11:5 | trait OtherTrait | None | None |
6+
| anonymous.rs:10:9:10:20 | fn g | None | None |
7+
| anonymous.rs:13:5:15:5 | impl OtherTrait for OtherStruct { ... } | None | None |
8+
| anonymous.rs:14:9:14:22 | fn g | None | None |
9+
| anonymous.rs:17:5:19:5 | impl OtherTrait for ...::Struct { ... } | None | None |
10+
| anonymous.rs:18:9:18:22 | fn g | None | None |
11+
| anonymous.rs:21:5:23:5 | impl ...::Trait for OtherStruct { ... } | None | None |
12+
| anonymous.rs:22:9:22:22 | fn f | None | None |
13+
| anonymous.rs:25:5:27:5 | fn nested | None | None |
14+
| anonymous.rs:26:9:26:27 | struct OtherStruct | None | None |
15+
| anonymous.rs:29:5:34:5 | fn usage | None | None |
16+
| anonymous.rs:37:1:39:1 | fn other | None | None |
17+
| anonymous.rs:38:5:38:23 | struct OtherStruct | None | None |
18+
| lib.rs:1:1:1:14 | mod anonymous | None | None |
19+
| lib.rs:2:1:2:12 | mod regular | None | None |
20+
| regular.rs:4:1:5:18 | struct Struct | None | None |
21+
| regular.rs:7:1:9:1 | trait Trait | None | None |
22+
| regular.rs:8:5:8:16 | fn f | None | None |
23+
| regular.rs:11:1:13:1 | impl Trait for Struct { ... } | None | None |
24+
| regular.rs:12:5:12:18 | fn f | None | None |
25+
| regular.rs:15:1:17:1 | impl Struct { ... } | None | None |
26+
| regular.rs:16:5:16:18 | fn g | None | None |
27+
| regular.rs:19:1:21:1 | trait TraitWithBlanketImpl | None | None |
28+
| regular.rs:20:5:20:16 | fn h | None | None |
29+
| regular.rs:23:1:25:1 | impl TraitWithBlanketImpl for T { ... } | None | None |
30+
| regular.rs:24:5:24:18 | fn h | None | None |
31+
| regular.rs:27:1:27:12 | fn free | None | None |
32+
| regular.rs:29:1:35:1 | fn usage | None | None |
33+
| regular.rs:37:1:41:1 | enum MyEnum | None | None |
34+
| regular.rs:43:1:49:1 | fn enum_qualified_usage | None | None |
35+
| regular.rs:51:1:58:1 | fn enum_unqualified_usage | None | None |
36+
| regular.rs:54:5:54:18 | Use | None | None |
37+
| regular.rs:60:1:66:1 | fn enum_match | None | None |
38+
resolvedPaths
39+
| anonymous.rs:30:17:30:30 | OtherStruct {...} | None | None |
40+
| anonymous.rs:31:9:31:9 | s | None | None |
41+
| anonymous.rs:31:9:31:13 | s.f(...) | None | None |
42+
| anonymous.rs:32:9:32:9 | s | None | None |
43+
| anonymous.rs:32:9:32:13 | s.g(...) | None | None |
44+
| anonymous.rs:33:9:33:14 | nested | None | None |
45+
| regular.rs:30:13:30:21 | Struct {...} | None | None |
46+
| regular.rs:31:5:31:5 | s | None | None |
47+
| regular.rs:31:5:31:9 | s.f(...) | None | None |
48+
| regular.rs:32:5:32:5 | s | None | None |
49+
| regular.rs:32:5:32:9 | s.g(...) | None | None |
50+
| regular.rs:33:5:33:5 | s | None | None |
51+
| regular.rs:33:5:33:9 | s.h(...) | None | None |
52+
| regular.rs:34:5:34:8 | free | None | None |
53+
| regular.rs:44:9:44:26 | ...::None::<...> | None | None |
54+
| regular.rs:45:9:45:20 | ...::Some | None | None |
55+
| regular.rs:46:9:46:24 | ...::Variant1 | None | None |
56+
| regular.rs:47:9:47:24 | ...::Variant2 | None | None |
57+
| regular.rs:48:9:48:33 | ...::Variant3 {...} | None | None |
58+
| regular.rs:52:9:52:18 | None::<...> | None | None |
59+
| regular.rs:53:9:53:12 | Some | None | None |
60+
| regular.rs:55:9:55:16 | Variant1 | None | None |
61+
| regular.rs:56:9:56:16 | Variant2 | None | None |
62+
| regular.rs:57:9:57:25 | Variant3 {...} | None | None |
63+
| regular.rs:61:11:61:11 | e | None | None |
64+
| regular.rs:62:9:62:24 | ...::Variant1 | None | None |
65+
| regular.rs:63:9:63:27 | ...::Variant2(...) | None | None |
66+
| regular.rs:64:9:64:31 | ...::Variant3 {...} | None | None |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extractor-tests/canonical_path/canonical_paths.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
skip_path_resolution: true
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// would prefer to write `include!("../canonical_path/regular.rs");
2+
// but `include!` does not work with out-of-dir files
3+
4+
#[derive(Eq, PartialEq)]
5+
pub struct Struct;
6+
7+
pub trait Trait {
8+
fn f(&self);
9+
}
10+
11+
impl Trait for Struct {
12+
fn f(&self) {}
13+
}
14+
15+
impl Struct {
16+
fn g(&self) {}
17+
}
18+
19+
trait TraitWithBlanketImpl {
20+
fn h(&self);
21+
}
22+
23+
impl<T: Eq> TraitWithBlanketImpl for T {
24+
fn h(&self) {}
25+
}
26+
27+
fn free() {}
28+
29+
fn usage() {
30+
let s = Struct {};
31+
s.f();
32+
s.g();
33+
s.h();
34+
free();
35+
}
36+
37+
enum MyEnum {
38+
Variant1,
39+
Variant2(usize),
40+
Variant3 { x: usize },
41+
}
42+
43+
fn enum_qualified_usage() {
44+
_ = Option::None::<()>;
45+
_ = Option::Some(0);
46+
_ = MyEnum::Variant1;
47+
_ = MyEnum::Variant2(0);
48+
_ = MyEnum::Variant3 { x: 1 };
49+
}
50+
51+
fn enum_unqualified_usage() {
52+
_ = None::<()>;
53+
_ = Some(0);
54+
use MyEnum::*;
55+
_ = Variant1;
56+
_ = Variant2(0);
57+
_ = Variant3 { x: 1 };
58+
}
59+
60+
fn enum_match(e: MyEnum) {
61+
match e {
62+
MyEnum::Variant1 => {}
63+
MyEnum::Variant2(_) => {}
64+
MyEnum::Variant3 { .. } => {}
65+
}
66+
}

0 commit comments

Comments
 (0)