diff --git a/Cargo.lock b/Cargo.lock index 9a8d9d40b6e45..0b44201d56f0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4239,7 +4239,6 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_lexer", - "rustc_macros", "rustc_middle", "rustc_serialize", "rustc_session", diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl deleted file mode 100644 index e4c9a4dad7b48..0000000000000 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ /dev/null @@ -1,151 +0,0 @@ --passes-previously-accepted = - this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - --passes-see-issue = - see issue #{$issue} for more information - -passes-outer-crate-level-attr = - crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - -passes-inner-crate-level-attr = - crate-level attribute should be in the root module - -passes-ignored-attr-with-macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs - .warn = {-passes-previously-accepted} - .note = {-passes-see-issue(issue: "80564")} - -passes-ignored-attr = `#[{$sym}]` is ignored on struct fields and match arms - .warn = {-passes-previously-accepted} - .note = {-passes-see-issue(issue: "80564")} - -passes-inline-ignored-function-prototype = `#[inline]` is ignored on function prototypes - -passes-inline-ignored-constants = `#[inline]` is ignored on constants - .warn = {-passes-previously-accepted} - .note = {-passes-see-issue(issue: "65833")} - -passes-inline-not-fn-or-closure = attribute should be applied to function or closure - .label = not a function or closure - -passes-no-coverage-ignored-function-prototype = `#[no_coverage]` is ignored on function prototypes - -passes-no-coverage-propagate = - `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly - -passes-no-coverage-fn-defn = `#[no_coverage]` may only be applied to function definitions - -passes-no-coverage-not-coverable = `#[no_coverage]` must be applied to coverable code - .label = not coverable code - -passes-should-be-applied-to-fn = attribute should be applied to a function definition - .label = not a function definition - -passes-naked-tracked-caller = cannot use `#[track_caller]` with `#[naked]` - -passes-should-be-applied-to-struct-enum = attribute should be applied to a struct or enum - .label = not a struct or enum - -passes-should-be-applied-to-trait = attribute should be applied to a trait - .label = not a trait - -passes-target-feature-on-statement = {passes-should-be-applied-to-fn} - .warn = {-passes-previously-accepted} - .label = {passes-should-be-applied-to-fn.label} - -passes-should-be-applied-to-static = attribute should be applied to a static - .label = not a static - -passes-doc-expect-str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")] - -passes-doc-alias-empty = {$attr_str} attribute cannot have empty value - -passes-doc-alias-bad-char = {$char_} character isn't allowed in {$attr_str} - -passes-doc-alias-start-end = {$attr_str} cannot start or end with ' ' - -passes-doc-alias-bad-location = {$attr_str} isn't allowed on {$location} - -passes-doc-alias-not-an-alias = {$attr_str} is the same as the item's name - -passes-doc-alias-duplicated = doc alias is duplicated - .label = first defined here - -passes-doc-alias-not-string-literal = `#[doc(alias("a"))]` expects string literals - -passes-doc-alias-malformed = - doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` - -passes-doc-keyword-empty-mod = `#[doc(keyword = "...")]` should be used on empty modules - -passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules - -passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier - -passes-doc-tuple-variadic-not-first = - `#[doc(tuple_variadic)]` must be used on the first of a set of tuple trait impls with varying arity - -passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks - -passes-doc-inline-conflict-first = this attribute... -passes-doc-inline-conflict-second = ...conflicts with this attribute -passes-doc-inline-conflict = conflicting doc inlining attributes - .help = remove one of the conflicting attributes - -passes-doc-inline-only-use = this attribute can only be applied to a `use` item - .label = only applicable on `use` items - .not-a-use-item-label = not a `use` item - .note = read for more information - -passes-doc-attr-not-crate-level = - `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute - -passes-attr-crate-level = this attribute can only be applied at the crate level - .suggestion = to apply to the crate, use an inner attribute - .help = to apply to the crate, use an inner attribute - .note = read for more information - -passes-doc-test-unknown = unknown `doc(test)` attribute `{$path}` - -passes-doc-test-takes-list = `#[doc(test(...)]` takes a list of attributes - -passes-doc-primitive = `doc(primitive)` should never have been stable - -passes-doc-test-unknown-any = unknown `doc` attribute `{$path}` - -passes-doc-test-unknown-spotlight = unknown `doc` attribute `{$path}` - .note = `doc(spotlight)` was renamed to `doc(notable_trait)` - .suggestion = use `notable_trait` instead - .no-op-note = `doc(spotlight)` is now a no-op - -passes-doc-test-unknown-include = unknown `doc` attribute `{$path}` - .suggestion = use `doc = include_str!` instead - -passes-doc-invalid = invalid `doc` attribute - -passes-pass-by-value = `pass_by_value` attribute should be applied to a struct, enum or type alias - .label = is not a struct, enum or type alias - -passes-allow-incoherent-impl = - `rustc_allow_incoherent_impl` attribute should be applied to impl items. - .label = the only currently supported targets are inherent methods - -passes-has-incoherent-inherent-impl = - `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits. - .label = only adts, extern types and traits are supported - -passes-must-use-async = - `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within - .label = this attribute does nothing, the `Future`s returned by async functions are already `must_use` - -passes-must-use-no-effect = `#[must_use]` has no effect when applied to {$article} {$target} - -passes-must-not-suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait - .label = is not a struct, enum, or trait - -passes-cold = {passes-should-be-applied-to-fn} - .warn = {-passes-previously-accepted} - .label = {passes-should-be-applied-to-fn.label} - -passes-link = attribute should be applied to an `extern` block with non-Rust ABI - .warn = {-passes-previously-accepted} - .label = not an `extern` block diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_error_messages/locales/en-US/privacy.ftl index f8a750da93f8d..2b0778f48caee 100644 --- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl +++ b/compiler/rustc_error_messages/locales/en-US/privacy.ftl @@ -10,12 +10,3 @@ privacy-unnamed-item-is-private = {$kind} is private privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface .label = can't leak {$vis_descr} {$kind} .visibility-label = `{$descr}` declared as {$vis_descr} - -privacy-from-private-dep-in-public-interface = - {$kind} `{$descr}` from private dependency '{$krate}' in public interface - -private-in-public-lint = - {$vis_descr} {$kind} `{$descr}` in public interface (error {$kind -> - [trait] E0445 - *[other] E0446 - }) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6b961eaeb42af..382b3a20c65bf 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -37,7 +37,6 @@ fluent_messages! { expand => "../locales/en-US/expand.ftl", lint => "../locales/en-US/lint.ftl", parser => "../locales/en-US/parser.ftl", - passes => "../locales/en-US/passes.ftl", privacy => "../locales/en-US/privacy.ftl", typeck => "../locales/en-US/typeck.ftl", } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 7d7f3e1833576..a73758cdb353d 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -40,35 +40,6 @@ pub trait IntoDiagnosticArg { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>; } -macro_rules! into_diagnostic_arg_using_display { - ($( $ty:ty ),+ $(,)?) => { - $( - impl IntoDiagnosticArg for $ty { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - self.to_string().into_diagnostic_arg() - } - } - )+ - } -} - -into_diagnostic_arg_using_display!( - i8, - u8, - i16, - u16, - i32, - u32, - i64, - u64, - i128, - u128, - std::num::NonZeroU32, - hir::Target, - Edition, - Ident, -); - impl IntoDiagnosticArg for bool { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { if self { @@ -79,9 +50,81 @@ impl IntoDiagnosticArg for bool { } } -impl IntoDiagnosticArg for char { +impl IntoDiagnosticArg for i8 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u8 { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self))) + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i16 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u16 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i32 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u32 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i64 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u64 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i128 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u128 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for String { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self)) + } +} + +impl IntoDiagnosticArg for std::num::NonZeroU32 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for Edition { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) } } @@ -91,15 +134,15 @@ impl IntoDiagnosticArg for Symbol { } } -impl<'a> IntoDiagnosticArg for &'a str { +impl IntoDiagnosticArg for Ident { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { self.to_string().into_diagnostic_arg() } } -impl IntoDiagnosticArg for String { +impl<'a> IntoDiagnosticArg for &'a str { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(self)) + self.to_string().into_diagnostic_arg() } } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 9e68ee282e652..99ac6a3546ed6 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -595,7 +595,6 @@ macro_rules! error_code { pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, G>); impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> { - #[rustc_lint_diagnostics] /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`. pub fn build(mut self, msg: impl Into) -> DiagnosticBuilder<'a, G> { self.0.set_primary_message(msg); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 6b5b8b5932018..027f377b0acc7 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -59,7 +59,7 @@ impl<'a> SessionDiagnosticDerive<'a> { return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } (Some(DiagnosticDeriveKind::Lint), _) => { - span_err(span, "only `#[error(..)]` and `#[warning(..)]` are supported") + span_err(span, "only `#[error(..)]` and `#[warn(..)]` are supported") .help("use the `#[error(...)]` attribute to create a error") .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 5c5275b7cfb92..74ce1ab08c264 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -8,13 +8,12 @@ use crate::diagnostics::utils::{ report_error_if_not_applied_to_span, report_type_error, type_is_unit, type_matches_path, Applicability, FieldInfo, FieldInnerTy, HasFieldMap, SetOnce, }; -use proc_macro2::{Ident, Span, TokenStream}; +use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; use std::collections::HashMap; use std::str::FromStr; use syn::{ - parse_quote, spanned::Spanned, Attribute, Field, Meta, MetaList, MetaNameValue, NestedMeta, - Path, Type, + parse_quote, spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path, Type, }; use synstructure::{BindingInfo, Structure}; @@ -81,8 +80,8 @@ impl DiagnosticDeriveBuilder { } pub fn body<'s>(&mut self, structure: &mut Structure<'s>) -> (TokenStream, TokenStream) { - // Keep track of which fields need to be handled with a by-move binding. - let mut needs_moved = std::collections::HashSet::new(); + // Keep track of which fields are subdiagnostics or have no attributes. + let mut subdiagnostics_or_empty = std::collections::HashSet::new(); // Generates calls to `span_label` and similar functions based on the attributes // on fields. Code for suggestions uses formatting machinery and the value of @@ -93,11 +92,16 @@ impl DiagnosticDeriveBuilder { let attrs = structure .clone() .filter(|field_binding| { - let ast = &field_binding.ast(); - !self.needs_move(ast) || { - needs_moved.insert(field_binding.binding.clone()); - false - } + let attrs = &field_binding.ast().attrs; + + (!attrs.is_empty() + && attrs.iter().all(|attr| { + "subdiagnostic" != attr.path.segments.last().unwrap().ident.to_string() + })) + || { + subdiagnostics_or_empty.insert(field_binding.binding.clone()); + false + } }) .each(|field_binding| self.generate_field_attrs_code(field_binding)); @@ -107,41 +111,12 @@ impl DiagnosticDeriveBuilder { // attributes or a `#[subdiagnostic]` attribute then it must be passed as an // argument to the diagnostic so that it can be referred to by Fluent messages. let args = structure - .filter(|field_binding| needs_moved.contains(&field_binding.binding)) + .filter(|field_binding| subdiagnostics_or_empty.contains(&field_binding.binding)) .each(|field_binding| self.generate_field_attrs_code(field_binding)); (attrs, args) } - /// Returns `true` if `field` should generate a `set_arg` call rather than any other diagnostic - /// call (like `span_label`). - fn should_generate_set_arg(&self, field: &Field) -> bool { - field.attrs.is_empty() - } - - /// Returns `true` if `field` needs to have code generated in the by-move branch of the - /// generated derive rather than the by-ref branch. - fn needs_move(&self, field: &Field) -> bool { - let generates_set_arg = self.should_generate_set_arg(field); - let is_multispan = type_matches_path(&field.ty, &["rustc_errors", "MultiSpan"]); - // FIXME(davidtwco): better support for one field needing to be in the by-move and - // by-ref branches. - let is_subdiagnostic = field - .attrs - .iter() - .map(|attr| attr.path.segments.last().unwrap().ident.to_string()) - .any(|attr| attr == "subdiagnostic"); - - // `set_arg` calls take their argument by-move.. - generates_set_arg - // If this is a `MultiSpan` field then it needs to be moved to be used by any - // attribute.. - || is_multispan - // If this a `#[subdiagnostic]` then it needs to be moved as the other diagnostic is - // unlikely to be `Copy`.. - || is_subdiagnostic - } - /// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates /// diagnostic builder calls for setting error code and creating note/help messages. @@ -156,7 +131,7 @@ impl DiagnosticDeriveBuilder { let name = name.as_str(); let meta = attr.parse_meta()?; - let is_help_note_or_warn = matches!(name, "help" | "note" | "warn_"); + let is_help_or_note = matches!(name, "help" | "note"); let nested = match meta { // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or @@ -164,12 +139,8 @@ impl DiagnosticDeriveBuilder { Meta::List(MetaList { ref nested, .. }) => nested, // Subdiagnostics without spans can be applied to the type too, and these are just // paths: `#[help]` and `#[note]` - Meta::Path(_) if is_help_note_or_warn => { - let fn_name = if name == "warn_" { - Ident::new("warn", attr.span()) - } else { - Ident::new(name, attr.span()) - }; + Meta::Path(_) if is_help_or_note => { + let fn_name = proc_macro2::Ident::new(name, attr.span()); return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::_subdiag::#fn_name); }); } _ => throw_invalid_attr!(attr, &meta), @@ -181,11 +152,9 @@ impl DiagnosticDeriveBuilder { "error" => self.kind.set_once((DiagnosticDeriveKind::Error, span)), "warning" => self.kind.set_once((DiagnosticDeriveKind::Warn, span)), "lint" => self.kind.set_once((DiagnosticDeriveKind::Lint, span)), - "help" | "note" | "warn_" => (), + "help" | "note" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help( - "only `error`, `warning`, `help`, `note` and `warn_` are valid attributes", - ) + diag.help("only `error`, `warning`, `help` and `note` are valid attributes") }), } @@ -194,16 +163,14 @@ impl DiagnosticDeriveBuilder { let mut nested_iter = nested.into_iter(); if let Some(nested_attr) = nested_iter.next() { // Report an error if there are any other list items after the path. - if is_help_note_or_warn && nested_iter.next().is_some() { + if is_help_or_note && nested_iter.next().is_some() { throw_invalid_nested_attr!(attr, &nested_attr, |diag| { - diag.help( - "`help`, `note` and `warn_` struct attributes can only have one argument", - ) + diag.help("`help` and `note` struct attributes can only have one argument") }); } match nested_attr { - NestedMeta::Meta(Meta::Path(path)) if is_help_note_or_warn => { + NestedMeta::Meta(Meta::Path(path)) if is_help_or_note => { let fn_name = proc_macro2::Ident::new(name, attr.span()); return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); }); } @@ -211,7 +178,7 @@ impl DiagnosticDeriveBuilder { self.slug.set_once((path.clone(), span)); } NestedMeta::Meta(meta @ Meta::NameValue(_)) - if !is_help_note_or_warn + if !is_help_or_note && meta.path().segments.last().unwrap().ident.to_string() == "code" => { // don't error for valid follow-up attributes @@ -260,55 +227,57 @@ impl DiagnosticDeriveBuilder { let field = binding_info.ast(); let field_binding = &binding_info.binding; - if self.should_generate_set_arg(&field) { + let inner_ty = FieldInnerTy::from_type(&field.ty); + + // When generating `set_arg` or `add_subdiagnostic` calls, move data rather than + // borrow it to avoid requiring clones - this must therefore be the last use of + // each field (for example, any formatting machinery that might refer to a field + // should be generated already). + if field.attrs.is_empty() { let diag = &self.diag; let ident = field.ident.as_ref().unwrap(); - return quote! { + quote! { #diag.set_arg( stringify!(#ident), #field_binding ); - }; + } + } else { + field + .attrs + .iter() + .map(move |attr| { + let name = attr.path.segments.last().unwrap().ident.to_string(); + let (binding, needs_destructure) = match (name.as_str(), &inner_ty) { + // `primary_span` can accept a `Vec` so don't destructure that. + ("primary_span", FieldInnerTy::Vec(_)) => { + (quote! { #field_binding.clone() }, false) + } + // `subdiagnostics` are not derefed because they are bound by value. + ("subdiagnostic", _) => (quote! { #field_binding }, true), + _ => (quote! { *#field_binding }, true), + }; + + let generated_code = self + .generate_inner_field_code( + attr, + FieldInfo { + binding: binding_info, + ty: inner_ty.inner_type().unwrap_or(&field.ty), + span: &field.span(), + }, + binding, + ) + .unwrap_or_else(|v| v.to_compile_error()); + + if needs_destructure { + inner_ty.with(field_binding, generated_code) + } else { + generated_code + } + }) + .collect() } - - let needs_move = self.needs_move(&field); - let inner_ty = FieldInnerTy::from_type(&field.ty); - - field - .attrs - .iter() - .map(move |attr| { - let name = attr.path.segments.last().unwrap().ident.to_string(); - let needs_clone = - name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_)); - let (binding, needs_destructure) = if needs_clone { - // `primary_span` can accept a `Vec` so don't destructure that. - (quote! { #field_binding.clone() }, false) - } else if needs_move { - (quote! { #field_binding }, true) - } else { - (quote! { *#field_binding }, true) - }; - - let generated_code = self - .generate_inner_field_code( - attr, - FieldInfo { - binding: binding_info, - ty: inner_ty.inner_type().unwrap_or(&field.ty), - span: &field.span(), - }, - binding, - ) - .unwrap_or_else(|v| v.to_compile_error()); - - if needs_destructure { - inner_ty.with(field_binding, generated_code) - } else { - generated_code - } - }) - .collect() } fn generate_inner_field_code( @@ -355,12 +324,10 @@ impl DiagnosticDeriveBuilder { report_error_if_not_applied_to_span(attr, &info)?; Ok(self.add_spanned_subdiagnostic(binding, ident, parse_quote! { _subdiag::label })) } - "note" | "help" | "warn_" => { - let warn_ident = Ident::new("warn", Span::call_site()); - let (ident, path) = match name { - "note" => (ident, parse_quote! { _subdiag::note }), - "help" => (ident, parse_quote! { _subdiag::help }), - "warn_" => (&warn_ident, parse_quote! { _subdiag::warn }), + "note" | "help" => { + let path = match name { + "note" => parse_quote! { _subdiag::note }, + "help" => parse_quote! { _subdiag::help }, _ => unreachable!(), }; if type_matches_path(&info.ty, &["rustc_span", "Span"]) { @@ -397,10 +364,10 @@ impl DiagnosticDeriveBuilder { "suggestion" | "suggestion_short" | "suggestion_hidden" | "suggestion_verbose" => { return self.generate_inner_field_code_suggestion(attr, info); } - "label" | "help" | "note" | "warn_" => (), + "label" | "help" | "note" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { diag.help( - "only `label`, `help`, `note`, `warn` or `suggestion{,_short,_hidden,_verbose}` are \ + "only `label`, `note`, `help` or `suggestion{,_short,_hidden,_verbose}` are \ valid field attributes", ) }), @@ -429,14 +396,7 @@ impl DiagnosticDeriveBuilder { Ok(self.add_spanned_subdiagnostic(binding, ident, msg)) } "note" | "help" if type_is_unit(&info.ty) => Ok(self.add_subdiagnostic(ident, msg)), - // `warn_` must be special-cased because the attribute `warn` already has meaning and - // so isn't used, despite the diagnostic API being named `warn`. - "warn_" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => Ok(self - .add_spanned_subdiagnostic(binding, &Ident::new("warn", Span::call_site()), msg)), - "warn_" if type_is_unit(&info.ty) => { - Ok(self.add_subdiagnostic(&Ident::new("warn", Span::call_site()), msg)) - } - "note" | "help" | "warn_" => report_type_error(attr, "`Span` or `()`")?, + "note" | "help" => report_type_error(attr, "`Span` or `()`")?, _ => unreachable!(), } } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 1170d2b3c59a4..2758fcd1310fe 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -260,12 +260,10 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok #generated pub mod _subdiag { - pub const help: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); pub const note: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); - pub const warn: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn")); + pub const help: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); pub const label: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); pub const suggestion: crate::SubdiagnosticMessage = diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index edf4dbed9853e..2a5b6beba94bb 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -37,8 +37,6 @@ enum SubdiagnosticKind { Note, /// `#[help(...)]` Help, - /// `#[warn_(...)]` - Warn, /// `#[suggestion{,_short,_hidden,_verbose}]` Suggestion(SubdiagnosticSuggestionKind), } @@ -51,7 +49,6 @@ impl FromStr for SubdiagnosticKind { "label" => Ok(SubdiagnosticKind::Label), "note" => Ok(SubdiagnosticKind::Note), "help" => Ok(SubdiagnosticKind::Help), - "warn_" => Ok(SubdiagnosticKind::Warn), "suggestion" => Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal)), "suggestion_short" => { Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short)) @@ -73,7 +70,6 @@ impl quote::IdentFragment for SubdiagnosticKind { SubdiagnosticKind::Label => write!(f, "label"), SubdiagnosticKind::Note => write!(f, "note"), SubdiagnosticKind::Help => write!(f, "help"), - SubdiagnosticKind::Warn => write!(f, "warn"), SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal) => { write!(f, "suggestion") } diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 002abb152f759..8977db4606c56 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -85,13 +85,7 @@ pub(crate) fn report_error_if_not_applied_to_span( attr: &Attribute, info: &FieldInfo<'_>, ) -> Result<(), DiagnosticDeriveError> { - if !type_matches_path(&info.ty, &["rustc_span", "Span"]) - && !type_matches_path(&info.ty, &["rustc_errors", "MultiSpan"]) - { - report_type_error(attr, "`Span` or `MultiSpan`")?; - } - - Ok(()) + report_error_if_not_applied_to_ty(attr, info, &["rustc_span", "Span"], "`Span`") } /// Inner type of a field and type of wrapper. diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index ab509b26f1c55..168530c54b99e 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -130,9 +130,8 @@ decl_derive!( warning, error, lint, - help, note, - warn_, + help, // field attributes skip_arg, primary_span, @@ -149,9 +148,8 @@ decl_derive!( warning, error, lint, - help, note, - warn_, + help, // field attributes skip_arg, primary_span, @@ -168,7 +166,6 @@ decl_derive!( label, help, note, - warn_, suggestion, suggestion_short, suggestion_hidden, diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index faa9c493d8875..676812db59ae5 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -15,7 +15,6 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } -rustc_macros = { path = "../rustc_macros" } rustc_ast = { path = "../rustc_ast" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d96e7d3efe83d..e626a1e4ed101 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -4,10 +4,9 @@ //! conflicts between multiple such attributes attached to the same //! item. -use crate::errors; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{fluent, pluralize, struct_span_err, Applicability, MultiSpan}; +use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_expand::base::resolve_path; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; @@ -176,20 +175,16 @@ impl CheckAttrVisitor<'_> { if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) { - match attr.style { - ast::AttrStyle::Outer => self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::OuterCrateLevelAttr, - ), - ast::AttrStyle::Inner => self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::InnerCrateLevelAttr, - ), - } + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + let msg = match attr.style { + ast::AttrStyle::Outer => { + "crate-level attribute should be an inner attribute: add an exclamation \ + mark: `#![foo]`" + } + ast::AttrStyle::Inner => "crate-level attribute should be in the root module", + }; + lint.build(msg).emit(); + }); } } @@ -214,21 +209,37 @@ impl CheckAttrVisitor<'_> { } fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredAttrWithMacro { sym }, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build(&format!( + "`#[{sym}]` is ignored on struct fields, match arms and macro defs", + )) + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .note( + "see issue #80564 \ + for more information", + ) + .emit(); + }); } fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredAttr { sym }, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build(&format!("`#[{sym}]` is ignored on struct fields and match arms")) + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .note( + "see issue #80564 \ + for more information", + ) + .emit(); + }); } /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. @@ -238,12 +249,9 @@ impl CheckAttrVisitor<'_> { | Target::Closure | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredInlineAttrFnProto, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("`#[inline]` is ignored on function prototypes").emit(); + }); true } // FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with @@ -251,12 +259,19 @@ impl CheckAttrVisitor<'_> { // accidentally, to to be compatible with crates depending on them, we can't throw an // error here. Target::AssocConst => { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredInlineAttrConstants, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("`#[inline]` is ignored on constants") + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .note( + "see issue #65833 \ + for more information", + ) + .emit(); + }); true } // FIXME(#80564): Same for fields, arms, and macro defs @@ -265,10 +280,14 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx.sess.emit_err(errors::InlineNotFnOrClosure { - attr_span: attr.span, - defn_span: span, - }); + struct_span_err!( + self.tcx.sess, + attr.span, + E0518, + "attribute should be applied to function or closure", + ) + .span_label(span, "not a function or closure") + .emit(); false } } @@ -290,40 +309,36 @@ impl CheckAttrVisitor<'_> { // function prototypes can't be covered Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredNoCoverageFnProto, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("`#[no_coverage]` is ignored on function prototypes").emit(); + }); true } Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredNoCoveragePropagate, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("`#[no_coverage]` does not propagate into items and must be applied to the contained functions directly").emit(); + }); true } Target::Expression | Target::Statement | Target::Arm => { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredNoCoverageFnDefn, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("`#[no_coverage]` may only be applied to function definitions") + .emit(); + }); true } _ => { - self.tcx.sess.emit_err(errors::IgnoredNoCoverageNotCoverable { - attr_span: attr.span, - defn_span: span, - }); + struct_span_err!( + self.tcx.sess, + attr.span, + E0788, + "`#[no_coverage]` must be applied to coverable code", + ) + .span_label(span, "not coverable code") + .emit(); false } } @@ -374,10 +389,14 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { - attr_span: attr.span, - defn_span: span, - }); + self.tcx + .sess + .struct_span_err( + attr.span, + "attribute should be applied to a function definition", + ) + .span_label(span, "not a function definition") + .emit(); false } } @@ -389,10 +408,14 @@ impl CheckAttrVisitor<'_> { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { - attr_span: attr.span, - defn_span: span, - }); + self.tcx + .sess + .struct_span_err( + attr.span, + "attribute should be applied to a function definition", + ) + .span_label(span, "not a function definition") + .emit(); false } } @@ -409,7 +432,13 @@ impl CheckAttrVisitor<'_> { ) -> bool { match target { _ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => { - self.tcx.sess.emit_err(errors::NakedTrackedCaller { attr_span }); + struct_span_err!( + self.tcx.sess, + attr_span, + E0736, + "cannot use `#[track_caller]` with `#[naked]`", + ) + .emit(); false } Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true, @@ -424,9 +453,14 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx - .sess - .emit_err(errors::TrackedCallerWrongLocation { attr_span, defn_span: span }); + struct_span_err!( + self.tcx.sess, + attr_span, + E0739, + "attribute should be applied to function" + ) + .span_label(span, "not a function") + .emit(); false } } @@ -451,10 +485,14 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx.sess.emit_err(errors::NonExhaustiveWrongLocation { - attr_span: attr.span, - defn_span: span, - }); + struct_span_err!( + self.tcx.sess, + attr.span, + E0701, + "attribute can only be applied to a struct or enum" + ) + .span_label(span, "not a struct or enum") + .emit(); false } } @@ -473,10 +511,11 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToTrait { - attr_span: attr.span, - defn_span: span, - }); + self.tcx + .sess + .struct_span_err(attr.span, "attribute can only be applied to a trait") + .span_label(span, "not a trait") + .emit(); false } } @@ -492,10 +531,11 @@ impl CheckAttrVisitor<'_> { match target { Target::Trait => true, _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToTrait { - attr_span: attr.span, - defn_span: span, - }); + self.tcx + .sess + .struct_span_err(attr.span, "attribute can only be applied to a trait") + .span_label(span, "not a trait") + .emit(); false } } @@ -515,12 +555,16 @@ impl CheckAttrVisitor<'_> { // FIXME: #[target_feature] was previously erroneously allowed on statements and some // crates used this, so only emit a warning. Target::Statement => { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::TargetFeatureOnStatement, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("attribute should be applied to a function") + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .span_label(span, "not a function") + .emit(); + }); true } // FIXME(#80564): We permit struct fields, match arms and macro defs to have an @@ -532,10 +576,11 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { - attr_span: attr.span, - defn_span: span, - }); + self.tcx + .sess + .struct_span_err(attr.span, "attribute should be applied to a function") + .span_label(span, "not a function") + .emit(); false } } @@ -546,17 +591,24 @@ impl CheckAttrVisitor<'_> { match target { Target::ForeignStatic | Target::Static => true, _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToStatic { - attr_span: attr.span, - defn_span: span, - }); + self.tcx + .sess + .struct_span_err(attr.span, "attribute should be applied to a static") + .span_label(span, "not a static") + .emit(); false } } } fn doc_attr_str_error(&self, meta: &NestedMetaItem, attr_name: &str) { - self.tcx.sess.emit_err(errors::DocExpectStr { attr_span: meta.span(), attr_name }); + self.tcx + .sess + .struct_span_err( + meta.span(), + &format!("doc {0} attribute expects a string: #[doc({0} = \"a\")]", attr_name), + ) + .emit(); } fn check_doc_alias_value( @@ -569,12 +621,22 @@ impl CheckAttrVisitor<'_> { aliases: &mut FxHashMap, ) -> bool { let tcx = self.tcx; - let span = meta.name_value_literal_span().unwrap_or_else(|| meta.span()); - let attr_str = - &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" }); + let err_fn = move |span: Span, msg: &str| { + tcx.sess.span_err( + span, + &format!( + "`#[doc(alias{})]` {}", + if is_list { "(\"...\")" } else { " = \"...\"" }, + msg, + ), + ); + false + }; if doc_alias == kw::Empty { - tcx.sess.emit_err(errors::DocAliasEmpty { span, attr_str }); - return false; + return err_fn( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + "attribute cannot have empty value", + ); } let doc_alias_str = doc_alias.as_str(); @@ -582,16 +644,23 @@ impl CheckAttrVisitor<'_> { .chars() .find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) { - tcx.sess.emit_err(errors::DocAliasBadChar { span, attr_str, char_: c }); + self.tcx.sess.span_err( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + &format!( + "{:?} character isn't allowed in `#[doc(alias{})]`", + c, + if is_list { "(\"...\")" } else { " = \"...\"" }, + ), + ); return false; } if doc_alias_str.starts_with(' ') || doc_alias_str.ends_with(' ') { - tcx.sess.emit_err(errors::DocAliasStartEnd { span, attr_str }); - return false; + return err_fn( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + "cannot start or end with ' '", + ); } - - let span = meta.span(); - if let Some(location) = match target { + if let Some(err) = match target { Target::Impl => Some("implementation block"), Target::ForeignMod => Some("extern block"), Target::AssocTy => { @@ -617,21 +686,19 @@ impl CheckAttrVisitor<'_> { Target::Param => return false, _ => None, } { - tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location }); - return false; + return err_fn(meta.span(), &format!("isn't allowed on {}", err)); } let item_name = self.tcx.hir().name(hir_id); if item_name == doc_alias { - tcx.sess.emit_err(errors::DocAliasNotAnAlias { span, attr_str }); - return false; + return err_fn(meta.span(), "is the same as the item's name"); } + let span = meta.span(); if let Err(entry) = aliases.try_insert(doc_alias_str.to_owned(), span) { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - span, - errors::DocAliasDuplicated { first_defn: *entry.entry.get() }, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| { + lint.build("doc alias is duplicated") + .span_label(*entry.entry.get(), "first defined here") + .emit(); + }); } true } @@ -656,12 +723,22 @@ impl CheckAttrVisitor<'_> { _ => { self.tcx .sess - .emit_err(errors::DocAliasNotStringLiteral { span: v.span() }); + .struct_span_err( + v.span(), + "`#[doc(alias(\"a\"))]` expects string literals", + ) + .emit(); errors += 1; } }, None => { - self.tcx.sess.emit_err(errors::DocAliasNotStringLiteral { span: v.span() }); + self.tcx + .sess + .struct_span_err( + v.span(), + "`#[doc(alias(\"a\"))]` expects string literals", + ) + .emit(); errors += 1; } } @@ -670,7 +747,14 @@ impl CheckAttrVisitor<'_> { } else if let Some(doc_alias) = meta.value_str() { self.check_doc_alias_value(meta, doc_alias, hir_id, target, false, aliases) } else { - self.tcx.sess.emit_err(errors::DocAliasMalformed { span: meta.span() }); + self.tcx + .sess + .struct_span_err( + meta.span(), + "doc alias attribute expects a string `#[doc(alias = \"a\")]` or a list of \ + strings `#[doc(alias(\"a\", \"b\"))]`", + ) + .emit(); false } } @@ -687,20 +771,35 @@ impl CheckAttrVisitor<'_> { }) { Some(ItemKind::Mod(ref module)) => { if !module.item_ids.is_empty() { - self.tcx.sess.emit_err(errors::DocKeywordEmptyMod { span: meta.span() }); + self.tcx + .sess + .struct_span_err( + meta.span(), + "`#[doc(keyword = \"...\")]` can only be used on empty modules", + ) + .emit(); return false; } } _ => { - self.tcx.sess.emit_err(errors::DocKeywordNotMod { span: meta.span() }); + self.tcx + .sess + .struct_span_err( + meta.span(), + "`#[doc(keyword = \"...\")]` can only be used on modules", + ) + .emit(); return false; } } if !rustc_lexer::is_ident(doc_keyword.as_str()) { - self.tcx.sess.emit_err(errors::DocKeywordInvalidIdent { - span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - doc_keyword, - }); + self.tcx + .sess + .struct_span_err( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + &format!("`{doc_keyword}` is not a valid identifier"), + ) + .emit(); return false; } true @@ -713,12 +812,24 @@ impl CheckAttrVisitor<'_> { }) { Some(ItemKind::Impl(ref i)) => { if !matches!(&i.self_ty.kind, hir::TyKind::Tup([_])) { - self.tcx.sess.emit_err(errors::DocTupleVariadicNotFirst { span: meta.span() }); + self.tcx + .sess + .struct_span_err( + meta.span(), + "`#[doc(tuple_variadic)]` must be used on the first of a set of tuple trait impls with varying arity", + ) + .emit(); return false; } } _ => { - self.tcx.sess.emit_err(errors::DocKeywordOnlyImpl { span: meta.span() }); + self.tcx + .sess + .struct_span_err( + meta.span(), + "`#[doc(keyword = \"...\")]` can only be used on impl blocks", + ) + .emit(); return false; } } @@ -747,9 +858,13 @@ impl CheckAttrVisitor<'_> { if let Some((prev_inline, prev_span)) = *specified_inline { if do_inline != prev_inline { let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]); - spans.push_span_label(prev_span, fluent::passes::doc_inline_conflict_first); - spans.push_span_label(meta.span(), fluent::passes::doc_inline_conflict_second); - self.tcx.sess.emit_err(errors::DocKeywordConflict { spans }); + spans.push_span_label(prev_span, "this attribute..."); + spans.push_span_label(meta.span(), "...conflicts with this attribute"); + self.tcx + .sess + .struct_span_err(spans, "conflicting doc inlining attributes") + .help("remove one of the conflicting attributes") + .emit(); return false; } true @@ -758,14 +873,23 @@ impl CheckAttrVisitor<'_> { true } } else { - self.tcx.emit_spanned_lint( + self.tcx.struct_span_lint_hir( INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), - errors::DocInlineOnlyUse { - attr_span: meta.span(), - item_span: (attr.style == AttrStyle::Outer) - .then(|| self.tcx.hir().span(hir_id)), + |lint| { + let mut err = lint.build( + "this attribute can only be applied to a `use` item", + ); + err.span_label(meta.span(), "only applicable on `use` items"); + if attr.style == AttrStyle::Outer { + err.span_label( + self.tcx.hir().span(hir_id), + "not a `use` item", + ); + } + err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information") + .emit(); }, ); false @@ -780,7 +904,15 @@ impl CheckAttrVisitor<'_> { attr_name: &str, ) -> bool { if CRATE_HIR_ID == hir_id { - self.tcx.sess.emit_err(errors::DocAttrNotCrateLevel { span: meta.span(), attr_name }); + self.tcx + .sess + .struct_span_err( + meta.span(), + &format!( + "`#![doc({attr_name} = \"...\")]` isn't allowed as a crate-level attribute", + ), + ) + .emit(); return false; } true @@ -794,25 +926,36 @@ impl CheckAttrVisitor<'_> { hir_id: HirId, ) -> bool { if hir_id != CRATE_HIR_ID { - self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| { - let mut err = lint.build(fluent::passes::attr_crate_level); - if attr.style == AttrStyle::Outer - && self.tcx.hir().get_parent_item(hir_id) == CRATE_DEF_ID - { - if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) { - src.insert(1, '!'); - err.span_suggestion_verbose( - attr.span, - fluent::passes::suggestion, - src, - Applicability::MaybeIncorrect, - ); - } else { - err.span_help(attr.span, fluent::passes::help); + self.tcx.struct_span_lint_hir( + INVALID_DOC_ATTRIBUTES, + hir_id, + meta.span(), + |lint| { + let mut err = lint.build( + "this attribute can only be applied at the crate level", + ); + if attr.style == AttrStyle::Outer && self.tcx.hir().get_parent_item(hir_id) == CRATE_DEF_ID { + if let Ok(mut src) = + self.tcx.sess.source_map().span_to_snippet(attr.span) + { + src.insert(1, '!'); + err.span_suggestion_verbose( + attr.span, + "to apply to the crate, use an inner attribute", + src, + Applicability::MaybeIncorrect, + ); + } else { + err.span_help( + attr.span, + "to apply to the crate, use an inner attribute", + ); + } } - } - err.note(fluent::passes::note).emit(); - }); + err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information") + .emit(); + }, + ); return false; } true @@ -827,14 +970,18 @@ impl CheckAttrVisitor<'_> { match i_meta.name_or_empty() { sym::attr | sym::no_crate_inject => {} _ => { - self.tcx.emit_spanned_lint( + self.tcx.struct_span_lint_hir( INVALID_DOC_ATTRIBUTES, hir_id, i_meta.span(), - errors::DocTestUnknown { - path: rustc_ast_pretty::pprust::path_to_string( - &i_meta.meta_item().unwrap().path, - ), + |lint| { + lint.build(&format!( + "unknown `doc(test)` attribute `{}`", + rustc_ast_pretty::pprust::path_to_string( + &i_meta.meta_item().unwrap().path + ), + )) + .emit(); }, ); is_valid = false; @@ -842,12 +989,9 @@ impl CheckAttrVisitor<'_> { } } } else { - self.tcx.emit_spanned_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocTestTakesList, - ); + self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| { + lint.build("`#[doc(test(...)]` takes a list of attributes").emit(); + }); is_valid = false; } is_valid @@ -949,66 +1093,79 @@ impl CheckAttrVisitor<'_> { sym::primitive => { if !self.tcx.features().rustdoc_internals { - self.tcx.emit_spanned_lint( + self.tcx.struct_span_lint_hir( INVALID_DOC_ATTRIBUTES, hir_id, i_meta.span, - errors::DocPrimitive, + |lint| { + let mut diag = lint.build( + "`doc(primitive)` should never have been stable", + ); + diag.emit(); + }, ); } } _ => { - let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); - if i_meta.has_name(sym::spotlight) { - self.tcx.emit_spanned_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownSpotlight { - path, - span: i_meta.span + self.tcx.struct_span_lint_hir( + INVALID_DOC_ATTRIBUTES, + hir_id, + i_meta.span, + |lint| { + let mut diag = lint.build(&format!( + "unknown `doc` attribute `{}`", + rustc_ast_pretty::pprust::path_to_string(&i_meta.path), + )); + if i_meta.has_name(sym::spotlight) { + diag.note( + "`doc(spotlight)` was renamed to `doc(notable_trait)`", + ); + diag.span_suggestion_short( + i_meta.span, + "use `notable_trait` instead", + "notable_trait", + Applicability::MachineApplicable, + ); + diag.note("`doc(spotlight)` is now a no-op"); } - ); - } else if i_meta.has_name(sym::include) && - let Some(value) = i_meta.value_str() { - let applicability = if list.len() == 1 { - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - // If there are multiple attributes, the suggestion would suggest - // deleting all of them, which is incorrect. - self.tcx.emit_spanned_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownInclude { - path, - value: value.to_string(), - inner: (attr.style == AttrStyle::Inner) - .then_some("!") - .unwrap_or(""), - sugg: (attr.meta().unwrap().span, applicability), + if i_meta.has_name(sym::include) { + if let Some(value) = i_meta.value_str() { + // if there are multiple attributes, the suggestion would suggest deleting all of them, which is incorrect + let applicability = if list.len() == 1 { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + let inner = if attr.style == AttrStyle::Inner { + "!" + } else { + "" + }; + diag.span_suggestion( + attr.meta().unwrap().span, + "use `doc = include_str!` instead", + format!( + "#{inner}[doc = include_str!(\"{value}\")]", + ), + applicability, + ); + } } - ); - } else { - self.tcx.emit_spanned_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownAny { path } - ); - } + diag.emit(); + }, + ); is_valid = false; } } } else { - self.tcx.emit_spanned_lint( + self.tcx.struct_span_lint_hir( INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), - errors::DocInvalid, + |lint| { + lint.build("invalid `doc` attribute").emit(); + }, ); is_valid = false; } @@ -1023,7 +1180,14 @@ impl CheckAttrVisitor<'_> { match target { Target::Struct | Target::Enum | Target::TyAlias => true, _ => { - self.tcx.sess.emit_err(errors::PassByValue { attr_span: attr.span, span }); + self.tcx + .sess + .struct_span_err( + attr.span, + "`pass_by_value` attribute should be applied to a struct, enum or type alias.", + ) + .span_label(span, "is not a struct, enum or type alias") + .emit(); false } } @@ -1033,7 +1197,14 @@ impl CheckAttrVisitor<'_> { match target { Target::Method(MethodKind::Inherent) => true, _ => { - self.tcx.sess.emit_err(errors::AllowIncoherentImpl { attr_span: attr.span, span }); + self.tcx + .sess + .struct_span_err( + attr.span, + "`rustc_allow_incoherent_impl` attribute should be applied to impl items.", + ) + .span_label(span, "the only currently supported targets are inherent methods") + .emit(); false } } @@ -1052,7 +1223,12 @@ impl CheckAttrVisitor<'_> { _ => { self.tcx .sess - .emit_err(errors::HasIncoherentInherentImpl { attr_span: attr.span, span }); + .struct_span_err( + attr.span, + "`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.", + ) + .span_label(span, "only adts, extern types and traits are supported") + .emit(); false } } @@ -1062,12 +1238,19 @@ impl CheckAttrVisitor<'_> { fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { let node = self.tcx.hir().get(hir_id); if let Some(kind) = node.fn_kind() && let rustc_hir::IsAsync::Async = kind.asyncness() { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseAsync { span } - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build( + "`must_use` attribute on `async` functions \ + applies to the anonymous `Future` returned by the \ + function, not the value within", + ) + .span_label( + span, + "this attribute does nothing, the `Future`s \ + returned by async functions are already `must_use`", + ) + .emit(); + }); } if !matches!( @@ -1095,12 +1278,12 @@ impl CheckAttrVisitor<'_> { _ => "a", }; - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseNoEffect { article, target }, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build(&format!( + "`#[must_use]` has no effect when applied to {article} {target}" + )) + .emit(); + }); } // For now, its always valid @@ -1112,7 +1295,11 @@ impl CheckAttrVisitor<'_> { match target { Target::Struct | Target::Enum | Target::Union | Target::Trait => true, _ => { - self.tcx.sess.emit_err(errors::MustNotSuspend { attr_span: attr.span, span }); + self.tcx + .sess + .struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, or trait") + .span_label(span, "is not a struct, enum, or trait") + .emit(); false } } @@ -1132,12 +1319,16 @@ impl CheckAttrVisitor<'_> { _ => { // FIXME: #[cold] was previously allowed on non-functions and some crates used // this, so only emit a warning. - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::Cold { span }, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build("attribute should be applied to a function") + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .span_label(span, "not a function") + .emit(); + }); } } } @@ -1152,12 +1343,19 @@ impl CheckAttrVisitor<'_> { return; } - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::Link { span: (target != Target::ForeignMod).then_some(span) }, - ); + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + let mut diag = + lint.build("attribute should be applied to an `extern` block with non-Rust ABI"); + diag.warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ); + if target != Target::ForeignMod { + diag.span_label(span, "not an `extern` block"); + } + diag.emit(); + }); } /// Checks if `#[link_name]` is applied to an item other than a foreign function or static. diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs deleted file mode 100644 index f8e8720ab5474..0000000000000 --- a/compiler/rustc_passes/src/errors.rs +++ /dev/null @@ -1,362 +0,0 @@ -use rustc_errors::{Applicability, MultiSpan}; -use rustc_macros::{LintDiagnostic, SessionDiagnostic}; -use rustc_span::{Span, Symbol}; - -#[derive(LintDiagnostic)] -#[lint(passes::outer_crate_level_attr)] -pub struct OuterCrateLevelAttr; - -#[derive(LintDiagnostic)] -#[lint(passes::inner_crate_level_attr)] -pub struct InnerCrateLevelAttr; - -#[derive(LintDiagnostic)] -#[lint(passes::ignored_attr_with_macro)] -pub struct IgnoredAttrWithMacro<'a> { - pub sym: &'a str, -} - -#[derive(LintDiagnostic)] -#[lint(passes::ignored_attr)] -pub struct IgnoredAttr<'a> { - pub sym: &'a str, -} - -#[derive(LintDiagnostic)] -#[lint(passes::inline_ignored_function_prototype)] -pub struct IgnoredInlineAttrFnProto; - -#[derive(LintDiagnostic)] -#[lint(passes::inline_ignored_constants)] -#[warn_] -#[note] -pub struct IgnoredInlineAttrConstants; - -#[derive(SessionDiagnostic)] -#[error(passes::inline_not_fn_or_closure, code = "E0518")] -pub struct InlineNotFnOrClosure { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::no_coverage_ignored_function_prototype)] -pub struct IgnoredNoCoverageFnProto; - -#[derive(LintDiagnostic)] -#[lint(passes::no_coverage_propagate)] -pub struct IgnoredNoCoveragePropagate; - -#[derive(LintDiagnostic)] -#[lint(passes::no_coverage_fn_defn)] -pub struct IgnoredNoCoverageFnDefn; - -#[derive(SessionDiagnostic)] -#[error(passes::no_coverage_not_coverable, code = "E0788")] -pub struct IgnoredNoCoverageNotCoverable { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_fn)] -pub struct AttrShouldBeAppliedToFn { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::naked_tracked_caller, code = "E0736")] -pub struct NakedTrackedCaller { - #[primary_span] - pub attr_span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_fn, code = "E0739")] -pub struct TrackedCallerWrongLocation { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_struct_enum, code = "E0701")] -pub struct NonExhaustiveWrongLocation { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_trait)] -pub struct AttrShouldBeAppliedToTrait { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::target_feature_on_statement)] -pub struct TargetFeatureOnStatement; - -#[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_static)] -pub struct AttrShouldBeAppliedToStatic { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_expect_str)] -pub struct DocExpectStr<'a> { - #[primary_span] - pub attr_span: Span, - pub attr_name: &'a str, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_empty)] -pub struct DocAliasEmpty<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_bad_char)] -pub struct DocAliasBadChar<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, - pub char_: char, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_start_end)] -pub struct DocAliasStartEnd<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_bad_location)] -pub struct DocAliasBadLocation<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, - pub location: &'a str, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_not_an_alias)] -pub struct DocAliasNotAnAlias<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_alias_duplicated)] -pub struct DocAliasDuplicated { - #[label] - pub first_defn: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_not_string_literal)] -pub struct DocAliasNotStringLiteral { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_alias_malformed)] -pub struct DocAliasMalformed { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_empty_mod)] -pub struct DocKeywordEmptyMod { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_not_mod)] -pub struct DocKeywordNotMod { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_invalid_ident)] -pub struct DocKeywordInvalidIdent { - #[primary_span] - pub span: Span, - pub doc_keyword: Symbol, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_tuple_variadic_not_first)] -pub struct DocTupleVariadicNotFirst { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_only_impl)] -pub struct DocKeywordOnlyImpl { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_inline_conflict)] -#[help] -pub struct DocKeywordConflict { - #[primary_span] - pub spans: MultiSpan, -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_inline_only_use)] -#[note] -pub struct DocInlineOnlyUse { - #[label] - pub attr_span: Span, - #[label(passes::not_a_use_item_label)] - pub item_span: Option, -} - -#[derive(SessionDiagnostic)] -#[error(passes::doc_attr_not_crate_level)] -pub struct DocAttrNotCrateLevel<'a> { - #[primary_span] - pub span: Span, - pub attr_name: &'a str, -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown)] -pub struct DocTestUnknown { - pub path: String, -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_test_takes_list)] -pub struct DocTestTakesList; - -#[derive(LintDiagnostic)] -#[lint(passes::doc_primitive)] -pub struct DocPrimitive; - -#[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown_any)] -pub struct DocTestUnknownAny { - pub path: String, -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown_spotlight)] -#[note] -#[note(passes::no_op_note)] -pub struct DocTestUnknownSpotlight { - pub path: String, - #[suggestion_short(applicability = "machine-applicable", code = "notable_trait")] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown_include)] -pub struct DocTestUnknownInclude { - pub path: String, - pub value: String, - pub inner: &'static str, - #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] - pub sugg: (Span, Applicability), -} - -#[derive(LintDiagnostic)] -#[lint(passes::doc_invalid)] -pub struct DocInvalid; - -#[derive(SessionDiagnostic)] -#[error(passes::pass_by_value)] -pub struct PassByValue { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::allow_incoherent_impl)] -pub struct AllowIncoherentImpl { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(passes::has_incoherent_inherent_impl)] -pub struct HasIncoherentInherentImpl { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::must_use_async)] -pub struct MustUseAsync { - #[label] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::must_use_no_effect)] -pub struct MustUseNoEffect { - pub article: &'static str, - pub target: rustc_hir::Target, -} - -#[derive(SessionDiagnostic)] -#[error(passes::must_not_suspend)] -pub struct MustNotSuspend { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::cold)] -#[warn_] -pub struct Cold { - #[label] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[lint(passes::link)] -#[warn_] -pub struct Link { - #[label] - pub span: Option, -} diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index defa9d15296e0..497c0931c2182 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -7,8 +7,8 @@ #![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(iter_intersperse)] -#![cfg_attr(bootstrap, feature(let_chains))] #![feature(let_else)] +#![feature(let_chains)] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(try_blocks)] @@ -27,7 +27,6 @@ pub mod dead; mod debugger_visualizer; mod diagnostic_items; pub mod entry; -mod errors; pub mod hir_id_validator; pub mod hir_stats; mod lang_items; diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index b0fac91f6ebc3..482721d373ab7 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] @@ -73,19 +73,3 @@ pub struct InPublicInterface<'a> { #[label(privacy::visibility_label)] pub vis_span: Span, } - -#[derive(LintDiagnostic)] -#[lint(privacy::from_private_dep_in_public_interface)] -pub struct FromPrivateDependencyInPublicInterface<'a> { - pub kind: &'a str, - pub descr: String, - pub krate: Symbol, -} - -#[derive(LintDiagnostic)] -#[lint(privacy::private_in_public_lint)] -pub struct PrivateInPublicLint<'a> { - pub vis_descr: &'static str, - pub kind: &'a str, - pub descr: String, -} diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9a835808d4935..5b21c04664774 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -38,8 +38,8 @@ use std::ops::ControlFlow; use std::{cmp, fmt, mem}; use errors::{ - FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, UnnamedItemIsPrivate, + FieldIsPrivate, FieldIsPrivateLabel, InPublicInterface, InPublicInterfaceTraits, ItemIsPrivate, + UnnamedItemIsPrivate, }; //////////////////////////////////////////////////////////////////////////////// @@ -1716,14 +1716,19 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { - self.tcx.emit_spanned_lint( + self.tcx.struct_span_lint_hir( lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES, self.tcx.hir().local_def_id_to_hir_id(self.item_def_id), self.tcx.def_span(self.item_def_id.to_def_id()), - FromPrivateDependencyInPublicInterface { - kind, - descr: descr.to_string(), - krate: self.tcx.crate_name(def_id.krate), + |lint| { + lint.build(&format!( + "{} `{}` from private dependency '{}' in public \ + interface", + kind, + descr, + self.tcx.crate_name(def_id.krate) + )) + .emit(); }, ); } @@ -1749,14 +1754,12 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } }; let span = self.tcx.def_span(self.item_def_id.to_def_id()); - let descr = descr.to_string(); if self.has_old_errors || self.in_assoc_ty || self.tcx.resolutions(()).has_pub_restricted { let descr = descr.to_string(); - let vis_span = - self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id)); + let vis_span = self.tcx.def_span(def_id); if kind == "trait" { self.tcx.sess.emit_err(InPublicInterfaceTraits { span, @@ -1775,11 +1778,19 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { }); } } else { - self.tcx.emit_spanned_lint( + let err_code = if kind == "trait" { "E0445" } else { "E0446" }; + self.tcx.struct_span_lint_hir( lint::builtin::PRIVATE_IN_PUBLIC, hir_id, span, - PrivateInPublicLint { vis_descr, kind, descr }, + |lint| { + lint.build(&format!( + "{} (error {})", + format!("{} {} `{}` in public interface", vis_descr, kind, descr), + err_code + )) + .emit(); + }, ); } } diff --git a/src/test/rustdoc-ui/invalid-doc-attr.stderr b/src/test/rustdoc-ui/invalid-doc-attr.stderr index a4fa3817905c7..55006b2087eb0 100644 --- a/src/test/rustdoc-ui/invalid-doc-attr.stderr +++ b/src/test/rustdoc-ui/invalid-doc-attr.stderr @@ -12,7 +12,7 @@ LL | #![deny(warnings)] = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information help: to apply to the crate, use an inner attribute | LL | #![doc(test(no_crate_inject))] @@ -29,7 +29,7 @@ LL | pub fn foo() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: this attribute can only be applied at the crate level --> $DIR/invalid-doc-attr.rs:15:12 @@ -39,7 +39,7 @@ LL | #![doc(test(no_crate_inject))] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information error: conflicting doc inlining attributes --> $DIR/invalid-doc-attr.rs:28:7 @@ -59,7 +59,7 @@ LL | #[doc(test(no_crate_inject))] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information error: this attribute can only be applied to a `use` item --> $DIR/invalid-doc-attr.rs:22:11 @@ -72,7 +72,7 @@ LL | pub fn baz() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: aborting due to 6 previous errors diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 0a210cbdc9430..56e95d70fd53d 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -23,7 +23,7 @@ extern crate rustc_middle; use rustc_middle::ty::Ty; extern crate rustc_errors; -use rustc_errors::{Applicability, MultiSpan}; +use rustc_errors::Applicability; extern crate rustc_session; @@ -140,7 +140,7 @@ struct CodeNotProvided {} #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct MessageWrongType { #[primary_span] - //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` + //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` foo: String, } @@ -165,7 +165,7 @@ struct ErrorWithField { #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithMessageAppliedToField { #[label(typeck::label)] - //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` name: String, } @@ -208,7 +208,7 @@ struct LabelOnSpan { #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelOnNonSpan { #[label(typeck::label)] - //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` id: u32, } @@ -538,7 +538,7 @@ struct LabelWithTrailingList { #[derive(SessionDiagnostic)] #[lint(typeck::ambiguous_lifetime_bound)] -//~^ ERROR only `#[error(..)]` and `#[warning(..)]` are supported +//~^ ERROR only `#[error(..)]` and `#[warn(..)]` are supported struct LintsBad { } @@ -552,17 +552,3 @@ struct LintsGood { //~^ ERROR only `#[lint(..)]` is supported struct ErrorsBad { } - -#[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] -struct ErrorWithMultiSpan { - #[primary_span] - span: MultiSpan, -} - -#[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[warn_] -struct ErrorWithWarn { - val: String, -} diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index c1080aa24521f..e282884289db3 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -21,7 +21,7 @@ error: `#[nonsense(...)]` is not a valid attribute LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: only `error`, `warning`, `help`, `note` and `warn_` are valid attributes + = help: only `error`, `warning`, `help` and `note` are valid attributes error: diagnostic kind not specified --> $DIR/diagnostic-derive.rs:53:1 @@ -233,7 +233,7 @@ LL | | struct SlugNotProvided {} | = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` -error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` +error: the `#[primary_span]` attribute can only be applied to fields of type `Span` --> $DIR/diagnostic-derive.rs:142:5 | LL | #[primary_span] @@ -247,7 +247,7 @@ LL | #[nonsense] | = help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes -error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` +error: the `#[label(...)]` attribute can only be applied to fields of type `Span` --> $DIR/diagnostic-derive.rs:167:5 | LL | #[label(typeck::label)] @@ -279,7 +279,7 @@ LL | #[derive(SessionDiagnostic)] = note: if you intended to print `}`, you can escape it using `}}` = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` +error: the `#[label(...)]` attribute can only be applied to fields of type `Span` --> $DIR/diagnostic-derive.rs:210:5 | LL | #[label(typeck::label)] @@ -363,7 +363,7 @@ error: `#[label(...)]` is not a valid attribute LL | #[label(typeck::label, foo("..."))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: only `#[error(..)]` and `#[warning(..)]` are supported +error: only `#[error(..)]` and `#[warn(..)]` are supported --> $DIR/diagnostic-derive.rs:540:1 | LL | / #[lint(typeck::ambiguous_lifetime_bound)] diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 16da25c402b57..6f4b6105b3e49 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -244,7 +244,7 @@ enum V { //~^ ERROR label without `#[primary_span]` field struct W { #[primary_span] - //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` + //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` span: String, } @@ -508,15 +508,3 @@ enum AX { span: Span, } } - -#[derive(SessionSubdiagnostic)] -#[warn_(parser::add_paren)] -struct AY { -} - -#[derive(SessionSubdiagnostic)] -#[warn_(parser::add_paren)] -struct AZ { - #[primary_span] - span: Span, -} diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index a289c4fffd936..f833bd210f7f5 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -120,7 +120,7 @@ error: subdiagnostic kind not specified LL | B { | ^ -error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` +error: the `#[primary_span]` attribute can only be applied to fields of type `Span` --> $DIR/subdiagnostic-derive.rs:246:5 | LL | #[primary_span] diff --git a/src/test/ui/attributes/invalid-doc-attr.stderr b/src/test/ui/attributes/invalid-doc-attr.stderr index a4fa3817905c7..55006b2087eb0 100644 --- a/src/test/ui/attributes/invalid-doc-attr.stderr +++ b/src/test/ui/attributes/invalid-doc-attr.stderr @@ -12,7 +12,7 @@ LL | #![deny(warnings)] = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information help: to apply to the crate, use an inner attribute | LL | #![doc(test(no_crate_inject))] @@ -29,7 +29,7 @@ LL | pub fn foo() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: this attribute can only be applied at the crate level --> $DIR/invalid-doc-attr.rs:15:12 @@ -39,7 +39,7 @@ LL | #![doc(test(no_crate_inject))] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information error: conflicting doc inlining attributes --> $DIR/invalid-doc-attr.rs:28:7 @@ -59,7 +59,7 @@ LL | #[doc(test(no_crate_inject))] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information error: this attribute can only be applied to a `use` item --> $DIR/invalid-doc-attr.rs:22:11 @@ -72,7 +72,7 @@ LL | pub fn baz() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: aborting due to 6 previous errors diff --git a/src/test/ui/attributes/multiple-invalid.stderr b/src/test/ui/attributes/multiple-invalid.stderr index a8dba0ba37d3a..9bd29f15dbcca 100644 --- a/src/test/ui/attributes/multiple-invalid.stderr +++ b/src/test/ui/attributes/multiple-invalid.stderr @@ -7,14 +7,14 @@ LL | #[inline] LL | const FOO: u8 = 0; | ------------------ not a function or closure -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/multiple-invalid.rs:6:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | const FOO: u8 = 0; - | ------------------ not a function definition + | ------------------ not a function error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 5d6796b49448a..3f838fcf52355 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -259,7 +259,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] | ^^^^^^^^^ -warning: attribute should be applied to a function definition +warning: attribute should be applied to a function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:453:1 | LL | #[cold] @@ -272,7 +272,7 @@ LL | | mod inner { #![cold] } ... | LL | | LL | | } - | |_- not a function definition + | |_- not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -399,7 +399,7 @@ warning: `#[proc_macro_derive]` only has an effect on functions LL | #![proc_macro_derive()] | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: attribute should be applied to a function definition +warning: attribute should be applied to a function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 | LL | #![cold] @@ -743,35 +743,35 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] impl S { } | ^^^^^^^^^ -warning: attribute should be applied to a function definition +warning: attribute should be applied to a function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:17 | LL | mod inner { #![cold] } - | ------------^^^^^^^^-- not a function definition + | ------------^^^^^^^^-- not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -warning: attribute should be applied to a function definition +warning: attribute should be applied to a function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5 | LL | #[cold] struct S; - | ^^^^^^^ --------- not a function definition + | ^^^^^^^ --------- not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -warning: attribute should be applied to a function definition +warning: attribute should be applied to a function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5 | LL | #[cold] type T = S; - | ^^^^^^^ ----------- not a function definition + | ^^^^^^^ ----------- not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -warning: attribute should be applied to a function definition +warning: attribute should be applied to a function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:5 | LL | #[cold] impl S { } - | ^^^^^^^ ---------- not a function definition + | ^^^^^^^ ---------- not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 8f6dde665e628..d822847a7a589 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -22,7 +22,7 @@ LL | #![deny(future_incompatible)] = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/issues/issue-54044.stderr b/src/test/ui/issues/issue-54044.stderr index 100965de1aa84..0200a6a629d8f 100644 --- a/src/test/ui/issues/issue-54044.stderr +++ b/src/test/ui/issues/issue-54044.stderr @@ -1,11 +1,11 @@ -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/issue-54044.rs:3:1 | LL | #[cold] | ^^^^^^^ ... LL | struct Foo; - | ----------- not a function definition + | ----------- not a function | note: the lint level is defined here --> $DIR/issue-54044.rs:1:9 @@ -14,14 +14,14 @@ LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/issue-54044.rs:9:5 | LL | #[cold] | ^^^^^^^ ... LL | 5; - | - not a function definition + | - not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! diff --git a/src/test/ui/issues/issue-78957.stderr b/src/test/ui/issues/issue-78957.stderr index 45fa69d6fd708..fa2eaab5b417b 100644 --- a/src/test/ui/issues/issue-78957.stderr +++ b/src/test/ui/issues/issue-78957.stderr @@ -4,11 +4,11 @@ error[E0518]: attribute should be applied to function or closure LL | pub struct Foo<#[inline] const N: usize>; | ^^^^^^^^^ -------------- not a function or closure -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/issue-78957.rs:7:16 | LL | pub struct Bar<#[cold] const N: usize>; - | ^^^^^^^ -------------- not a function definition + | ^^^^^^^ -------------- not a function | note: the lint level is defined here --> $DIR/issue-78957.rs:1:9 @@ -29,11 +29,11 @@ error[E0518]: attribute should be applied to function or closure LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); | ^^^^^^^^^ -- not a function or closure -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/issue-78957.rs:15:17 | LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); - | ^^^^^^^ -- not a function definition + | ^^^^^^^ -- not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -49,11 +49,11 @@ error[E0518]: attribute should be applied to function or closure LL | pub struct Foo3<#[inline] T>(PhantomData); | ^^^^^^^^^ - not a function or closure -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/issue-78957.rs:23:17 | LL | pub struct Bar3<#[cold] T>(PhantomData); - | ^^^^^^^ - not a function definition + | ^^^^^^^ - not a function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! diff --git a/src/test/ui/macros/issue-68060.stderr b/src/test/ui/macros/issue-68060.stderr index b13e418e664a6..1b58cf9c4ede5 100644 --- a/src/test/ui/macros/issue-68060.stderr +++ b/src/test/ui/macros/issue-68060.stderr @@ -1,11 +1,11 @@ -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/issue-68060.rs:4:13 | LL | #[target_feature(enable = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | |_| (), - | ------ not a function definition + | ------ not a function error: aborting due to previous error diff --git a/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.rs b/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.rs index 0bf620934ec7b..66156b6e53bab 100644 --- a/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.rs +++ b/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.rs @@ -1,23 +1,23 @@ #![feature(marker_trait_attr)] -#[marker] //~ ERROR attribute should be applied to a trait +#[marker] //~ ERROR attribute can only be applied to a trait struct Struct {} -#[marker] //~ ERROR attribute should be applied to a trait +#[marker] //~ ERROR attribute can only be applied to a trait impl Struct {} -#[marker] //~ ERROR attribute should be applied to a trait +#[marker] //~ ERROR attribute can only be applied to a trait union Union { x: i32, } -#[marker] //~ ERROR attribute should be applied to a trait +#[marker] //~ ERROR attribute can only be applied to a trait const CONST: usize = 10; -#[marker] //~ ERROR attribute should be applied to a trait +#[marker] //~ ERROR attribute can only be applied to a trait fn function() {} -#[marker] //~ ERROR attribute should be applied to a trait +#[marker] //~ ERROR attribute can only be applied to a trait type Type = (); fn main() {} diff --git a/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.stderr b/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.stderr index 19a5290dd7eb6..d30b990caac2b 100644 --- a/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.stderr +++ b/src/test/ui/marker_trait_attr/marker-attribute-on-non-trait.stderr @@ -1,4 +1,4 @@ -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/marker-attribute-on-non-trait.rs:3:1 | LL | #[marker] @@ -6,7 +6,7 @@ LL | #[marker] LL | struct Struct {} | ---------------- not a trait -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/marker-attribute-on-non-trait.rs:6:1 | LL | #[marker] @@ -14,7 +14,7 @@ LL | #[marker] LL | impl Struct {} | -------------- not a trait -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/marker-attribute-on-non-trait.rs:9:1 | LL | #[marker] @@ -24,7 +24,7 @@ LL | | x: i32, LL | | } | |_- not a trait -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/marker-attribute-on-non-trait.rs:14:1 | LL | #[marker] @@ -32,7 +32,7 @@ LL | #[marker] LL | const CONST: usize = 10; | ------------------------ not a trait -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/marker-attribute-on-non-trait.rs:17:1 | LL | #[marker] @@ -40,7 +40,7 @@ LL | #[marker] LL | fn function() {} | ---------------- not a trait -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/marker-attribute-on-non-trait.rs:20:1 | LL | #[marker] diff --git a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs index 143f9a3009b61..3c4a09fafd2db 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs @@ -3,11 +3,11 @@ struct Foo; #[non_exhaustive] -//~^ ERROR attribute should be applied to a struct or enum [E0701] +//~^ ERROR attribute can only be applied to a struct or enum [E0701] trait Bar { } #[non_exhaustive] -//~^ ERROR attribute should be applied to a struct or enum [E0701] +//~^ ERROR attribute can only be applied to a struct or enum [E0701] union Baz { f1: u16, f2: u16 diff --git a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr index 136cd763b05c1..76d9e2d8205b7 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr @@ -4,7 +4,7 @@ error: malformed `non_exhaustive` attribute input LL | #[non_exhaustive(anything)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` -error[E0701]: attribute should be applied to a struct or enum +error[E0701]: attribute can only be applied to a struct or enum --> $DIR/invalid-attribute.rs:5:1 | LL | #[non_exhaustive] @@ -13,7 +13,7 @@ LL | LL | trait Bar { } | ------------- not a struct or enum -error[E0701]: attribute should be applied to a struct or enum +error[E0701]: attribute can only be applied to a struct or enum --> $DIR/invalid-attribute.rs:9:1 | LL | #[non_exhaustive] diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.rs b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs index 2d2b01b6f947a..bc0ca9552806f 100644 --- a/src/test/ui/rfc-2091-track-caller/only-for-fns.rs +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs @@ -1,5 +1,5 @@ #[track_caller] struct S; -//~^^ ERROR attribute should be applied to a function definition +//~^^ ERROR attribute should be applied to function fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr index b36597bded941..6666dcfa6e599 100644 --- a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr @@ -1,10 +1,10 @@ -error[E0739]: attribute should be applied to a function definition +error[E0739]: attribute should be applied to function --> $DIR/only-for-fns.rs:1:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ LL | struct S; - | --------- not a function definition + | --------- not a function error: aborting due to previous error diff --git a/src/test/ui/rustdoc/doc_keyword.rs b/src/test/ui/rustdoc/doc_keyword.rs index 68a8802b2f645..43b84e5018cda 100644 --- a/src/test/ui/rustdoc/doc_keyword.rs +++ b/src/test/ui/rustdoc/doc_keyword.rs @@ -15,6 +15,6 @@ fn foo() {} // Regression test for the ICE described in #83512. trait Foo { #[doc(keyword = "match")] - //~^ ERROR: `#[doc(keyword = "...")]` should be used on modules + //~^ ERROR: `#[doc(keyword = "...")]` can only be used on modules fn quux() {} } diff --git a/src/test/ui/rustdoc/doc_keyword.stderr b/src/test/ui/rustdoc/doc_keyword.stderr index a1d0e4ffc0938..6ba7034d54122 100644 --- a/src/test/ui/rustdoc/doc_keyword.stderr +++ b/src/test/ui/rustdoc/doc_keyword.stderr @@ -1,16 +1,16 @@ -error: `#[doc(keyword = "...")]` should be used on empty modules +error: `#[doc(keyword = "...")]` can only be used on empty modules --> $DIR/doc_keyword.rs:6:7 | LL | #[doc(keyword = "hell")] | ^^^^^^^^^^^^^^^^ -error: `#[doc(keyword = "...")]` should be used on modules +error: `#[doc(keyword = "...")]` can only be used on modules --> $DIR/doc_keyword.rs:11:7 | LL | #[doc(keyword = "hall")] | ^^^^^^^^^^^^^^^^ -error: `#[doc(keyword = "...")]` should be used on modules +error: `#[doc(keyword = "...")]` can only be used on modules --> $DIR/doc_keyword.rs:17:11 | LL | #[doc(keyword = "match")] diff --git a/src/test/ui/target-feature/invalid-attribute.stderr b/src/test/ui/target-feature/invalid-attribute.stderr index 889ced9752bd4..25a2c1975e7b2 100644 --- a/src/test/ui/target-feature/invalid-attribute.stderr +++ b/src/test/ui/target-feature/invalid-attribute.stderr @@ -34,43 +34,43 @@ LL | fn bar() {} = note: see issue #69098 for more information = help: add `#![feature(target_feature_11)]` to the crate attributes to enable -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:34:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | mod another {} - | -------------- not a function definition + | -------------- not a function -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:39:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | const FOO: usize = 7; - | --------------------- not a function definition + | --------------------- not a function -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:44:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | struct Foo; - | ----------- not a function definition + | ----------- not a function -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:49:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | enum Bar {} - | ----------- not a function definition + | ----------- not a function -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:54:1 | LL | #[target_feature(enable = "sse2")] @@ -81,16 +81,16 @@ LL | | LL | | f1: u16, LL | | f2: u16, LL | | } - | |_- not a function definition + | |_- not a function -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:62:1 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | trait Baz {} - | ------------ not a function definition + | ------------ not a function error: cannot use `#[inline(always)]` with `#[target_feature]` --> $DIR/invalid-attribute.rs:67:1 @@ -98,7 +98,7 @@ error: cannot use `#[inline(always)]` with `#[target_feature]` LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:85:5 | LL | #[target_feature(enable = "sse2")] @@ -108,16 +108,16 @@ LL | / unsafe { LL | | foo(); LL | | bar(); LL | | } - | |_____- not a function definition + | |_____- not a function -error: attribute should be applied to a function definition +error: attribute should be applied to a function --> $DIR/invalid-attribute.rs:93:5 | LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | || {}; - | ----- not a function definition + | ----- not a function error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions --> $DIR/invalid-attribute.rs:77:5 diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs index 1f896da94db57..d9de6d5edb9b4 100644 --- a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs +++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs @@ -36,11 +36,11 @@ trait Tr5 { } #[rustc_must_implement_one_of(abc, xyz)] -//~^ attribute should be applied to a trait +//~^ attribute can only be applied to a trait fn function() {} #[rustc_must_implement_one_of(abc, xyz)] -//~^ attribute should be applied to a trait +//~^ attribute can only be applied to a trait struct Struct {} fn main() {} diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index 869184f0d1a69..bc28dc2c4f40d 100644 --- a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -4,7 +4,7 @@ error: malformed `rustc_must_implement_one_of` attribute input LL | #[rustc_must_implement_one_of] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/rustc_must_implement_one_of_misuse.rs:38:1 | LL | #[rustc_must_implement_one_of(abc, xyz)] @@ -13,7 +13,7 @@ LL | LL | fn function() {} | ---------------- not a trait -error: attribute should be applied to a trait +error: attribute can only be applied to a trait --> $DIR/rustc_must_implement_one_of_misuse.rs:42:1 | LL | #[rustc_must_implement_one_of(abc, xyz)]