Skip to content

Commit 6a45f4d

Browse files
committed
Move check to existing pass
This alters the diagnostics a bit, as the trait method is still stable. The only thing this check does is ensure that compilation fails if a trait implementation is declared const-stable.
1 parent 69b71de commit 6a45f4d

File tree

7 files changed

+62
-158
lines changed

7 files changed

+62
-158
lines changed

compiler/rustc_interface/src/passes.rs

-4
Original file line numberDiff line numberDiff line change
@@ -982,10 +982,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
982982

983983
sess.time("layout_testing", || layout_test::test_layout(tcx));
984984

985-
sess.time("stable_impl_const_trait_checking", || {
986-
rustc_passes::stability::check_const_impl_trait(tcx)
987-
});
988-
989985
// Avoid overwhelming user with errors if borrow checking failed.
990986
// I'm not sure how helpful this is, to be honest, but it avoids a
991987
// lot of annoying errors in the ui tests (basically,

compiler/rustc_passes/src/stability.rs

+26-56
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc_hir::def::{DefKind, Res};
99
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX};
1010
use rustc_hir::hir_id::CRATE_HIR_ID;
1111
use rustc_hir::intravisit::{self, Visitor};
12-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
1312
use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
1413
use rustc_middle::hir::nested_filter;
1514
use rustc_middle::middle::privacy::AccessLevels;
@@ -606,44 +605,6 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
606605
// stable (assuming they have not inherited instability from their parent).
607606
}
608607

609-
struct CheckStableConstImplTrait<'tcx> {
610-
tcx: TyCtxt<'tcx>,
611-
}
612-
613-
impl<'tcx> ItemLikeVisitor<'tcx> for CheckStableConstImplTrait<'tcx> {
614-
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
615-
if !matches!(
616-
item.kind,
617-
hir::ItemKind::Impl(hir::Impl {
618-
of_trait: Some(_),
619-
constness: hir::Constness::Const,
620-
..
621-
})
622-
) {
623-
return;
624-
}
625-
626-
if self.tcx.lookup_const_stability(item.def_id).map_or(false, |stab| stab.is_const_stable())
627-
{
628-
self.tcx
629-
.sess
630-
.struct_span_err(item.span, "trait implementations cannot be const stable yet")
631-
.note("see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information")
632-
.emit();
633-
}
634-
}
635-
636-
fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem<'tcx>) {
637-
// Nothing to do here.
638-
}
639-
fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem<'tcx>) {
640-
// Nothing to do here.
641-
}
642-
fn visit_foreign_item(&mut self, _foreign_item: &'tcx hir::ForeignItem<'tcx>) {
643-
// Nothing to do here.
644-
}
645-
}
646-
647608
fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
648609
let mut index = Index {
649610
stab_map: Default::default(),
@@ -748,16 +709,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
748709
// For implementations of traits, check the stability of each item
749710
// individually as it's possible to have a stable trait with unstable
750711
// items.
751-
hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
752-
if self.tcx.features().staged_api {
712+
hir::ItemKind::Impl(hir::Impl {
713+
of_trait: Some(ref t),
714+
self_ty,
715+
items,
716+
constness,
717+
..
718+
}) => {
719+
let features = self.tcx.features();
720+
if features.staged_api {
721+
let attrs = self.tcx.hir().attrs(item.hir_id());
722+
let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item.span);
723+
753724
// If this impl block has an #[unstable] attribute, give an
754725
// error if all involved types and traits are stable, because
755726
// it will have no effect.
756727
// See: https://github.com/rust-lang/rust/issues/55436
757-
let attrs = self.tcx.hir().attrs(item.hir_id());
758-
if let (Some((Stability { level: attr::Unstable { .. }, .. }, span)), _) =
759-
attr::find_stability(&self.tcx.sess, attrs, item.span)
760-
{
728+
if let Some((Stability { level: attr::Unstable { .. }, .. }, span)) = stab {
761729
let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
762730
c.visit_ty(self_ty);
763731
c.visit_trait_ref(t);
@@ -773,6 +741,19 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
773741
);
774742
}
775743
}
744+
745+
// `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
746+
// needs to have an error emitted.
747+
if features.const_trait_impl
748+
&& constness == hir::Constness::Const
749+
&& const_stab.map_or(false, |(stab, _)| stab.is_const_stable())
750+
{
751+
self.tcx
752+
.sess
753+
.struct_span_err(item.span, "trait implementations cannot be const stable yet")
754+
.note("see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information")
755+
.emit();
756+
}
776757
}
777758

778759
for impl_item_ref in items {
@@ -864,17 +845,6 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
864845
}
865846
}
866847

867-
pub fn check_const_impl_trait(tcx: TyCtxt<'_>) {
868-
let features = tcx.features(); // FIXME How cheap is this call?
869-
// Both feature gates have to be enabled for this check to have any effect.
870-
if !features.staged_api || !features.const_trait_impl {
871-
return;
872-
}
873-
874-
let mut visitor = CheckStableConstImplTrait { tcx };
875-
tcx.hir().visit_all_item_likes(&mut visitor);
876-
}
877-
878848
/// Given the list of enabled features that were not language features (i.e., that
879849
/// were expected to be library features), and the list of features used from
880850
/// libraries, identify activated features that don't exist and error about them.

src/test/ui/rfc-2632-const-trait-impl/stability.rs

-43
This file was deleted.

src/test/ui/rfc-2632-const-trait-impl/stability.stderr

-24
This file was deleted.

src/test/ui/rfc-2632-const-trait-impl/staged-api.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,36 @@ extern crate staged_api;
1111
use staged_api::*;
1212

1313
#[stable(feature = "rust1", since = "1.0.0")]
14-
pub struct Stable;
14+
pub struct Foo;
1515

1616
#[stable(feature = "rust1", since = "1.0.0")]
17-
#[cfg_attr(stable, rustc_const_stable(feature = "rust1", since = "1.0.0"))]
18-
impl const MyTrait for Stable {
17+
#[cfg_attr(unstable, rustc_const_unstable(feature = "foo", issue = "none"))]
18+
impl const MyTrait for Foo {
1919
//[stable]~^ ERROR trait implementations cannot be const stable yet
20-
//[unstable]~^^ ERROR implementation has missing const stability attribute
2120
fn func() {}
2221
}
2322

23+
// Const stability has no impact on usage in non-const contexts.
2424
fn non_const_context() {
2525
Unstable::func();
26-
Stable::func();
26+
Foo::func();
2727
}
2828

2929
#[unstable(feature = "none", issue = "none")]
3030
const fn const_context() {
3131
Unstable::func();
32-
//[stable]~^ ERROR `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
33-
Stable::func();
32+
// ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is
33+
// not const-stable.
34+
Foo::func();
35+
//[unstable]~^ not yet stable as a const fn
36+
}
37+
38+
#[stable(feature = "rust1", since = "1.0.0")]
39+
const fn stable_const_context() {
40+
Unstable::func();
41+
//[unstable]~^ ERROR not yet stable as a const fn
42+
Foo::func();
43+
//[unstable]~^ ERROR not yet stable as a const fn
3444
}
3545

3646
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
2-
--> $DIR/staged-api.rs:31:5
3-
|
4-
LL | Unstable::func();
5-
| ^^^^^^^^^^^^^^^^
6-
|
7-
= help: add `#![feature(unstable)]` to the crate attributes to enable
8-
9-
error: trait implementations cannot be const stable yet
1+
error: implementation has missing const stability attribute
102
--> $DIR/staged-api.rs:18:1
113
|
12-
LL | / impl const MyTrait for Stable {
13-
LL | |
4+
LL | / impl const MyTrait for Foo {
145
LL | |
156
LL | | fn func() {}
167
LL | | }
178
| |_^
18-
|
19-
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
209

21-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
2211

Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
error: implementation has missing const stability attribute
2-
--> $DIR/staged-api.rs:18:1
3-
|
4-
LL | / impl const MyTrait for Stable {
5-
LL | |
6-
LL | |
7-
LL | | fn func() {}
8-
LL | | }
9-
| |_^
1+
error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
2+
--> $DIR/staged-api.rs:34:5
3+
|
4+
LL | Foo::func();
5+
| ^^^^^^^^^^^
6+
|
7+
= help: add `#![feature(foo)]` to the crate attributes to enable
8+
9+
error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
10+
--> $DIR/staged-api.rs:42:5
11+
|
12+
LL | Foo::func();
13+
| ^^^^^^^^^^^
14+
|
15+
= help: add `#![feature(foo)]` to the crate attributes to enable
1016

11-
error: aborting due to previous error
17+
error: aborting due to 2 previous errors
1218

0 commit comments

Comments
 (0)