Expand relative assets to a placeholder if we are running in rust (#4860)

analyzer
This commit is contained in:
Evan Almloff authored and GitHub committed 2025-10-30 18:53:39 -07:00
1 parent 566dab939f
commit ee1719af92
1 file changed
+29
@@ -209,6 +209,16 @@ fn resolve_path(raw: &str, span: Span) -> Result<PathBuf, AssetParseError> {
if let Some(local_folder) = span.local_file().as_ref().and_then(|f| f.parent()) {
local_folder.join(raw)
} else {
// If we are running in rust analyzer, just assume the path is valid and return an error when
// we compile if it doesn't exist
if looks_like_rust_analyzer(&span) {
return Ok(
"The asset macro was expanded under Rust Analyzer which doesn't support paths or local assets yet"
.into(),
);
}
// Otherwise, return an error about the version of rust required for relative assets
return Err(AssetParseError::RelativeAssetPath);
}
} else {
@@ -328,3 +338,22 @@ impl std::fmt::Display for AssetParseError {
}
}
}
/// Rust analyzer doesn't provide a stable way to detect if macros are running under it.
/// This function uses heuristics to determine if we are running under rust analyzer for better error
/// messages.
fn looks_like_rust_analyzer(span: &Span) -> bool {
// Rust analyzer spans have a struct debug impl compared to rustcs custom debug impl
// RA Example: SpanData { range: 45..58, anchor: SpanAnchor(EditionedFileId(0, Edition2024), ErasedFileAstId { kind: Fn, index: 0, hash: 9CD8 }), ctx: SyntaxContext(4294967036) }
// Rustc Example: #0 bytes(70..83)
let looks_like_rust_analyzer_span = format!("{:?}", span).contains("ctx:");
// The rust analyzer macro expander runs under RUST_ANALYZER_INTERNALS_DO_NOT_USE
let looks_like_rust_analyzer_env = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE").is_ok();
// The rust analyzer executable is named rust-analyzer-proc-macro-srv
let looks_like_rust_analyzer_exe = std::env::current_exe().ok().is_some_and(|p| {
p.file_stem()
.and_then(|s| s.to_str())
.is_some_and(|s| s.contains("rust-analyzer"))
});
looks_like_rust_analyzer_span || looks_like_rust_analyzer_env || looks_like_rust_analyzer_exe
}