1
Fork 0

lint: avoid linting diag functions with diag lints

Functions annotated with `#[rustc_lint_diagnostics]` are used by the
diagnostic migration lints to know when to lint, but functions that are
annotated with this attribute shouldn't themselves be linted.

Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
David Wood 2022-08-31 12:06:22 +01:00
parent 7f442f8ba1
commit 11fc7852fe
3 changed files with 24 additions and 10 deletions

View file

@ -393,8 +393,14 @@ impl LateLintPass<'_> for Diagnostics {
return; return;
} }
let mut found_parent_with_attr = false;
let mut found_impl = false; let mut found_impl = false;
for (_, parent) in cx.tcx.hir().parent_iter(expr.hir_id) { for (hir_id, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
if let Some(owner_did) = hir_id.as_owner() {
found_parent_with_attr = found_parent_with_attr
|| cx.tcx.has_attr(owner_did.to_def_id(), sym::rustc_lint_diagnostics);
}
debug!(?parent); debug!(?parent);
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent && if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent &&
let Impl { of_trait: Some(of_trait), .. } = impl_ && let Impl { of_trait: Some(of_trait), .. } = impl_ &&
@ -407,7 +413,7 @@ impl LateLintPass<'_> for Diagnostics {
} }
} }
debug!(?found_impl); debug!(?found_impl);
if !found_impl { if !found_parent_with_attr && !found_impl {
cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| { cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| {
lint.build(fluent::lint::diag_out_of_impl).emit(); lint.build(fluent::lint::diag_out_of_impl).emit();
}) })
@ -425,7 +431,7 @@ impl LateLintPass<'_> for Diagnostics {
} }
} }
debug!(?found_diagnostic_message); debug!(?found_diagnostic_message);
if !found_diagnostic_message { if !found_parent_with_attr && !found_diagnostic_message {
cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| { cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| {
lint.build(fluent::lint::untranslatable_diag).emit(); lint.build(fluent::lint::untranslatable_diag).emit();
}) })

View file

@ -1,6 +1,7 @@
// compile-flags: -Z unstable-options // compile-flags: -Z unstable-options
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(rustc_attrs)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)] #![deny(rustc::diagnostic_outside_of_impl)]
@ -71,3 +72,10 @@ pub fn make_diagnostics<'a>(sess: &'a ParseSess) {
//~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls //~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
//~^^ ERROR diagnostics should be created using translatable messages //~^^ ERROR diagnostics should be created using translatable messages
} }
// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted.
#[rustc_lint_diagnostics]
pub fn skipped_because_of_annotation<'a>(sess: &'a ParseSess) {
let _diag = sess.struct_err("untranslatable diagnostic"); // okay!
}

View file

@ -1,41 +1,41 @@
error: diagnostics should be created using translatable messages error: diagnostics should be created using translatable messages
--> $DIR/diagnostics.rs:36:14 --> $DIR/diagnostics.rs:37:14
| |
LL | sess.struct_err("untranslatable diagnostic") LL | sess.struct_err("untranslatable diagnostic")
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/diagnostics.rs:5:9 --> $DIR/diagnostics.rs:6:9
| |
LL | #![deny(rustc::untranslatable_diagnostic)] LL | #![deny(rustc::untranslatable_diagnostic)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: diagnostics should be created using translatable messages error: diagnostics should be created using translatable messages
--> $DIR/diagnostics.rs:53:14 --> $DIR/diagnostics.rs:54:14
| |
LL | diag.note("untranslatable diagnostic"); LL | diag.note("untranslatable diagnostic");
| ^^^^ | ^^^^
error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
--> $DIR/diagnostics.rs:67:22 --> $DIR/diagnostics.rs:68:22
| |
LL | let _diag = sess.struct_err(fluent::parser::expect_path); LL | let _diag = sess.struct_err(fluent::parser::expect_path);
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/diagnostics.rs:6:9 --> $DIR/diagnostics.rs:7:9
| |
LL | #![deny(rustc::diagnostic_outside_of_impl)] LL | #![deny(rustc::diagnostic_outside_of_impl)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
--> $DIR/diagnostics.rs:70:22 --> $DIR/diagnostics.rs:71:22
| |
LL | let _diag = sess.struct_err("untranslatable diagnostic"); LL | let _diag = sess.struct_err("untranslatable diagnostic");
| ^^^^^^^^^^ | ^^^^^^^^^^
error: diagnostics should be created using translatable messages error: diagnostics should be created using translatable messages
--> $DIR/diagnostics.rs:70:22 --> $DIR/diagnostics.rs:71:22
| |
LL | let _diag = sess.struct_err("untranslatable diagnostic"); LL | let _diag = sess.struct_err("untranslatable diagnostic");
| ^^^^^^^^^^ | ^^^^^^^^^^