Rust: downgrade uncompiled source files from warning to info

This commit is contained in:
Paolo Tranquilli
2025-08-26 11:56:53 +02:00
parent 80031e5c00
commit 02b4c1fa85
3 changed files with 78 additions and 30 deletions

View File

@@ -1,5 +1,5 @@
use crate::diagnostics::{ExtractionStep, emit_extraction_diagnostics};
use crate::rust_analyzer::path_to_file_id;
use crate::rust_analyzer::{RustAnalyzerNoSemantics, path_to_file_id};
use crate::translate::{ResolvePaths, SourceKind};
use crate::trap::TrapId;
use anyhow::Context;
@@ -87,14 +87,12 @@ impl<'a> Extractor<'a> {
translator.emit_parse_error(&ast, &err);
}
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
if let Err(reason) = semantics_info {
if let Err(RustAnalyzerNoSemantics { severity, reason }) = semantics_info {
if !reason.is_empty() {
let message = format!("semantic analyzer unavailable ({reason})");
let full_message = format!(
"{message}: macro expansion, call graph, and type inference will be skipped."
);
let full_message = format!("{message}: macro expansion will be skipped.");
translator.emit_diagnostic(
trap::DiagnosticSeverity::Warning,
severity,
"semantics".to_owned(),
message,
full_message,
@@ -135,10 +133,10 @@ impl<'a> Extractor<'a> {
&mut self,
file: &Path,
source_kind: SourceKind,
reason: &str,
err: RustAnalyzerNoSemantics,
) {
self.extract(
&RustAnalyzer::WithoutSemantics { reason },
&RustAnalyzer::from(err),
file,
ResolvePaths::No,
source_kind,
@@ -163,21 +161,25 @@ impl<'a> Extractor<'a> {
file: &Path,
semantics: &Semantics<'_, RootDatabase>,
vfs: &Vfs,
) -> Result<(), String> {
) -> Result<(), RustAnalyzerNoSemantics> {
let before = Instant::now();
let Some(id) = path_to_file_id(file, vfs) else {
return Err("not included in files loaded from manifest".to_string());
return Err(RustAnalyzerNoSemantics::warning(
"not included in files loaded from manifest",
));
};
match semantics.file_to_module_def(id) {
None => return Err("not included as a module".to_string()),
None => {
return Err(RustAnalyzerNoSemantics::info("not included as a module"));
}
Some(module)
if module
.as_source_file_id(semantics.db)
.is_none_or(|mod_file_id| mod_file_id.file_id(semantics.db) != id) =>
{
return Err(
"not loaded as its own module, probably included by `!include`".to_string(),
);
return Err(RustAnalyzerNoSemantics::info(
"not loaded as its own module, probably included by `!include`",
));
}
_ => {}
};
@@ -279,7 +281,11 @@ fn main() -> anyhow::Result<()> {
continue 'outer;
}
}
extractor.extract_without_semantics(file, SourceKind::Source, "no manifest found");
extractor.extract_without_semantics(
file,
SourceKind::Source,
RustAnalyzerNoSemantics::warning("no manifest found"),
);
}
let cwd = cwd()?;
let (cargo_config, load_cargo_config) = cfg.to_cargo_config(&cwd);
@@ -319,7 +325,7 @@ fn main() -> anyhow::Result<()> {
source_resolve_paths,
source_mode,
),
Err(reason) => extractor.extract_without_semantics(file, source_mode, &reason),
Err(e) => extractor.extract_without_semantics(file, source_mode, e),
};
}
for (file_id, file) in vfs.iter() {
@@ -347,7 +353,7 @@ fn main() -> anyhow::Result<()> {
extractor.extract_without_semantics(
file,
SourceKind::Source,
"unable to load manifest",
RustAnalyzerNoSemantics::warning("unable to load manifest"),
);
}
}
@@ -359,7 +365,7 @@ fn main() -> anyhow::Result<()> {
let entry = entry.context("failed to read builtins directory")?;
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "rs") {
extractor.extract_without_semantics(&path, SourceKind::Library, "");
extractor.extract_without_semantics(&path, SourceKind::Library, Default::default());
}
}

View File

@@ -1,3 +1,4 @@
use crate::trap;
use itertools::Itertools;
use ra_ap_base_db::{EditionedFileId, FileText, RootQueryDb, SourceDatabase};
use ra_ap_hir::Semantics;
@@ -23,16 +24,47 @@ use std::rc::Rc;
use tracing::{debug, error, info, trace, warn};
use triomphe::Arc;
#[derive(Clone, Default)]
pub struct RustAnalyzerNoSemantics {
pub severity: trap::DiagnosticSeverity,
pub reason: &'static str,
}
impl RustAnalyzerNoSemantics {
pub fn warning(reason: &'static str) -> Self {
RustAnalyzerNoSemantics {
severity: trap::DiagnosticSeverity::Warning,
reason,
}
}
pub fn info(reason: &'static str) -> Self {
RustAnalyzerNoSemantics {
severity: trap::DiagnosticSeverity::Info,
reason,
}
}
}
pub enum RustAnalyzer<'a> {
WithSemantics {
vfs: &'a Vfs,
semantics: &'a Semantics<'a, RootDatabase>,
},
WithoutSemantics {
reason: &'a str,
severity: trap::DiagnosticSeverity,
reason: &'static str,
},
}
impl From<RustAnalyzerNoSemantics> for RustAnalyzer<'static> {
fn from(value: RustAnalyzerNoSemantics) -> Self {
RustAnalyzer::WithoutSemantics {
severity: value.severity,
reason: value.reason,
}
}
}
pub struct FileSemanticInformation<'a> {
pub file_id: EditionedFileId,
pub semantics: &'a Semantics<'a, RootDatabase>,
@@ -42,7 +74,7 @@ pub struct ParseResult<'a> {
pub ast: SourceFile,
pub text: Arc<str>,
pub errors: Vec<SyntaxError>,
pub semantics_info: Result<FileSemanticInformation<'a>, &'a str>,
pub semantics_info: Result<FileSemanticInformation<'a>, RustAnalyzerNoSemantics>,
}
impl<'a> RustAnalyzer<'a> {
@@ -52,7 +84,7 @@ impl<'a> RustAnalyzer<'a> {
load_config: &LoadCargoConfig,
) -> Option<(RootDatabase, Vfs)> {
let progress = |t| trace!("progress: {t}");
let manifest = project.manifest_path();
let manifest: &ManifestPath = project.manifest_path();
match load_workspace_at(manifest.as_ref(), config, load_config, &progress) {
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
Err(err) => {
@@ -67,16 +99,25 @@ impl<'a> RustAnalyzer<'a> {
fn get_file_data(
&self,
path: &Path,
) -> Result<(&Semantics<'_, RootDatabase>, EditionedFileId, FileText), &str> {
) -> Result<(&Semantics<'_, RootDatabase>, EditionedFileId, FileText), RustAnalyzerNoSemantics>
{
match self {
RustAnalyzer::WithoutSemantics { reason } => Err(reason),
RustAnalyzer::WithoutSemantics { severity, reason } => Err(RustAnalyzerNoSemantics {
severity: *severity,
reason,
}),
RustAnalyzer::WithSemantics { vfs, semantics } => {
let file_id = path_to_file_id(path, vfs).ok_or("file not found in project")?;
let input = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
.or(Err("no text available for the file in the project"))?;
let editioned_file_id = semantics
.attach_first_edition(file_id)
.ok_or("failed to determine rust edition")?;
let file_id = path_to_file_id(path, vfs).ok_or(
RustAnalyzerNoSemantics::warning("file not found in project"),
)?;
let input = std::panic::catch_unwind(|| semantics.db.file_text(file_id)).or(
Err(RustAnalyzerNoSemantics::warning(
"no text available for the file in the project",
)),
)?;
let editioned_file_id = semantics.attach_first_edition(file_id).ok_or(
RustAnalyzerNoSemantics::warning("failed to determine rust edition"),
)?;
Ok((semantics, editioned_file_id, input))
}
}

View File

@@ -127,9 +127,10 @@ pub struct TrapFile {
compression: Compression,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum DiagnosticSeverity {
Debug = 10,
#[default]
Info = 20,
Warning = 30,
Error = 40,