Skip to content

Commit ae233d2

Browse files
committed
Rust: Guard library diagnostics
1 parent 575ff15 commit ae233d2

4 files changed

Lines changed: 55 additions & 19 deletions

File tree

rust/codeql-extractor.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,10 @@ options:
8888
Extract the full source code of dependencies instead of only extracting signatures.
8989
type: string
9090
pattern: "^(false|true)$"
91+
library_diagnostics:
92+
title: Emit dependency library diagnostics
93+
description: >
94+
Collect and emit detailed parse and macro-expansion diagnostics for dependency libraries.
95+
This can substantially increase extraction time.
96+
type: string
97+
pattern: "^(false|true)$"

rust/extractor/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub struct Config {
7373
pub extra_includes: Vec<PathBuf>,
7474
pub proc_macro_server: Option<PathBuf>,
7575
pub extract_dependencies_as_source: bool,
76+
pub library_diagnostics: bool,
7677
pub force_library_mode: bool, // for testing purposes
7778
}
7879

rust/extractor/src/main.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ pub mod trap;
3838
struct Extractor<'a> {
3939
archiver: &'a Archiver,
4040
traps: &'a trap::TrapFileProvider,
41+
library_diagnostics: bool,
4142
steps: Vec<ExtractionStep>,
4243
}
4344

4445
impl<'a> Extractor<'a> {
45-
pub fn new(archiver: &'a Archiver, traps: &'a trap::TrapFileProvider) -> Self {
46+
pub fn new(
47+
archiver: &'a Archiver,
48+
traps: &'a trap::TrapFileProvider,
49+
library_diagnostics: bool,
50+
) -> Self {
4651
Self {
4752
archiver,
4853
traps,
54+
library_diagnostics,
4955
steps: Vec::new(),
5056
}
5157
}
@@ -74,10 +80,13 @@ impl<'a> Extractor<'a> {
7480
line_index,
7581
semantics_info.as_ref().ok(),
7682
source_kind,
83+
self.library_diagnostics,
7784
);
7885

79-
for err in errors {
80-
translator.emit_parse_error(&ast, &err);
86+
if translator.detailed_diagnostics_enabled() {
87+
for err in errors {
88+
translator.emit_parse_error(&ast, &err);
89+
}
8190
}
8291
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
8392
if let Err(RustAnalyzerNoSemantics { severity, reason }) = semantics_info
@@ -238,7 +247,7 @@ fn main() -> anyhow::Result<()> {
238247
let archiver = archive::Archiver {
239248
root: cfg.source_archive_dir.clone(),
240249
};
241-
let mut extractor = Extractor::new(&archiver, &traps);
250+
let mut extractor = Extractor::new(&archiver, &traps, cfg.library_diagnostics);
242251
let files: Vec<PathBuf> = cfg
243252
.inputs
244253
.iter()

rust/extractor/src/translate/base.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pub struct Translator<'db> {
131131
file_id: Option<EditionedFileId>,
132132
pub semantics: Option<&'db Semantics<'db, RootDatabase>>,
133133
source_kind: SourceKind,
134+
library_diagnostics: bool,
134135
pub(crate) macro_context_depth: usize,
135136
diagnostic_count: usize,
136137
/// When emitting a reconstructed built-in derive expansion, holds the span map of the
@@ -152,6 +153,7 @@ impl<'db> Translator<'db> {
152153
line_index: LineIndex,
153154
semantic_info: Option<&FileSemanticInformation<'db>>,
154155
source_kind: SourceKind,
156+
library_diagnostics: bool,
155157
) -> Translator<'db> {
156158
Translator {
157159
trap,
@@ -161,11 +163,17 @@ impl<'db> Translator<'db> {
161163
file_id: semantic_info.map(|i| i.file_id),
162164
semantics: semantic_info.map(|i| i.semantics),
163165
source_kind,
166+
library_diagnostics,
164167
macro_context_depth: 0,
165168
diagnostic_count: 0,
166169
builtin_derive_span_map: None,
167170
}
168171
}
172+
173+
pub fn detailed_diagnostics_enabled(&self) -> bool {
174+
self.source_kind == SourceKind::Source || self.library_diagnostics
175+
}
176+
169177
fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> {
170178
let start = self.line_index.try_line_col(range.start())?;
171179
let range_end = range.end();
@@ -368,6 +376,9 @@ impl<'db> Translator<'db> {
368376
node: &impl ast::AstNode,
369377
expanded: &SyntaxNode,
370378
) {
379+
if !self.detailed_diagnostics_enabled() {
380+
return;
381+
}
371382
let semantics = self.semantics.as_ref().unwrap();
372383
if let Some(value) = semantics
373384
.hir_file_for(expanded)
@@ -448,7 +459,7 @@ impl<'db> Translator<'db> {
448459
value,
449460
&mut self.trap.writer,
450461
);
451-
} else {
462+
} else if self.detailed_diagnostics_enabled() {
452463
let range = self.text_range_for_node(mcall);
453464
self.emit_parse_error(mcall, &SyntaxError::new(
454465
format!(
@@ -463,18 +474,20 @@ impl<'db> Translator<'db> {
463474
if self.reconstruct_format_args_expansion(mcall, label) {
464475
return;
465476
}
466-
// let's not spam warnings if we don't have semantics, we already emitted one
467-
let range = self.text_range_for_node(mcall);
468-
self.emit_parse_error(
469-
mcall,
470-
&SyntaxError::new(
471-
format!(
472-
"macro expansion failed for '{}'",
473-
mcall.path().map(|p| p.to_string()).unwrap_or_default()
477+
if self.detailed_diagnostics_enabled() {
478+
// let's not spam warnings if we don't have semantics, we already emitted one
479+
let range = self.text_range_for_node(mcall);
480+
self.emit_parse_error(
481+
mcall,
482+
&SyntaxError::new(
483+
format!(
484+
"macro expansion failed for '{}'",
485+
mcall.path().map(|p| p.to_string()).unwrap_or_default()
486+
),
487+
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
474488
),
475-
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
476-
),
477-
);
489+
);
490+
}
478491
}
479492
}
480493

@@ -633,7 +646,9 @@ impl<'db> Translator<'db> {
633646
) -> Option<Label<generated::MacroItems>> {
634647
let semantics = self.semantics.unwrap(); // if we are here, we have semantics
635648
self.emit_macro_expansion_parse_errors(node, &value);
636-
if let Some(err) = err {
649+
if let Some(err) = err
650+
&& self.detailed_diagnostics_enabled()
651+
{
637652
let rendered = err.render_to_string(semantics.db);
638653
self.emit_diagnostic_for_node(
639654
node,
@@ -645,7 +660,7 @@ impl<'db> Translator<'db> {
645660
}
646661
if let Some(items) = ast::MacroItems::cast(value) {
647662
self.emit_macro_items(&items)
648-
} else {
663+
} else if self.detailed_diagnostics_enabled() {
649664
let message =
650665
"attribute or derive macro expansion cannot be cast to MacroItems".to_owned();
651666
self.emit_diagnostic_for_node(
@@ -656,6 +671,8 @@ impl<'db> Translator<'db> {
656671
message,
657672
);
658673
None
674+
} else {
675+
None
659676
}
660677
}
661678

@@ -768,7 +785,9 @@ impl<'db> Translator<'db> {
768785
let (parsed, output_span_map) =
769786
token_tree_to_syntax_node(&output, TopEntryPoint::MacroItems, &mut |_| edition);
770787
let items = ast::MacroItems::cast(parsed.syntax_node())?;
771-
if let Some(err) = err {
788+
if let Some(err) = err
789+
&& self.detailed_diagnostics_enabled()
790+
{
772791
let rendered = err.render_to_string(db);
773792
self.emit_diagnostic_for_node(
774793
adt,

0 commit comments

Comments
 (0)