Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5d0388e

Browse files
require trait impls to have matching const stabilities as the traits
1 parent 550e035 commit 5d0388e

File tree

8 files changed

+201
-17
lines changed

8 files changed

+201
-17
lines changed

‎compiler/rustc_const_eval/src/check_consts/mod.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ pub fn rustc_allow_const_fn_unstable(
9292
/// world into two functions: those that are safe to expose on stable (and hence may not use
9393
/// unstable features, not even recursively), and those that are not.
9494
pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
95+
// A default body in a `#[const_trait]` is const-stable when the trait is const-stable.
96+
if tcx.is_const_default_method(def_id) {
97+
return is_fn_or_trait_safe_to_expose_on_stable(tcx, tcx.parent(def_id));
98+
}
99+
95100
match tcx.lookup_const_stability(def_id) {
96101
None => {
97102
// In a `staged_api` crate, we do enforce recursive const stability for all unmarked

‎compiler/rustc_passes/messages.ftl‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,13 @@ passes_target_feature_on_statement =
732732
.warn = {-passes_previously_accepted}
733733
.label = {passes_should_be_applied_to_fn.label}
734734
735+
passes_trait_impl_const_stability_mismatch = const stability on the impl does not match the const stability on the trait
736+
passes_trait_impl_const_stability_mismatch_impl_stable = this impl is (implicitly) stable...
737+
passes_trait_impl_const_stability_mismatch_impl_unstable = this impl is unstable...
738+
passes_trait_impl_const_stability_mismatch_trait_stable = ...but the trait is stable
739+
passes_trait_impl_const_stability_mismatch_trait_unstable = ...but the trait is unstable
740+
741+
735742
passes_trait_impl_const_stable =
736743
trait implementations cannot be const stable yet
737744
.note = see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information

‎compiler/rustc_passes/src/errors.rs‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,45 @@ pub(crate) struct TraitImplConstStable {
15881588
pub span: Span,
15891589
}
15901590

1591+
#[derive(Diagnostic)]
1592+
#[diag(passes_trait_impl_const_stability_mismatch)]
1593+
pub(crate) struct TraitImplConstStabilityMismatch {
1594+
#[primary_span]
1595+
pub span: Span,
1596+
#[subdiagnostic]
1597+
pub impl_stability: ImplConstStability,
1598+
#[subdiagnostic]
1599+
pub trait_stability: TraitConstStability,
1600+
}
1601+
1602+
#[derive(Subdiagnostic)]
1603+
pub(crate) enum TraitConstStability {
1604+
#[note(passes_trait_impl_const_stability_mismatch_trait_stable)]
1605+
Stable {
1606+
#[primary_span]
1607+
span: Span,
1608+
},
1609+
#[note(passes_trait_impl_const_stability_mismatch_trait_unstable)]
1610+
Unstable {
1611+
#[primary_span]
1612+
span: Span,
1613+
},
1614+
}
1615+
1616+
#[derive(Subdiagnostic)]
1617+
pub(crate) enum ImplConstStability {
1618+
#[note(passes_trait_impl_const_stability_mismatch_impl_stable)]
1619+
Stable {
1620+
#[primary_span]
1621+
span: Span,
1622+
},
1623+
#[note(passes_trait_impl_const_stability_mismatch_impl_unstable)]
1624+
Unstable {
1625+
#[primary_span]
1626+
span: Span,
1627+
},
1628+
}
1629+
15911630
#[derive(Diagnostic)]
15921631
#[diag(passes_unknown_feature, code = E0635)]
15931632
pub(crate) struct UnknownFeature {

‎compiler/rustc_passes/src/stability.rs‎

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
301301
let mut const_stab = const_stab.map(|(stab, _span)| stab);
302302

303303
// If this is a const fn but not annotated with stability markers, see if we can inherit regular stability.
304-
if fn_sig.is_some_and(|s| s.header.is_const()) && const_stab.is_none() &&
304+
if fn_sig.is_some_and(|s| s.header.is_const()) && const_stab.is_none() &&
305305
// We only ever inherit unstable features.
306306
let Some(inherit_regular_stab) =
307307
final_stab.filter(|s| s.is_unstable())
@@ -816,24 +816,54 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
816816
}
817817
}
818818

819-
// `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
820-
// needs to have an error emitted.
821-
if features.const_trait_impl()
822-
&& self.tcx.is_const_trait_impl(item.owner_id.to_def_id())
823-
&& const_stab.is_some_and(|(stab, _)| stab.is_const_stable())
824-
{
825-
self.tcx.dcx().emit_err(errors::TraitImplConstStable { span: item.span });
819+
if features.const_trait_impl() && hir::Constness::Const == *constness {
820+
let stable_or_implied_stable = match const_stab {
821+
None => true,
822+
Some((stab, _)) if stab.is_const_stable() => {
823+
// `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
824+
// needs to have an error emitted.
825+
// Note: Remove this error once `const_trait_impl` is stabilized
826+
self.tcx
827+
.dcx()
828+
.emit_err(errors::TraitImplConstStable { span: item.span });
829+
true
830+
}
831+
Some(_) => false,
832+
};
833+
834+
if let Some(trait_id) = t.trait_def_id()
835+
&& let Some(const_stab) = self.tcx.lookup_const_stability(trait_id)
836+
{
837+
// the const stability of a trait impl must match the const stability on the trait.
838+
if const_stab.is_const_stable() != stable_or_implied_stable {
839+
let trait_span = self.tcx.def_ident_span(trait_id).unwrap();
840+
841+
let impl_stability = if stable_or_implied_stable {
842+
errors::ImplConstStability::Stable { span: item.span }
843+
} else {
844+
errors::ImplConstStability::Unstable { span: item.span }
845+
};
846+
let trait_stability = if const_stab.is_const_stable() {
847+
errors::TraitConstStability::Stable { span: trait_span }
848+
} else {
849+
errors::TraitConstStability::Unstable { span: trait_span }
850+
};
851+
852+
self.tcx.dcx().emit_err(errors::TraitImplConstStabilityMismatch {
853+
span: item.span,
854+
impl_stability,
855+
trait_stability,
856+
});
857+
}
858+
}
826859
}
827860
}
828861

829-
match constness {
830-
rustc_hir::Constness::Const => {
831-
if let Some(def_id) = t.trait_def_id() {
832-
// FIXME(const_trait_impl): Improve the span here.
833-
self.tcx.check_const_stability(def_id, t.path.span, t.path.span);
834-
}
835-
}
836-
rustc_hir::Constness::NotConst => {}
862+
if let hir::Constness::Const = constness
863+
&& let Some(def_id) = t.trait_def_id()
864+
{
865+
// FIXME(const_trait_impl): Improve the span here.
866+
self.tcx.check_const_stability(def_id, t.path.span, t.path.span);
837867
}
838868

839869
for impl_item_ref in *items {

‎library/core/src/ops/arith.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub trait Add<Rhs = Self> {
9696
macro_rules! add_impl {
9797
($($t:ty)*) => ($(
9898
#[stable(feature = "rust1", since = "1.0.0")]
99+
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
99100
impl const Add for $t {
100101
type Output = $t;
101102

‎library/core/src/ops/deref.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub trait Deref {
150150
}
151151

152152
#[stable(feature = "rust1", since = "1.0.0")]
153+
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
153154
impl<T: ?Sized> const Deref for &T {
154155
type Target = T;
155156

@@ -163,6 +164,7 @@ impl<T: ?Sized> const Deref for &T {
163164
impl<T: ?Sized> !DerefMut for &T {}
164165

165166
#[stable(feature = "rust1", since = "1.0.0")]
167+
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
166168
impl<T: ?Sized> const Deref for &mut T {
167169
type Target = T;
168170

@@ -273,6 +275,7 @@ pub trait DerefMut: ~const Deref {
273275
}
274276

275277
#[stable(feature = "rust1", since = "1.0.0")]
278+
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
276279
impl<T: ?Sized> const DerefMut for &mut T {
277280
fn deref_mut(&mut self) -> &mut T {
278281
*self

‎tests/ui/traits/const-traits/staged-api.rs‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,36 @@ const fn implicitly_stable_const_context() {
8585
//~^ ERROR cannot use `#[feature(const_trait_impl)]`
8686
}
8787

88+
// check that const stability of impls and traits must match
89+
#[const_trait]
90+
#[rustc_const_unstable(feature = "beef", issue = "none")]
91+
trait U {}
92+
93+
#[const_trait]
94+
#[rustc_const_stable(since = "0.0.0", feature = "beef2")]
95+
trait S {}
96+
97+
// implied stable
98+
impl const U for u8 {}
99+
//~^ const stability on the impl does not match the const stability on the trait
100+
101+
#[rustc_const_stable(since = "0.0.0", feature = "beef2")]
102+
impl const U for u16 {}
103+
//~^ const stability on the impl does not match the const stability on the trait
104+
//~| trait implementations cannot be const stable yet
105+
106+
#[rustc_const_unstable(feature = "beef", issue = "none")]
107+
impl const U for u32 {}
108+
109+
// implied stable
110+
impl const S for u8 {}
111+
112+
#[rustc_const_stable(since = "0.0.0", feature = "beef2")]
113+
impl const S for u16 {}
114+
//~^ trait implementations cannot be const stable yet
115+
116+
#[rustc_const_unstable(feature = "beef", issue = "none")]
117+
impl const S for u32 {}
118+
//~^ const stability on the impl does not match the const stability on the trait
119+
88120
fn main() {}

‎tests/ui/traits/const-traits/staged-api.stderr‎

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,70 @@
1+
error: const stability on the impl does not match the const stability on the trait
2+
--> $DIR/staged-api.rs:98:1
3+
|
4+
LL | impl const U for u8 {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: this impl is (implicitly) stable..
8+
--> $DIR/staged-api.rs:98:1
9+
|
10+
LL | impl const U for u8 {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^
12+
note: ..but the trait is unstable
13+
--> $DIR/staged-api.rs:91:7
14+
|
15+
LL | trait U {}
16+
| ^
17+
18+
error: trait implementations cannot be const stable yet
19+
--> $DIR/staged-api.rs:102:1
20+
|
21+
LL | impl const U for u16 {}
22+
| ^^^^^^^^^^^^^^^^^^^^^^^
23+
|
24+
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
25+
26+
error: const stability on the impl does not match the const stability on the trait
27+
--> $DIR/staged-api.rs:102:1
28+
|
29+
LL | impl const U for u16 {}
30+
| ^^^^^^^^^^^^^^^^^^^^^^^
31+
|
32+
note: this impl is (implicitly) stable..
33+
--> $DIR/staged-api.rs:102:1
34+
|
35+
LL | impl const U for u16 {}
36+
| ^^^^^^^^^^^^^^^^^^^^^^^
37+
note: ..but the trait is unstable
38+
--> $DIR/staged-api.rs:91:7
39+
|
40+
LL | trait U {}
41+
| ^
42+
43+
error: trait implementations cannot be const stable yet
44+
--> $DIR/staged-api.rs:113:1
45+
|
46+
LL | impl const S for u16 {}
47+
| ^^^^^^^^^^^^^^^^^^^^^^^
48+
|
49+
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
50+
51+
error: const stability on the impl does not match the const stability on the trait
52+
--> $DIR/staged-api.rs:117:1
53+
|
54+
LL | impl const S for u32 {}
55+
| ^^^^^^^^^^^^^^^^^^^^^^^
56+
|
57+
note: this impl is unstable..
58+
--> $DIR/staged-api.rs:117:1
59+
|
60+
LL | impl const S for u32 {}
61+
| ^^^^^^^^^^^^^^^^^^^^^^^
62+
note: ..but the trait is stable
63+
--> $DIR/staged-api.rs:95:7
64+
|
65+
LL | trait S {}
66+
| ^
67+
168
error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
269
--> $DIR/staged-api.rs:38:5
370
|
@@ -323,5 +390,5 @@ LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
323390
LL | const fn implicitly_stable_const_context() {
324391
|
325392

326-
error: aborting due to 19 previous errors
393+
error: aborting due to 24 previous errors
327394

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /