From 5c7193a9a7b5a5d51562e103b10d3c0fb3d7ff76 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 Jan 2026 11:29:22 +0000 Subject: [PATCH 1/2] Avoid Span::local_file in rustc_fluent_macro Rust-analyzer doesn't implement this yet, causing it to show an error for pretty much every lib.rs file you have open due to the fluent macro panicking. --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_ast_passes/src/lib.rs | 2 +- compiler/rustc_attr_parsing/src/lib.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_builtin_macros/src/lib.rs | 2 +- compiler/rustc_codegen_gcc/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- compiler/rustc_codegen_ssa/src/lib.rs | 2 +- compiler/rustc_const_eval/src/lib.rs | 2 +- compiler/rustc_driver_impl/src/lib.rs | 2 +- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_expand/src/lib.rs | 2 +- compiler/rustc_fluent_macro/src/fluent.rs | 36 ++++++------------- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_incremental/src/lib.rs | 2 +- compiler/rustc_infer/src/lib.rs | 2 +- compiler/rustc_interface/src/lib.rs | 2 +- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_metadata/src/lib.rs | 2 +- compiler/rustc_middle/src/lib.rs | 2 +- compiler/rustc_mir_build/src/lib.rs | 2 +- compiler/rustc_mir_dataflow/src/lib.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- compiler/rustc_monomorphize/src/lib.rs | 2 +- compiler/rustc_parse/src/lib.rs | 2 +- compiler/rustc_passes/src/lib.rs | 2 +- compiler/rustc_pattern_analysis/src/lib.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_query_system/src/lib.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 2 +- compiler/rustc_session/src/lib.rs | 2 +- compiler/rustc_trait_selection/src/lib.rs | 2 +- compiler/rustc_ty_utils/src/lib.rs | 2 +- src/tools/compiletest/src/directives.rs | 1 + tests/ui-fulldeps/fluent-messages/test.rs | 1 + tests/ui-fulldeps/fluent-messages/test.stderr | 32 ++++++++--------- .../session-diagnostic/invalid-variable.rs | 1 + 38 files changed, 63 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index fd7c3360b05e3..c73e0037367b9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -88,7 +88,7 @@ mod pat; mod path; pub mod stability; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 06795a6be81ef..42e43a803005b 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -12,4 +12,4 @@ pub mod ast_validation; mod errors; pub mod feature_gate; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 349e6c234520d..0b8ff816cff26 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -114,4 +114,4 @@ pub use context::{Early, Late, OmitDoc, ShouldEmit}; pub use interface::AttributeParser; pub use session_diagnostics::ParsedDescription; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 91defbad0a0e0..e2f8fe3883e26 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -98,7 +98,7 @@ mod used_muts; /// A public API provided for the Rust compiler consumers. pub mod consumers; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } /// Associate some local constants with the `'tcx` lifetime struct TyCtxtConsts<'tcx>(PhantomData<&'tcx ()>); diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 89ac8db760638..a772bb2a66547 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -59,7 +59,7 @@ pub mod standard_library_imports; pub mod test_harness; pub mod util; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 96d3a0024f418..42c79ae9b6d4e 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -105,7 +105,7 @@ use tempfile::TempDir; use crate::back::lto::ModuleBuffer; use crate::gcc_util::{target_cpu, to_gcc_features}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub struct PrintOnPanic String>(pub F); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 438a74e0a0912..170876ca64beb 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -73,7 +73,7 @@ mod typetree; mod va_arg; mod value; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub(crate) use macros::TryFromU32; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d7461c76ff03e..a01381feafbe7 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -57,7 +57,7 @@ pub mod size_of_val; pub mod target_features; pub mod traits; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub struct ModuleCodegen { /// The name of the module. When the crate may be saved between diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 2fce4b8c0566e..53c0716184f56 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -27,7 +27,7 @@ use rustc_middle::util::Providers; pub use self::errors::ReportErrorExt; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn provide(providers: &mut Providers) { const_eval::provide(providers); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 7820198f2dcf2..0ca9cc6cf7b9c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -106,7 +106,7 @@ use crate::session_diagnostics::{ RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage, }; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn default_translator() -> Translator { Translator::with_fallback_bundle(DEFAULT_LOCALE_RESOURCES.to_vec(), false) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 148368045f4f5..94404fdaa1f00 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -99,7 +99,7 @@ pub mod translation; pub type PResult<'a, T> = Result>; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 5eefa4bcdf6be..7a4d0ed9b52cb 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -29,4 +29,4 @@ pub mod module; #[allow(rustc::untranslatable_diagnostic)] pub mod proc_macro; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 46d11d0469a43..d7cfc668fd0c7 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -1,6 +1,6 @@ use std::collections::{HashMap, HashSet}; use std::fs::read_to_string; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use annotate_snippets::{Renderer, Snippet}; use fluent_bundle::{FluentBundle, FluentError, FluentResource}; @@ -12,31 +12,12 @@ use fluent_syntax::parser::ParserError; use proc_macro::tracked::path; #[cfg(bootstrap)] use proc_macro::tracked_path::path; -use proc_macro::{Diagnostic, Level, Span}; +use proc_macro::{Diagnostic, Level}; use proc_macro2::TokenStream; use quote::quote; use syn::{Ident, LitStr, parse_macro_input}; use unic_langid::langid; -/// Helper function for returning an absolute path for macro-invocation relative file paths. -/// -/// If the input is already absolute, then the input is returned. If the input is not absolute, -/// then it is appended to the directory containing the source file with this macro invocation. -fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf { - let path = Path::new(path); - if path.is_absolute() { - path.to_path_buf() - } else { - // `/a/b/c/foo/bar.rs` contains the current macro invocation - let mut source_file_path = span.local_file().unwrap(); - // `/a/b/c/foo/` - source_file_path.pop(); - // `/a/b/c/foo/../locales/en-US/example.ftl` - source_file_path.push(path); - source_file_path - } -} - /// Final tokens. fn finish(body: TokenStream, resource: TokenStream) -> proc_macro::TokenStream { quote! { @@ -99,12 +80,13 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok let resource_str = parse_macro_input!(input as LitStr); let resource_span = resource_str.span().unwrap(); let relative_ftl_path = resource_str.value(); - let absolute_ftl_path = invocation_relative_path_to_absolute(resource_span, &relative_ftl_path); + let absolute_ftl_path = + PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()).join(&relative_ftl_path); let crate_name = Ident::new(&crate_name, resource_str.span()); path(absolute_ftl_path.to_str().unwrap()); - let resource_contents = match read_to_string(absolute_ftl_path) { + let resource_contents = match read_to_string(&absolute_ftl_path) { Ok(resource_contents) => resource_contents, Err(e) => { Diagnostic::spanned( @@ -143,7 +125,8 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok let message = annotate_snippets::Level::Error.title(&err).snippet( Snippet::source(this.source()) - .origin(&relative_ftl_path) + // Using an absolute path is fine here as compilation will not continue. + .origin(absolute_ftl_path.to_str().unwrap()) .fold(true) .annotation(annotate_snippets::Level::Error.span(pos.start..pos.end - 1)), ); @@ -289,7 +272,10 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok } } - finish(constants, quote! { include_str!(#relative_ftl_path) }) + finish( + constants, + quote! { include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", #relative_ftl_path)) }, + ) } fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 7296ba6f964a4..b50a7cc0cd9c6 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -103,7 +103,7 @@ use rustc_trait_selection::traits; pub use crate::collect::suggest_impl_trait; use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) { if !decl.c_variadic { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 39c28c4f4e995..7e2ea3e34a5d8 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -67,7 +67,7 @@ use crate::expectation::Expectation; use crate::fn_ctxt::LoweredTy; use crate::gather_locals::GatherLocalsVisitor; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } #[macro_export] macro_rules! type_error_struct { diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index e750810c01193..71a7a0ac2eaa2 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -22,4 +22,4 @@ pub fn provide(providers: &mut Providers) { |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx)); } -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 05ea0f813818d..bd8147625dda4 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -23,4 +23,4 @@ mod errors; pub mod infer; pub mod traits; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index ce2398fab9197..adee62f2af9a9 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -22,4 +22,4 @@ pub use queries::Linker; #[cfg(test)] mod tests; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ec7ce1ade9290..9e45851925732 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -140,7 +140,7 @@ pub use rustc_errors::BufferedEarlyLint; pub use rustc_session::lint::Level::{self, *}; pub use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintId, LintPass, LintVec}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn provide(providers: &mut Providers) { levels::provide(providers); diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index f3b738f93d2d7..d17c9628b3cca 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -35,4 +35,4 @@ pub use native_libs::{ }; pub use rmeta::{EncodedMetadata, METADATA_HEADER, encode_metadata, rendered_const}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 5f62d44df6b61..48d8aea998446 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -94,4 +94,4 @@ pub mod dep_graph; // Allows macros to refer to this crate as `::rustc_middle` extern crate self as rustc_middle; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8c7003b778761..d507dce95517d 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -20,7 +20,7 @@ pub mod thir; use rustc_middle::util::Providers; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 485925e7b50cd..448ee4e3746a6 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -34,7 +34,7 @@ pub mod rustc_peek; mod un_derefer; pub mod value_analysis; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub struct MoveDataTypingEnv<'tcx> { pub move_data: MoveData<'tcx>, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 701d7ff854a75..3d8f8e1b80b86 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -203,7 +203,7 @@ declare_passes! { mod validate : Validator; } -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn provide(providers: &mut Providers) { coverage::query::provide(providers); diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5b4f74ca6a708..e59250414a8b9 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -21,7 +21,7 @@ mod mono_checks; mod partitioning; mod util; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxtAt<'tcx>, diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 1fb44df65347e..001593705d18b 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -77,7 +77,7 @@ const _: () = { } }; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } // Unwrap the result if `Ok`, otherwise emit the diagnostics and abort. pub fn unwrap_or_emit_fatal(expr: Result>>) -> T { diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 865f2a9c3b8bb..48aea29d98d41 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -30,7 +30,7 @@ pub mod stability; mod upvars; mod weak_lang_items; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn provide(providers: &mut Providers) { check_attr::provide(providers); diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index f3308086ddc64..ac1c3055eec34 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -21,7 +21,7 @@ pub mod rustc; pub mod usefulness; #[cfg(feature = "rustc")] -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } use std::fmt; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 8656ec6e39aed..aeca7c6d80db2 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -38,7 +38,7 @@ use rustc_span::hygiene::Transparency; use rustc_span::{Ident, Span, Symbol, sym}; use tracing::debug; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } //////////////////////////////////////////////////////////////////////////////// // Generic infrastructure used to implement specific visitors below. diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 7fa643d91aa3b..c1f694353af41 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -15,4 +15,4 @@ mod values; pub use error::{HandleCycleError, QueryOverflow, QueryOverflowNote}; pub use values::Value; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 063b6b4058f05..5b13e1e007e38 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -98,7 +98,7 @@ pub use macros::registered_tools_ast; use crate::ref_mut::{CmCell, CmRefCell}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } #[derive(Copy, Clone, PartialEq, Debug)] enum Determinacy { diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 90108e9110440..3a99b5a92cea0 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -32,7 +32,7 @@ pub mod output; pub use getopts; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 6705d271bc7d9..49f66f083e062 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -37,4 +37,4 @@ pub mod regions; pub mod solve; pub mod traits; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index d8b50b2d2e42f..51798dc6c7104 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -31,7 +31,7 @@ pub mod sig_types; mod structural_match; mod ty; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +rustc_fluent_macro::fluent_messages! { "messages.ftl" } pub fn provide(providers: &mut Providers) { abi::provide(providers); diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 624f4dd7c2b1c..44a50c12c4067 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -661,6 +661,7 @@ impl Config { // Trim whitespace from the name, so that `//@ exec-env: FOO=BAR` // sees the name as `FOO` and not ` FOO`. let name = name.trim(); + let value = value.replace("$ROOT", std::env::current_dir().unwrap().to_str().unwrap()); (name.to_owned(), value.to_owned()) } diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index c1f5fe730c769..3158e5cc2c5f3 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -1,4 +1,5 @@ //@ normalize-stderr: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" +//@ rustc-env: CARGO_MANIFEST_DIR=$ROOT/tests/ui-fulldeps/fluent-messages #![feature(rustc_private)] #![crate_type = "lib"] diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index 0b3bb14ce513b..94b62286943d1 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -1,17 +1,17 @@ error: could not open Fluent resource: os-specific message - --> $DIR/test.rs:21:44 + --> $DIR/test.rs:22:44 | LL | rustc_fluent_macro::fluent_messages! { "/definitely_does_not_exist.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not open Fluent resource: os-specific message - --> $DIR/test.rs:26:44 + --> $DIR/test.rs:27:44 | LL | rustc_fluent_macro::fluent_messages! { "../definitely_does_not_exist.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not parse Fluent resource - --> $DIR/test.rs:31:44 + --> $DIR/test.rs:32:44 | LL | rustc_fluent_macro::fluent_messages! { "./missing-message.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,20 +19,20 @@ LL | rustc_fluent_macro::fluent_messages! { "./missing-message.ftl" } = help: see additional errors emitted error: expected a message field for "no_crate_missing_message" - --> ./missing-message.ftl:1:1 + --> $DIR/./missing-message.ftl:1:1 | 1 | no_crate_missing_message = | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | error: overrides existing message: `no_crate_a_b_key` - --> $DIR/test.rs:36:44 + --> $DIR/test.rs:37:44 | LL | rustc_fluent_macro::fluent_messages! { "./duplicate.ftl" } | ^^^^^^^^^^^^^^^^^ error: name `no_crate_this-slug-has-hyphens` contains a '-' character - --> $DIR/test.rs:41:44 + --> $DIR/test.rs:42:44 | LL | rustc_fluent_macro::fluent_messages! { "./slug-with-hyphens.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./slug-with-hyphens.ftl" } = help: replace any '-'s with '_'s error: attribute `label-has-hyphens` contains a '-' character - --> $DIR/test.rs:46:44 + --> $DIR/test.rs:47:44 | LL | rustc_fluent_macro::fluent_messages! { "./label-with-hyphens.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./label-with-hyphens.ftl" } = help: replace any '-'s with '_'s error: name `with-hyphens` contains a '-' character - --> $DIR/test.rs:59:44 + --> $DIR/test.rs:60:44 | LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } = help: replace any '-'s with '_'s error: name `with-hyphens` does not start with the crate name - --> $DIR/test.rs:59:44 + --> $DIR/test.rs:60:44 | LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } = help: prepend `no_crate_` to the slug name: `no_crate_with_hyphens` error: name `no-crate_foo` contains a '-' character - --> $DIR/test.rs:59:44 + --> $DIR/test.rs:60:44 | LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } = help: replace any '-'s with '_'s error: referenced message `message` does not exist (in message `no_crate_missing_message_ref`) - --> $DIR/test.rs:73:44 + --> $DIR/test.rs:74:44 | LL | rustc_fluent_macro::fluent_messages! { "./missing-message-ref.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./missing-message-ref.ftl" } = help: you may have meant to use a variable reference (`{$message}`) error: invalid escape `\n` in Fluent resource - --> $DIR/test.rs:78:44 + --> $DIR/test.rs:79:44 | LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } = note: Fluent does not interpret these escape sequences () error: invalid escape `\"` in Fluent resource - --> $DIR/test.rs:78:44 + --> $DIR/test.rs:79:44 | LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } = note: Fluent does not interpret these escape sequences () error: invalid escape `\'` in Fluent resource - --> $DIR/test.rs:78:44 + --> $DIR/test.rs:79:44 | LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +104,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } = note: Fluent does not interpret these escape sequences () error: could not parse Fluent resource - --> $DIR/test.rs:85:44 + --> $DIR/test.rs:86:44 | LL | rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" } | ^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" } = help: see additional errors emitted error: expected a message field for "no_crate_bar" - --> ./many-lines.ftl:8:1 + --> $DIR/./many-lines.ftl:8:1 | 8 | no_crate_bar = | ^^^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs b/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs index cbe9e3f4ef4c1..b1e126bd359bb 100644 --- a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs +++ b/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs @@ -1,5 +1,6 @@ //@ run-fail //@ compile-flags: --test +//@ rustc-env: CARGO_MANIFEST_DIR=$ROOT/tests/ui-fulldeps/session-diagnostic // test that messages referencing non-existent fields cause test failures #![feature(rustc_private)] From 90c42f060bcb4b1f57a3f245d423100291c8bc3e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 Jan 2026 11:34:25 +0000 Subject: [PATCH 2/2] Recover from errors in rustc_fluent_macros This avoids cascading errors as much as possible. --- compiler/rustc_fluent_macro/src/fluent.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index d7cfc668fd0c7..a2f2e0033925f 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -98,22 +98,17 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok return failed(&crate_name); } }; - let mut bad = false; for esc in ["\\n", "\\\"", "\\'"] { for _ in resource_contents.matches(esc) { - bad = true; Diagnostic::spanned(resource_span, Level::Error, format!("invalid escape `{esc}` in Fluent resource")) .note("Fluent does not interpret these escape sequences ()") .emit(); } } - if bad { - return failed(&crate_name); - } let resource = match FluentResource::try_new(resource_contents) { Ok(resource) => resource, - Err((this, errs)) => { + Err((resource, errs)) => { Diagnostic::spanned(resource_span, Level::Error, "could not parse Fluent resource") .help("see additional errors emitted") .emit(); @@ -124,7 +119,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok err.replace_range(0..1, &err.chars().next().unwrap().to_lowercase().to_string()); let message = annotate_snippets::Level::Error.title(&err).snippet( - Snippet::source(this.source()) + Snippet::source(resource.source()) // Using an absolute path is fine here as compilation will not continue. .origin(absolute_ftl_path.to_str().unwrap()) .fold(true) @@ -134,7 +129,8 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok eprintln!("{}\n", renderer.render(message)); } - return failed(&crate_name); + // Try to recover from the parse error to avoid cascading errors. + resource } };