diff options
| author | mejrs <> | 2022-11-13 13:10:36 +0100 |
|---|---|---|
| committer | mejrs <> | 2022-11-21 15:24:51 +0100 |
| commit | e8e47e08731599e95724680ffbc574455bfeb233 (patch) | |
| tree | 92d025ba37a0f72c41eaee291ccb9100ca6e0140 /compiler/rustc_macros/src | |
| parent | d494502f64ea1b3a3164a13ce20cd1eba89c8141 (diff) | |
| download | rust-e8e47e08731599e95724680ffbc574455bfeb233.tar.gz rust-e8e47e08731599e95724680ffbc574455bfeb233.zip | |
Improve slug name error
Diffstat (limited to 'compiler/rustc_macros/src')
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/diagnostic.rs | 97 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/lib.rs | 1 |
2 files changed, 45 insertions, 53 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index c3772475769..be9821c00f5 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -5,6 +5,7 @@ use crate::diagnostics::error::{span_err, DiagnosticDeriveError}; use crate::diagnostics::utils::SetOnce; use proc_macro2::TokenStream; use quote::quote; +use syn::spanned::Spanned; use synstructure::Structure; /// The central struct for constructing the `into_diagnostic` method from an annotated struct. @@ -45,10 +46,19 @@ impl<'a> DiagnosticDerive<'a> { .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } + Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => { + span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") + .note(&format!( + "slug is `{slug_name}` but the crate name is `{crate_name}`" + )) + .help(&format!( + "expected a slug starting with `{slug_prefix}_...`" + )) + .emit(); + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + } Some(slug) => { - let check = make_check(slug); quote! { - #check let mut #diag = #handler.struct_diagnostic(rustc_errors::fluent::#slug); } } @@ -130,11 +140,19 @@ impl<'a> LintDiagnosticDerive<'a> { .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } + Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => { + span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") + .note(&format!( + "slug is `{slug_name}` but the crate name is `{crate_name}`" + )) + .help(&format!( + "expected a slug starting with `{slug_prefix}_...`" + )) + .emit(); + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + } Some(slug) => { - let check = make_check(slug); - quote! { - #check rustc_errors::fluent::#slug.into() } } @@ -161,53 +179,26 @@ impl<'a> LintDiagnosticDerive<'a> { } } -/// Checks whether the slug starts with the crate name it's in. -fn make_check(slug: &syn::Path) -> TokenStream { - quote! { - const _: () = { - const krate_str: &str = match option_env!("CARGO_CRATE_NAME") { - Some(c) => c, - None => "", - }; - const krate: &[u8] = krate_str.as_bytes(); - - if krate.len() > 6 - && krate[0] == b'r' - && krate[1] == b'u' - && krate[2] == b's' - && krate[3] == b't' - && krate[4] == b'c' - && krate[5] == b'_' - { - let slug = stringify!(#slug).as_bytes(); - - let mut pos = 0; - loop { - let b = slug[pos]; - if krate.len() == pos + 6 { - if b != b'_' { - panic!(concat!( - "slug \"", - stringify!(#slug), - "\" does not match the crate it is in" - )); - } - break; - } - let a = krate[pos + 6]; - - if a != b { - panic!(concat!( - "slug \"", - stringify!(#slug), - "\" does not match the crate it is in" - )); - } - pos += 1; - } - } else { - // Crate does not start with "rustc_" - } - }; +struct Mismatch { + slug_name: String, + crate_name: String, + slug_prefix: String, +} + +impl Mismatch { + /// Checks whether the slug starts with the crate name it's in. + fn check(slug: &syn::Path) -> Option<Mismatch> { + // If this is missing we're probably in a test, so bail. + let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; + + // If we're not in a "rustc_" crate, bail. + let Some(("rustc", slug_prefix)) = crate_name.split_once("_") else { return None }; + + let slug_name = slug.segments.first()?.ident.to_string(); + if !slug_name.starts_with(slug_prefix) { + Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) + } else { + None + } } } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 36bda3e0f6b..a2a01b66690 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,4 +1,5 @@ #![feature(allow_internal_unstable)] +#![feature(if_let_guard)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] |
