diff options
| author | bors <bors@rust-lang.org> | 2022-12-24 09:41:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-24 09:41:11 +0000 |
| commit | d23554fae855d884761d549cd6ee6537450b0f3c (patch) | |
| tree | b44bd3e79fa5019f0e8648737e71c432bc784188 /compiler/rustc_macros/src | |
| parent | 245357f61939d2b6d15f8c6b15f7026396f95871 (diff) | |
| parent | e52e0d855799fe651922be4a038fe84fe9009c72 (diff) | |
| download | rust-d23554fae855d884761d549cd6ee6537450b0f3c.tar.gz rust-d23554fae855d884761d549cd6ee6537450b0f3c.zip | |
Auto merge of #2738 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'compiler/rustc_macros/src')
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/diagnostic.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/subdiagnostic.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/utils.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/newtype.rs | 155 |
4 files changed, 59 insertions, 112 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 13f06fe7473..9ff94486404 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -39,10 +39,8 @@ impl<'a> DiagnosticDerive<'a> { let init = match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") - .help(format!( - "specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(hir_analysis_example_error)]`", - )) + .help("specify the slug as the first argument to the `#[diag(...)]` \ + attribute, such as `#[diag(hir_analysis_example_error)]`") .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } @@ -133,10 +131,8 @@ impl<'a> LintDiagnosticDerive<'a> { match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") - .help(format!( - "specify the slug as the first argument to the attribute, such as \ - `#[diag(compiletest_example)]`", - )) + .help("specify the slug as the first argument to the attribute, such as \ + `#[diag(compiletest_example)]`") .emit(); DiagnosticDeriveError::ErrorHandled.to_compile_error() } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 446aebe4f83..767db367322 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -29,7 +29,7 @@ impl SubdiagnosticDeriveBuilder { Self { diag, f } } - pub(crate) fn into_tokens<'a>(self, mut structure: Structure<'a>) -> TokenStream { + pub(crate) fn into_tokens(self, mut structure: Structure<'_>) -> TokenStream { let implementation = { let ast = structure.ast(); let span = ast.span().unwrap(); diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index da90233523c..4ff9c777ad8 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -385,7 +385,7 @@ impl quote::ToTokens for Applicability { /// Build the mapping of field names to fields. This allows attributes to peek values from /// other fields. -pub(super) fn build_field_mapping<'v>(variant: &VariantInfo<'v>) -> HashMap<String, TokenStream> { +pub(super) fn build_field_mapping(variant: &VariantInfo<'_>) -> HashMap<String, TokenStream> { let mut fields_map = FieldMap::new(); for binding in variant.bindings() { if let Some(ident) = &binding.ast().ident { diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index fd3f5225155..153473de624 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -1,35 +1,15 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::parse::*; -use syn::punctuated::Punctuated; use syn::*; -mod kw { - syn::custom_keyword!(derive); - syn::custom_keyword!(DEBUG_FORMAT); - syn::custom_keyword!(MAX); - syn::custom_keyword!(ENCODABLE); - syn::custom_keyword!(custom); - syn::custom_keyword!(ORD_IMPL); -} - -#[derive(Debug)] -enum DebugFormat { - // The user will provide a custom `Debug` impl, so we shouldn't generate - // one - Custom, - // Use the specified format string in the generated `Debug` impl - // By default, this is "{}" - Format(String), -} - // We parse the input and emit the output in a single step. // This field stores the final macro output struct Newtype(TokenStream); impl Parse for Newtype { fn parse(input: ParseStream<'_>) -> Result<Self> { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let vis: Visibility = input.parse()?; input.parse::<Token![struct]>()?; let name: Ident = input.parse()?; @@ -39,93 +19,68 @@ impl Parse for Newtype { // Any additional `#[derive]` macro paths to apply let mut derive_paths: Vec<Path> = Vec::new(); - let mut debug_format: Option<DebugFormat> = None; + let mut debug_format: Option<Lit> = None; let mut max = None; let mut consts = Vec::new(); let mut encodable = true; let mut ord = true; - // Parse an optional trailing comma - let try_comma = || -> Result<()> { - if body.lookahead1().peek(Token![,]) { - body.parse::<Token![,]>()?; - } - Ok(()) - }; - - if body.lookahead1().peek(Token![..]) { - body.parse::<Token![..]>()?; - } else { - loop { - if body.lookahead1().peek(kw::derive) { - body.parse::<kw::derive>()?; - let derives; - bracketed!(derives in body); - let derives: Punctuated<Path, Token![,]> = - derives.parse_terminated(Path::parse)?; - try_comma()?; - derive_paths.extend(derives); - continue; - } - if body.lookahead1().peek(kw::DEBUG_FORMAT) { - body.parse::<kw::DEBUG_FORMAT>()?; - body.parse::<Token![=]>()?; - let new_debug_format = if body.lookahead1().peek(kw::custom) { - body.parse::<kw::custom>()?; - DebugFormat::Custom - } else { - let format_str: LitStr = body.parse()?; - DebugFormat::Format(format_str.value()) - }; - try_comma()?; - if let Some(old) = debug_format.replace(new_debug_format) { - panic!("Specified multiple debug format options: {:?}", old); - } - continue; - } - if body.lookahead1().peek(kw::MAX) { - body.parse::<kw::MAX>()?; - body.parse::<Token![=]>()?; - let val: Lit = body.parse()?; - try_comma()?; - if let Some(old) = max.replace(val) { - panic!("Specified multiple MAX: {:?}", old); - } - continue; - } - if body.lookahead1().peek(kw::ENCODABLE) { - body.parse::<kw::ENCODABLE>()?; - body.parse::<Token![=]>()?; - body.parse::<kw::custom>()?; - try_comma()?; + attrs.retain(|attr| match attr.path.get_ident() { + Some(ident) => match &*ident.to_string() { + "custom_encodable" => { encodable = false; - continue; + false } - if body.lookahead1().peek(kw::ORD_IMPL) { - body.parse::<kw::ORD_IMPL>()?; - body.parse::<Token![=]>()?; - body.parse::<kw::custom>()?; + "no_ord_impl" => { ord = false; - continue; + false } + "max" => { + let Ok(Meta::NameValue(literal) )= attr.parse_meta() else { + panic!("#[max = NUMBER] attribute requires max value"); + }; + + if let Some(old) = max.replace(literal.lit) { + panic!("Specified multiple max: {:?}", old); + } - // We've parsed everything that the user provided, so we're done - if body.is_empty() { - break; + false } + "debug_format" => { + let Ok(Meta::NameValue(literal) )= attr.parse_meta() else { + panic!("#[debug_format = FMT] attribute requires a format"); + }; + + if let Some(old) = debug_format.replace(literal.lit) { + panic!("Specified multiple debug format options: {:?}", old); + } - // Otherwise, we are parsing a user-defined constant - let const_attrs = body.call(Attribute::parse_outer)?; - body.parse::<Token![const]>()?; - let const_name: Ident = body.parse()?; - body.parse::<Token![=]>()?; - let const_val: Expr = body.parse()?; - try_comma()?; - consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); }); + false + } + _ => true, + }, + _ => true, + }); + + loop { + // We've parsed everything that the user provided, so we're done + if body.is_empty() { + break; } + + // Otherwise, we are parsing a user-defined constant + let const_attrs = body.call(Attribute::parse_outer)?; + body.parse::<Token![const]>()?; + let const_name: Ident = body.parse()?; + body.parse::<Token![=]>()?; + let const_val: Expr = body.parse()?; + body.parse::<Token![;]>()?; + consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); }); } - let debug_format = debug_format.unwrap_or(DebugFormat::Format("{}".to_string())); + let debug_format = + debug_format.unwrap_or_else(|| Lit::Str(LitStr::new("{}", Span::call_site()))); + // shave off 256 indices at the end to allow space for packing these indices into enums let max = max.unwrap_or_else(|| Lit::Int(LitInt::new("0xFFFF_FF00", Span::call_site()))); @@ -180,18 +135,14 @@ impl Parse for Newtype { quote! {} }; - let debug_impl = match debug_format { - DebugFormat::Custom => quote! {}, - DebugFormat::Format(format) => { - quote! { - impl ::std::fmt::Debug for #name { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(fmt, #format, self.as_u32()) - } - } + let debug_impl = quote! { + impl ::std::fmt::Debug for #name { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(fmt, #debug_format, self.as_u32()) } } }; + let spec_partial_eq_impl = if let Lit::Int(max) = &max { if let Ok(max_val) = max.base10_parse::<u32>() { quote! { |
