diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/active.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 |
5 files changed, 58 insertions, 3 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index b0dbc2c2340..c0d2e76f310 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -218,6 +218,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } } + if !attr.is_doc_comment() + && attr.get_normal_item().path.segments.len() == 2 + && attr.get_normal_item().path.segments[0].ident.name == sym::diagnostic + && !self.features.diagnostic_namespace + { + let msg = "`#[diagnostic]` attribute name space is experimental"; + gate_feature_post!( + self, + diagnostic_namespace, + attr.get_normal_item().path.segments[0].ident.span, + msg + ); + } // Emit errors for non-staged-api crates. if !self.features.staged_api { diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 56a2c5eff3d..c03789f500a 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -379,6 +379,8 @@ declare_features! ( (active, deprecated_safe, "1.61.0", Some(94978), None), /// Allows having using `suggestion` in the `#[deprecated]` attribute. (active, deprecated_suggestion, "1.61.0", Some(94785), None), + /// Allows using the `#[diagnostic]` attribute tool namespace + (active, diagnostic_namespace, "CURRENT_RUSTC_VERSION", Some(94785), None), /// Controls errors in trait implementations. (active, do_not_recommend, "1.67.0", Some(51992), None), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a0f2e9aed81..cfb40a3b65c 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3400,6 +3400,7 @@ declare_lint_pass! { UNFULFILLED_LINT_EXPECTATIONS, UNINHABITED_STATIC, UNKNOWN_CRATE_TYPES, + UNKNOWN_DIAGNOSTIC_ATTRIBUTES, UNKNOWN_LINTS, UNNAMEABLE_TYPES, UNREACHABLE_CODE, @@ -4380,3 +4381,27 @@ declare_lint! { "effective visibility of a type is larger than the area in which it can be named", @feature_gate = sym::type_privacy_lints; } + +declare_lint! { + /// The `unknown_diagnostic_attributes` lint detects unrecognized diagnostic attributes. + /// + /// ### Example + /// + /// ```rust + /// #![feature(diagnostic_namespace)] + /// #[diagnostic::does_not_exist] + /// struct Foo; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// It is usually a mistake to specify a diagnostic attribute that does not exist. Check + /// the spelling, and check the diagnostic attribute listing for the correct name. Also + /// consider if you are using an old version of the compiler, and the attribute + /// is only available in a newer version. + pub UNKNOWN_DIAGNOSTIC_ATTRIBUTES, + Warn, + "unrecognized diagnostic attribute" +} diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 266e37e4cef..d456cc9a9a0 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -24,7 +24,9 @@ use rustc_hir::def_id::{CrateNum, LocalDefId}; use rustc_middle::middle::stability; use rustc_middle::ty::RegisteredTools; use rustc_middle::ty::TyCtxt; -use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE}; +use rustc_session::lint::builtin::{ + LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNKNOWN_DIAGNOSTIC_ATTRIBUTES, +}; use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES}; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::parse::feature_err; @@ -140,9 +142,9 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { } } } - // We implicitly add `rustfmt` and `clippy` to known tools, + // We implicitly add `rustfmt`, `clippy`, `diagnostic` to known tools, // but it's not an error to register them explicitly. - let predefined_tools = [sym::clippy, sym::rustfmt]; + let predefined_tools = [sym::clippy, sym::rustfmt, sym::diagnostic]; registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span)); registered_tools } @@ -595,6 +597,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } + if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) + && path.segments.len() >= 2 + && path.segments[0].ident.name == sym::diagnostic + { + self.tcx.sess.parse_sess.buffer_lint( + UNKNOWN_DIAGNOSTIC_ATTRIBUTES, + path.segments[1].span(), + node_id, + "unknown diagnostic attribute", + ); + } + Ok((ext, res)) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 54eb7bef5f2..1b426ef2048 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -620,6 +620,7 @@ symbols! { destruct, destructuring_assignment, diagnostic, + diagnostic_namespace, direct, discriminant_kind, discriminant_type, |
