diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index f8ff46189c052..ab89af2267934 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -87,6 +87,10 @@ passes_deprecated_annotation_has_no_effect = passes_deprecated_attribute = deprecated attribute must be paired with either stable or unstable attribute +passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls = + `#[diagnostic::on_const]` can only be applied to non-const trait impls + .label = this is a const trait impl + passes_diagnostic_diagnostic_on_const_only_for_trait_impls = `#[diagnostic::on_const]` can only be applied to trait impls .label = not a trait impl diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8cf68b280850e..552985003fb55 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -67,6 +67,13 @@ struct DiagnosticOnConstOnlyForTraitImpls { item_span: Span, } +#[derive(LintDiagnostic)] +#[diag(passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls)] +struct DiagnosticOnConstOnlyForNonConstTraitImpls { + #[label] + item_span: Span, +} + fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { match impl_item.kind { hir::ImplItemKind::Const(..) => Target::AssocConst, @@ -629,7 +636,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if target == (Target::Impl { of_trait: true }) { match item.unwrap() { ItemLike::Item(it) => match it.expect_impl().constness { - Constness::Const => {} + Constness::Const => { + let item_span = self.tcx.hir_span(hir_id); + self.tcx.emit_node_span_lint( + MISPLACED_DIAGNOSTIC_ATTRIBUTES, + hir_id, + attr_span, + DiagnosticOnConstOnlyForNonConstTraitImpls { item_span }, + ); + return; + } Constness::NotConst => return, }, ItemLike::ForeignItem => {} diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs index c0af549e2d012..f7babae3aa7c4 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs @@ -6,7 +6,7 @@ pub struct Foo; #[diagnostic::on_const(message = "tadaa", note = "boing")] -//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls +//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait impls impl const PartialEq for Foo { fn eq(&self, _other: &Foo) -> bool { true diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr index baa0b11f798b9..f92ea501696e5 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr @@ -13,14 +13,14 @@ note: the lint level is defined here LL | #![deny(misplaced_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[diagnostic::on_const]` can only be applied to trait impls +error: `#[diagnostic::on_const]` can only be applied to non-const trait impls --> $DIR/misplaced_attr.rs:8:1 | LL | #[diagnostic::on_const(message = "tadaa", note = "boing")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | impl const PartialEq for Foo { - | ---------------------------- not a trait impl + | ---------------------------- this is a const trait impl error: `#[diagnostic::on_const]` can only be applied to trait impls --> $DIR/misplaced_attr.rs:16:1