diff options
Diffstat (limited to 'compiler/rustc_macros/src/diagnostics/fluent.rs')
-rw-r--r-- | compiler/rustc_macros/src/diagnostics/fluent.rs | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 38c0f4895..607d51f56 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -15,8 +15,7 @@ use proc_macro2::TokenStream; use quote::quote; use std::{ collections::{HashMap, HashSet}, - fs::File, - io::Read, + fs::read_to_string, path::{Path, PathBuf}, }; use syn::{parse_macro_input, Ident, LitStr}; @@ -95,20 +94,28 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok // As this macro also outputs an `include_str!` for this file, the macro will always be // re-executed when the file changes. - let mut resource_file = match File::open(absolute_ftl_path) { - Ok(resource_file) => resource_file, + let resource_contents = match read_to_string(absolute_ftl_path) { + Ok(resource_contents) => resource_contents, Err(e) => { - Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource") - .note(e.to_string()) - .emit(); + Diagnostic::spanned( + resource_span, + Level::Error, + format!("could not open Fluent resource: {e}"), + ) + .emit(); return failed(&crate_name); } }; - let mut resource_contents = String::new(); - if let Err(e) = resource_file.read_to_string(&mut resource_contents) { - Diagnostic::spanned(resource_span, Level::Error, "could not read Fluent resource") - .note(e.to_string()) - .emit(); + 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 (<https://projectfluent.org/fluent/guide/special.html>)") + .emit(); + } + } + if bad { return failed(&crate_name); } |