diff --git a/tooling/lsp/src/notifications/mod.rs b/tooling/lsp/src/notifications/mod.rs index d23ccbef718..e8c2bd510dd 100644 --- a/tooling/lsp/src/notifications/mod.rs +++ b/tooling/lsp/src/notifications/mod.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::collections::{BTreeMap, HashSet}; use std::ops::ControlFlow; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::str::FromStr as _; use crate::{ @@ -283,7 +283,7 @@ fn publish_diagnostics( for custom_diagnostic in custom_diagnostics.into_iter() { let file = custom_diagnostic.file; let path = fm.path(file).expect("file must exist to have emitted diagnostic"); - if let Ok(uri) = Url::from_file_path(path) { + if let Some(uri) = uri_from_path(path) { if let Some(diagnostic) = custom_diagnostic_to_diagnostic(custom_diagnostic, files, fm, uri.clone()) { @@ -356,6 +356,7 @@ fn custom_diagnostic_to_diagnostic( let call_stack = diagnostic .call_stack .into_iter() + .rev() .filter_map(|frame| call_stack_frame_to_related_information(frame, files, fm)); let related_information: Vec<_> = secondaries.chain(notes).chain(call_stack).collect(); @@ -380,19 +381,29 @@ fn secondary_to_related_information( ) -> Option { let secondary_file = secondary.location.file; let path = fm.path(secondary_file)?; - let uri = Url::from_file_path(path).ok()?; + let uri = uri_from_path(path)?; let range = byte_span_to_range(files, secondary_file, secondary.location.span.into())?; let message = secondary.message; Some(DiagnosticRelatedInformation { location: lsp_types::Location { uri, range }, message }) } +fn uri_from_path(path: &Path) -> Option { + if let Ok(uri) = Url::from_file_path(path) { + Some(uri) + } else if path.starts_with("std") { + Some(Url::parse(&format!("noir-std://{}", path.to_string_lossy())).unwrap()) + } else { + None + } +} + fn call_stack_frame_to_related_information( frame: Location, files: &FileMap, fm: &FileManager, ) -> Option { let path = fm.path(frame.file)?; - let uri = Url::from_file_path(path).ok()?; + let uri = uri_from_path(path)?; let range = byte_span_to_range(files, frame.file, frame.span.into())?; Some(DiagnosticRelatedInformation { location: lsp_types::Location { uri, range },