Skip to content

Commit 89fb34f

Browse files
committed
Turn unstable trait impl error into a lint, so it can be disabled.
1 parent cf8e5d1 commit 89fb34f

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

compiler/rustc_passes/src/stability.rs

+28-21
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_middle::middle::stability::{DeprecationEntry, Index};
1616
use rustc_middle::ty::query::Providers;
1717
use rustc_middle::ty::TyCtxt;
1818
use rustc_session::lint;
19+
use rustc_session::lint::builtin::INEFFECTIVE_UNSTABLE_TRAIT_IMPL;
1920
use rustc_session::parse::feature_err;
2021
use rustc_session::Session;
2122
use rustc_span::symbol::{sym, Symbol};
@@ -539,27 +540,33 @@ impl Visitor<'tcx> for Checker<'tcx> {
539540
// individually as it's possible to have a stable trait with unstable
540541
// items.
541542
hir::ItemKind::Impl { of_trait: Some(ref t), self_ty, items, .. } => {
542-
// If this impl block has an #[unstable] attribute, give an
543-
// error if all involved types and traits are stable, because
544-
// it will have no effect.
545-
// See: https://github.com/rust-lang/rust/issues/55436
546-
if let (Some(Stability { level: attr::Unstable { .. }, .. }), _) =
547-
attr::find_stability(&self.tcx.sess, &item.attrs, item.span)
548-
{
549-
let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
550-
c.visit_ty(self_ty);
551-
c.visit_trait_ref(t);
552-
if c.fully_stable {
553-
let span = item
554-
.attrs
555-
.iter()
556-
.find(|a| a.has_name(sym::unstable))
557-
.map_or(item.span, |a| a.span);
558-
self.tcx.sess.span_err(
559-
span,
560-
"An `#[unstable]` annotation here has no effect. \
561-
See issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information.",
562-
);
543+
if self.tcx.features().staged_api {
544+
// If this impl block has an #[unstable] attribute, give an
545+
// error if all involved types and traits are stable, because
546+
// it will have no effect.
547+
// See: https://github.com/rust-lang/rust/issues/55436
548+
if let (Some(Stability { level: attr::Unstable { .. }, .. }), _) =
549+
attr::find_stability(&self.tcx.sess, &item.attrs, item.span)
550+
{
551+
let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
552+
c.visit_ty(self_ty);
553+
c.visit_trait_ref(t);
554+
if c.fully_stable {
555+
let span = item
556+
.attrs
557+
.iter()
558+
.find(|a| a.has_name(sym::unstable))
559+
.map_or(item.span, |a| a.span);
560+
self.tcx.struct_span_lint_hir(
561+
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
562+
item.hir_id,
563+
span,
564+
|lint| lint.build(
565+
"An `#[unstable]` annotation here has no effect. \
566+
See issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information.",
567+
).emit()
568+
);
569+
}
563570
}
564571
}
565572

compiler/rustc_session/src/lint/builtin.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! lints are all available in `rustc_lint::builtin`.
66
77
use crate::lint::FutureIncompatibleInfo;
8-
use crate::{declare_lint, declare_lint_pass};
8+
use crate::{declare_lint, declare_lint_pass, declare_tool_lint};
99
use rustc_span::edition::Edition;
1010
use rustc_span::symbol::sym;
1111

@@ -555,6 +555,12 @@ declare_lint! {
555555
};
556556
}
557557

558+
declare_tool_lint! {
559+
pub rustc::INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
560+
Deny,
561+
"detects `#[unstable]` on stable trait implementations for stable types"
562+
}
563+
558564
declare_lint_pass! {
559565
/// Does nothing as a lint pass, but registers some `Lint`s
560566
/// that are used by other parts of the compiler.
@@ -630,6 +636,7 @@ declare_lint_pass! {
630636
INCOMPLETE_INCLUDE,
631637
CENUM_IMPL_DROP_CAST,
632638
CONST_EVALUATABLE_UNCHECKED,
639+
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
633640
]
634641
}
635642

0 commit comments

Comments
 (0)