diff options
Diffstat (limited to 'compiler/rustc_macros')
| -rw-r--r-- | compiler/rustc_macros/build.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/diagnostic.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/subdiagnostic.rs | 39 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/utils.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/lib.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/lift.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/serialize.rs | 16 |
9 files changed, 80 insertions, 48 deletions
diff --git a/compiler/rustc_macros/build.rs b/compiler/rustc_macros/build.rs index 717f8a92245..62e827371a7 100644 --- a/compiler/rustc_macros/build.rs +++ b/compiler/rustc_macros/build.rs @@ -1,7 +1,7 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP"); - if !std::env::var("RUSTC_BOOTSTRAP").is_ok() { + if std::env::var("RUSTC_BOOTSTRAP").is_err() { eprintln!( "error: you are attempting to build the compiler without going through bootstrap" ); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 9d21d88165e..ef6005283d6 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -105,25 +105,12 @@ impl<'a> LintDiagnosticDerive<'a> { pub(crate) fn into_tokens(self) -> TokenStream { let LintDiagnosticDerive { mut structure } = self; let kind = DiagnosticDeriveKind::LintDiagnostic; + let slugs = RefCell::new(Vec::new()); let implementation = kind.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); - let formatting_init = &builder.formatting_init; - quote! { - #preamble - #formatting_init - #body - diag - } - }); - - let slugs = RefCell::new(Vec::new()); - let msg = kind.each_variant(&mut structure, |mut builder, variant| { - // Collect the slug by generating the preamble. - let _ = builder.preamble(variant); - - match builder.slug.value_ref() { + let primary_message = match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") .help( @@ -146,9 +133,18 @@ impl<'a> LintDiagnosticDerive<'a> { Some(slug) => { slugs.borrow_mut().push(slug.clone()); quote! { - crate::fluent_generated::#slug.into() + diag.primary_message(crate::fluent_generated::#slug); } } + }; + + let formatting_init = &builder.formatting_init; + quote! { + #primary_message + #preamble + #formatting_init + #body + diag } }); @@ -161,10 +157,6 @@ impl<'a> LintDiagnosticDerive<'a> { ) { #implementation; } - - fn msg(&self) -> rustc_errors::DiagMessage { - #msg - } } }); for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index ae481efb263..38d4a5ee61c 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -158,7 +158,9 @@ impl DiagnosticDeriveVariantBuilder { let slug = subdiag.slug.unwrap_or_else(|| match subdiag.kind { SubdiagnosticKind::Label => parse_quote! { _subdiag::label }, SubdiagnosticKind::Note => parse_quote! { _subdiag::note }, + SubdiagnosticKind::NoteOnce => parse_quote! { _subdiag::note_once }, SubdiagnosticKind::Help => parse_quote! { _subdiag::help }, + SubdiagnosticKind::HelpOnce => parse_quote! { _subdiag::help_once }, SubdiagnosticKind::Warn => parse_quote! { _subdiag::warn }, SubdiagnosticKind::Suggestion { .. } => parse_quote! { _subdiag::suggestion }, SubdiagnosticKind::MultipartSuggestion { .. } => unreachable!(), @@ -233,9 +235,11 @@ impl DiagnosticDeriveVariantBuilder { }; let fn_ident = format_ident!("{}", subdiag); match subdiag { - SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => { - Ok(self.add_subdiagnostic(&fn_ident, slug)) - } + SubdiagnosticKind::Note + | SubdiagnosticKind::NoteOnce + | SubdiagnosticKind::Help + | SubdiagnosticKind::HelpOnce + | SubdiagnosticKind::Warn => Ok(self.add_subdiagnostic(&fn_ident, slug)), SubdiagnosticKind::Label | SubdiagnosticKind::Suggestion { .. } => { throw_invalid_attr!(attr, |diag| diag .help("`#[label]` and `#[suggestion]` can only be applied to fields")); @@ -347,7 +351,11 @@ impl DiagnosticDeriveVariantBuilder { report_error_if_not_applied_to_span(attr, &info)?; Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug)) } - SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => { + SubdiagnosticKind::Note + | SubdiagnosticKind::NoteOnce + | SubdiagnosticKind::Help + | SubdiagnosticKind::HelpOnce + | SubdiagnosticKind::Warn => { let inner = info.ty.inner_type(); if type_matches_path(inner, &["rustc_span", "Span"]) || type_matches_path(inner, &["rustc_span", "MultiSpan"]) diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 389d88bebc7..134045d0644 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -91,7 +91,7 @@ pub fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream { /// Then, later, to emit the error: /// /// ```ignore (rust) -/// cx.span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { +/// cx.emit_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { /// method, /// success_ordering, /// fail_ordering, diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index ced782cdbc0..69014f39925 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -71,6 +71,7 @@ impl SubdiagnosticDerive { span_field: None, applicability: None, has_suggestion_parts: false, + has_subdiagnostic: false, is_enum, }; builder.into_tokens().unwrap_or_else(|v| v.to_compile_error()) @@ -90,7 +91,7 @@ impl SubdiagnosticDerive { fn add_to_diag_with<__G, __F>( self, #diag: &mut rustc_errors::Diag<'_, __G>, - #f: __F + #f: &__F ) where __G: rustc_errors::EmissionGuarantee, __F: rustc_errors::SubdiagMessageOp<__G>, @@ -133,6 +134,10 @@ struct SubdiagnosticDeriveVariantBuilder<'parent, 'a> { /// during finalization if still `false`. has_suggestion_parts: bool, + /// Set to true when a `#[subdiagnostic]` field is encountered, used to suppress the error + /// emitted when no subdiagnostic kinds are specified on the variant itself. + has_subdiagnostic: bool, + /// Set to true when this variant is an enum variant rather than just the body of a struct. is_enum: bool, } @@ -373,6 +378,13 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { Ok(quote! {}) } + "subdiagnostic" => { + let f = &self.parent.f; + let diag = &self.parent.diag; + let binding = &info.binding; + self.has_subdiagnostic = true; + Ok(quote! { #binding.add_to_diag_with(#diag, #f); }) + } _ => { let mut span_attrs = vec![]; if kind_stats.has_multipart_suggestion { @@ -480,18 +492,6 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { pub(crate) fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> { let kind_slugs = self.identify_kind()?; - if kind_slugs.is_empty() { - if self.is_enum { - // It's okay for a variant to not be a subdiagnostic at all.. - return Ok(quote! {}); - } else { - // ..but structs should always be _something_. - throw_span_err!( - self.variant.ast().ident.span().unwrap(), - "subdiagnostic kind not specified" - ); - } - }; let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug, _no_span)| kind).collect(); @@ -510,6 +510,19 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { .map(|binding| self.generate_field_attr_code(binding, kind_stats)) .collect(); + if kind_slugs.is_empty() && !self.has_subdiagnostic { + if self.is_enum { + // It's okay for a variant to not be a subdiagnostic at all.. + return Ok(quote! {}); + } else { + // ..but structs should always be _something_. + throw_span_err!( + self.variant.ast().ident.span().unwrap(), + "subdiagnostic kind not specified" + ); + } + }; + let span_field = self.span_field.value_ref(); let diag = &self.parent.diag; diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 4684306e235..05a5a32514b 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -575,8 +575,12 @@ pub(super) enum SubdiagnosticKind { Label, /// `#[note(...)]` Note, + /// `#[note_once(...)]` + NoteOnce, /// `#[help(...)]` Help, + /// `#[help_once(...)]` + HelpOnce, /// `#[warning(...)]` Warn, /// `#[suggestion{,_short,_hidden,_verbose}]` @@ -624,7 +628,9 @@ impl SubdiagnosticVariant { let mut kind = match name { "label" => SubdiagnosticKind::Label, "note" => SubdiagnosticKind::Note, + "note_once" => SubdiagnosticKind::NoteOnce, "help" => SubdiagnosticKind::Help, + "help_once" => SubdiagnosticKind::HelpOnce, "warning" => SubdiagnosticKind::Warn, _ => { // Recover old `#[(multipart_)suggestion_*]` syntaxes @@ -682,7 +688,9 @@ impl SubdiagnosticVariant { match kind { SubdiagnosticKind::Label | SubdiagnosticKind::Note + | SubdiagnosticKind::NoteOnce | SubdiagnosticKind::Help + | SubdiagnosticKind::HelpOnce | SubdiagnosticKind::Warn | SubdiagnosticKind::MultipartSuggestion { .. } => { return Ok(Some(SubdiagnosticVariant { kind, slug: None, no_span: false })); @@ -836,7 +844,9 @@ impl SubdiagnosticVariant { } SubdiagnosticKind::Label | SubdiagnosticKind::Note + | SubdiagnosticKind::NoteOnce | SubdiagnosticKind::Help + | SubdiagnosticKind::HelpOnce | SubdiagnosticKind::Warn => {} } @@ -849,7 +859,9 @@ impl quote::IdentFragment for SubdiagnosticKind { match self { SubdiagnosticKind::Label => write!(f, "label"), SubdiagnosticKind::Note => write!(f, "note"), + SubdiagnosticKind::NoteOnce => write!(f, "note_once"), SubdiagnosticKind::Help => write!(f, "help"), + SubdiagnosticKind::HelpOnce => write!(f, "help_once"), SubdiagnosticKind::Warn => write!(f, "warn"), SubdiagnosticKind::Suggestion { .. } => write!(f, "suggestions_with_style"), SubdiagnosticKind::MultipartSuggestion { .. } => { diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index eedc508fb14..de9c916b4f0 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -108,7 +108,9 @@ decl_derive!( // struct attributes diag, help, + help_once, note, + note_once, warning, // field attributes skip_arg, @@ -125,7 +127,9 @@ decl_derive!( // struct attributes diag, help, + help_once, note, + note_once, warning, // field attributes skip_arg, @@ -142,8 +146,11 @@ decl_derive!( // struct/variant attributes label, help, + help_once, note, + note_once, warning, + subdiagnostic, suggestion, suggestion_short, suggestion_hidden, diff --git a/compiler/rustc_macros/src/lift.rs b/compiler/rustc_macros/src/lift.rs index f7a84ba1510..d41ceb29816 100644 --- a/compiler/rustc_macros/src/lift.rs +++ b/compiler/rustc_macros/src/lift.rs @@ -41,7 +41,7 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre s.add_impl_generic(newtcx); s.bound_impl( - quote!(::rustc_middle::ty::Lift<'__lifted>), + quote!(::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>), quote! { type Lifted = #lifted; diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index 5fa11d22f0e..7b5dd1601c1 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -13,7 +13,7 @@ pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: quote! {} }; - s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound }); + s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound }); s.add_bounds(synstructure::AddBounds::Fields); s.underscore_const(true); @@ -34,7 +34,7 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; - s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_span::SpanDecoder}); + s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_span::SpanDecoder }); s.add_bounds(synstructure::AddBounds::Generics); s.underscore_const(true); @@ -43,7 +43,7 @@ pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke pub fn decodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; - s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_serialize::Decoder}); + s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_serialize::Decoder }); s.add_bounds(synstructure::AddBounds::Generics); s.underscore_const(true); @@ -120,7 +120,7 @@ fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream { let __decoder = quote! { __decoder }; // Use the span of the field for the method call, so // that backtraces will point to the field. - quote_spanned! {field_span=> #decode_inner_method(#__decoder) } + quote_spanned! { field_span=> #decode_inner_method(#__decoder) } } pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { @@ -133,7 +133,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: }; let encoder_ty = quote! { __E }; - s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound }); + s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound }); s.add_bounds(synstructure::AddBounds::Fields); s.underscore_const(true); @@ -142,7 +142,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { - s.add_impl_generic(parse_quote! {'tcx}); + s.add_impl_generic(parse_quote! { 'tcx }); } s.add_impl_generic(parse_quote! { '__a }); let encoder_ty = quote! { EncodeContext<'__a, 'tcx> }; @@ -154,7 +154,7 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let encoder_ty = quote! { __E }; - s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder}); + s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder }); s.add_bounds(synstructure::AddBounds::Generics); s.underscore_const(true); @@ -163,7 +163,7 @@ pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke pub fn encodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let encoder_ty = quote! { __E }; - s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder}); + s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder }); s.add_bounds(synstructure::AddBounds::Generics); s.underscore_const(true); |
