diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 3d4bd222715c3..2704cb8d78538 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -101,6 +101,16 @@ pub struct Stability { pub feature: Symbol, } +impl Stability { + pub fn is_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_stable(&self) -> bool { + self.level.is_stable() + } +} + /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] @@ -111,6 +121,16 @@ pub struct ConstStability { pub promotable: bool, } +impl ConstStability { + pub fn is_const_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_const_stable(&self) -> bool { + self.level.is_stable() + } +} + /// The available stability levels. #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 777f4393458e2..d6f62062d1f8e 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -9,7 +9,7 @@ use rustc_span::symbol::Symbol; pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if tcx.is_const_fn_raw(def_id) { let const_stab = tcx.lookup_const_stability(def_id)?; - if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None } + if const_stab.is_const_unstable() { Some(const_stab.feature) } else { None } } else { None } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 1104bbf471682..2c669dd6d9a9b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -229,18 +229,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // The local type and predicate checks are not free and only relevant for `const fn`s. if self.const_kind() == hir::ConstContext::ConstFn { - // Prevent const trait methods from being annotated as `stable`. - // FIXME: Do this as part of stability checking. - if self.is_const_stable_const_fn() { - if crate::const_eval::is_parent_const_impl_raw(tcx, def_id) { - self.ccx - .tcx - .sess - .struct_span_err(self.span, "trait methods cannot be stable const fn") - .emit(); - } - } - for (idx, local) in body.local_decls.iter_enumerated() { // Handle the return place below. if idx == RETURN_PLACE || local.internal { @@ -944,7 +932,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // have no `rustc_const_stable` attributes to be const-unstable as well. This // should be fixed later. let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none() - && tcx.lookup_stability(callee).map_or(false, |s| s.level.is_unstable()); + && tcx.lookup_stability(callee).map_or(false, |s| s.is_unstable()); if callee_is_unstable_unmarked { trace!("callee_is_unstable_unmarked"); // We do not use `const` modifiers for intrinsic "functions", as intrinsics are diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 23e2afae79183..0f79fe5513dd8 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -84,8 +84,6 @@ pub fn rustc_allow_const_fn_unstable( // functions are subject to more stringent restrictions than "const-unstable" functions: They // cannot use unstable features and can only call other "const-stable" functions. pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - use attr::{ConstStability, Stability, StabilityLevel}; - // A default body marked const is not const-stable because const // trait fns currently cannot be const-stable. We shouldn't // restrict default bodies to only call const-stable functions. @@ -96,22 +94,39 @@ pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // Const-stability is only relevant for `const fn`. assert!(tcx.is_const_fn_raw(def_id)); - // Functions with `#[rustc_const_unstable]` are const-unstable. + // A function is only const-stable if it has `#[rustc_const_stable]` or it the trait it belongs + // to is const-stable. match tcx.lookup_const_stability(def_id) { - Some(ConstStability { level: StabilityLevel::Unstable { .. }, .. }) => return false, - Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => return true, - None => {} + Some(stab) => stab.is_const_stable(), + None if is_parent_const_stable_trait(tcx, def_id) => { + // Remove this when `#![feature(const_trait_impl)]` is stabilized, + // returning `true` unconditionally. + tcx.sess.delay_span_bug( + tcx.def_span(def_id), + "trait implementations cannot be const stable yet", + ); + true + } + None => false, // By default, items are not const stable. } +} + +fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + let local_def_id = def_id.expect_local(); + let hir_id = tcx.local_def_id_to_hir_id(local_def_id); + + let Some(parent) = tcx.hir().find_parent_node(hir_id) else { return false }; + let parent_def = tcx.hir().get(parent); - // Functions with `#[unstable]` are const-unstable. - // - // FIXME(ecstaticmorse): We should keep const-stability attributes wholly separate from normal stability - // attributes. `#[unstable]` should be irrelevant. - if let Some(Stability { level: StabilityLevel::Unstable { .. }, .. }) = - tcx.lookup_stability(def_id) - { + if !matches!( + parent_def, + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), + .. + }) + ) { return false; } - true + tcx.lookup_const_stability(parent.owner).map_or(false, |stab| stab.is_const_stable()) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1616b753433a8..3b0df1d83e86a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2791,7 +2791,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn is_const_fn(self, def_id: DefId) -> bool { if self.is_const_fn_raw(def_id) { match self.lookup_const_stability(def_id) { - Some(stability) if stability.level.is_unstable() => { + Some(stability) if stability.is_const_unstable() => { // has a `rustc_const_unstable` attribute, check whether the user enabled the // corresponding feature gate. self.features() @@ -2808,6 +2808,21 @@ impl<'tcx> TyCtxt<'tcx> { false } } + + /// Whether the trait impl is marked const. This does not consider stability or feature gates. + pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { + let Some(local_def_id) = def_id.as_local() else { return false }; + let hir_id = self.local_def_id_to_hir_id(local_def_id); + let node = self.hir().get(hir_id); + + matches!( + node, + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), + .. + }) + ) + } } impl<'tcx> TyCtxtAt<'tcx> { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 58195fce28197..70cb1f2a281a8 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -147,7 +147,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // Propagate unstability. This can happen even for non-staged-api crates in case // -Zforce-unstable-if-unmarked is set. if let Some(stab) = self.parent_stab { - if inherit_deprecation.yes() && stab.level.is_unstable() { + if inherit_deprecation.yes() && stab.is_unstable() { self.index.stab_map.insert(def_id, stab); } } @@ -190,7 +190,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if const_stab.is_none() { debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab); if let Some(parent) = self.parent_const_stab { - if parent.level.is_unstable() { + if parent.is_const_unstable() { self.index.const_stab_map.insert(def_id, parent); } } @@ -272,9 +272,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if stab.is_none() { debug!("annotate: stab not found, parent = {:?}", self.parent_stab); if let Some(stab) = self.parent_stab { - if inherit_deprecation.yes() && stab.level.is_unstable() - || inherit_from_parent.yes() - { + if inherit_deprecation.yes() && stab.is_unstable() || inherit_from_parent.yes() { self.index.stab_map.insert(def_id, stab); } } @@ -532,7 +530,8 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { return; } - let is_const = self.tcx.is_const_fn(def_id.to_def_id()); + let is_const = self.tcx.is_const_fn(def_id.to_def_id()) + || self.tcx.is_const_trait_impl_raw(def_id.to_def_id()); let is_stable = self .tcx .lookup_stability(def_id) @@ -710,16 +709,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => { - if self.tcx.features().staged_api { + hir::ItemKind::Impl(hir::Impl { + of_trait: Some(ref t), + self_ty, + items, + constness, + .. + }) => { + let features = self.tcx.features(); + if features.staged_api { + let attrs = self.tcx.hir().attrs(item.hir_id()); + let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item.span); + // If this impl block has an #[unstable] attribute, give an // error if all involved types and traits are stable, because // it will have no effect. // See: https://github.com/rust-lang/rust/issues/55436 - let attrs = self.tcx.hir().attrs(item.hir_id()); - if let (Some((Stability { level: attr::Unstable { .. }, .. }, span)), _) = - attr::find_stability(&self.tcx.sess, attrs, item.span) - { + if let Some((Stability { level: attr::Unstable { .. }, .. }, span)) = stab { let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true }; c.visit_ty(self_ty); c.visit_trait_ref(t); @@ -735,6 +741,19 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { ); } } + + // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable + // needs to have an error emitted. + if features.const_trait_impl + && *constness == hir::Constness::Const + && const_stab.map_or(false, |(stab, _)| stab.is_const_stable()) + { + self.tcx + .sess + .struct_span_err(item.span, "trait implementations cannot be const stable yet") + .note("see issue #67792 for more information") + .emit(); + } } for impl_item_ref in *items { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9a579cb531164..6b73634afbc2e 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -344,7 +344,7 @@ crate fn build_impl( } if let Some(stab) = tcx.lookup_stability(did) { - if stab.level.is_unstable() && stab.feature == sym::rustc_private { + if stab.is_unstable() && stab.feature == sym::rustc_private { return; } } @@ -373,7 +373,7 @@ crate fn build_impl( } if let Some(stab) = tcx.lookup_stability(did) { - if stab.level.is_unstable() && stab.feature == sym::rustc_private { + if stab.is_unstable() && stab.feature == sym::rustc_private { return; } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 456d860f12559..934de5471fe13 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -632,7 +632,7 @@ impl Item { self.stability(tcx).as_ref().and_then(|s| { let mut classes = Vec::with_capacity(2); - if s.level.is_unstable() { + if s.is_unstable() { classes.push("unstable"); } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4951cd83af207..e0f4083a91812 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -445,10 +445,7 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) -> // The "rustc_private" crates are permanently unstable so it makes no sense // to render "unstable" everywhere. - if item - .stability(tcx) - .as_ref() - .map(|s| s.level.is_unstable() && s.feature != sym::rustc_private) + if item.stability(tcx).as_ref().map(|s| s.is_unstable() && s.feature != sym::rustc_private) == Some(true) { tags += &tag_html("unstable", "", "Experimental"); diff --git a/src/test/ui/consts/rustc-impl-const-stability.rs b/src/test/ui/consts/rustc-impl-const-stability.rs index e3fda57548ea3..0c18efa0a0235 100644 --- a/src/test/ui/consts/rustc-impl-const-stability.rs +++ b/src/test/ui/consts/rustc-impl-const-stability.rs @@ -1,19 +1,18 @@ -// build-pass +// check-pass #![crate_type = "lib"] #![feature(staged_api)] #![feature(const_trait_impl)] #![stable(feature = "foo", since = "1.0.0")] - #[stable(feature = "potato", since = "1.27.0")] pub struct Data { - _data: u128 + _data: u128, } #[stable(feature = "potato", since = "1.27.0")] +#[rustc_const_unstable(feature = "data_foo", issue = "none")] impl const Default for Data { - #[rustc_const_unstable(feature = "data_foo", issue = "none")] fn default() -> Data { Data { _data: 42 } } diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs index 80e61ab0a9e8b..19e9006094bed 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs @@ -1,5 +1,4 @@ #![feature(const_trait_impl)] - #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] @@ -13,9 +12,7 @@ pub trait MyTrait { pub struct Unstable; #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "staged", issue = "none")] +#[rustc_const_unstable(feature = "unstable", issue = "none")] impl const MyTrait for Unstable { - fn func() { - - } + fn func() {} } diff --git a/src/test/ui/rfc-2632-const-trait-impl/stability.rs b/src/test/ui/rfc-2632-const-trait-impl/stability.rs deleted file mode 100644 index 906956f5eba49..0000000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/stability.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![feature(allow_internal_unstable)] -#![feature(const_add)] -#![feature(const_trait_impl)] -#![feature(staged_api)] -#![stable(feature = "rust1", since = "1.0.0")] - -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Int(i32); - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "rust1", since = "1.0.0")] -impl const std::ops::Sub for Int { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - //~^ ERROR trait methods cannot be stable const fn - Int(self.0 - rhs.0) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_add", issue = "none")] -impl const std::ops::Add for Int { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - Int(self.0 + rhs.0) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "rust1", since = "1.0.0")] -pub const fn foo() -> Int { - Int(1i32) + Int(2i32) - //~^ ERROR not yet stable as a const fn -} - -// ok -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "bar", issue = "none")] -pub const fn bar() -> Int { - Int(1i32) + Int(2i32) -} - -fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/stability.stderr b/src/test/ui/rfc-2632-const-trait-impl/stability.stderr deleted file mode 100644 index 7473b801cce63..0000000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/stability.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: trait methods cannot be stable const fn - --> $DIR/stability.rs:15:5 - | -LL | / fn sub(self, rhs: Self) -> Self { -LL | | -LL | | Int(self.0 - rhs.0) -LL | | } - | |_____^ - -error: `::add` is not yet stable as a const fn - --> $DIR/stability.rs:34:5 - | -LL | Int(1i32) + Int(2i32) - | ^^^^^^^^^^^^^^^^^^^^^ - | - = help: const-stable functions can only call other const-stable functions - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.rs b/src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.rs new file mode 100644 index 0000000000000..fc0d82727b553 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.rs @@ -0,0 +1,16 @@ +// aux-build: staged-api.rs +extern crate staged_api; + +use staged_api::*; + +// Const stability has no impact on usage in non-const contexts. +fn non_const_context() { + Unstable::func(); +} + +const fn stable_const_context() { + Unstable::func(); + //~^ ERROR cannot call non-const fn `::func` in constant functions +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.stderr new file mode 100644 index 0000000000000..61f9840e0d0a0 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api-user-crate.stderr @@ -0,0 +1,11 @@ +error[E0015]: cannot call non-const fn `::func` in constant functions + --> $DIR/staged-api-user-crate.rs:12:5 + | +LL | Unstable::func(); + | ^^^^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs index 39a1b6066dea3..1d79f5adf93f3 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs @@ -1,9 +1,7 @@ -// revisions: stock staged -#![cfg_attr(staged, feature(staged))] +// revisions: stable unstable +#![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file. #![feature(const_trait_impl)] -#![allow(incomplete_features)] - #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] @@ -13,27 +11,53 @@ extern crate staged_api; use staged_api::*; #[stable(feature = "rust1", since = "1.0.0")] -pub struct Stable; +pub struct Foo; #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(staged, rustc_const_stable(feature = "rust1", since = "1.0.0"))] -// ^ should trigger error with or without the attribute -impl const MyTrait for Stable { - fn func() { //~ ERROR trait methods cannot be stable const fn - - } +#[cfg_attr(unstable, rustc_const_unstable(feature = "foo", issue = "none"))] +#[cfg_attr(stable, rustc_const_stable(feature = "foo", since = "1.0.0"))] +impl const MyTrait for Foo { + //[stable]~^ ERROR trait implementations cannot be const stable yet + fn func() {} } +// Const stability has no impact on usage in non-const contexts. fn non_const_context() { Unstable::func(); - Stable::func(); + Foo::func(); } #[unstable(feature = "none", issue = "none")] const fn const_context() { Unstable::func(); - //[stock]~^ ERROR `::func` is not yet stable as a const fn - Stable::func(); + // ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is + // not const-stable. + Foo::func(); + //[unstable]~^ ERROR not yet stable as a const fn + // ^ fails, because the `foo` feature is not active +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(unstable, rustc_const_unstable(feature = "foo", issue = "none"))] +pub const fn const_context_not_const_stable() { + //[stable]~^ ERROR function has missing const stability attribute + Unstable::func(); + // ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is + // not const-stable. + Foo::func(); + //[unstable]~^ ERROR not yet stable as a const fn + // ^ fails, because the `foo` feature is not active +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "cheese", since = "1.0.0")] +const fn stable_const_context() { + Unstable::func(); + //[unstable]~^ ERROR not yet stable as a const fn + Foo::func(); + //[unstable]~^ ERROR not yet stable as a const fn + const_context_not_const_stable() + //[unstable]~^ ERROR not yet stable as a const fn } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.stable.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stable.stderr new file mode 100644 index 0000000000000..a1aca762ef479 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stable.stderr @@ -0,0 +1,25 @@ +error: trait implementations cannot be const stable yet + --> $DIR/staged-api.rs:19:1 + | +LL | / impl const MyTrait for Foo { +LL | | +LL | | fn func() {} +LL | | } + | |_^ + | + = note: see issue #67792 for more information + +error: function has missing const stability attribute + --> $DIR/staged-api.rs:42:1 + | +LL | / pub const fn const_context_not_const_stable() { +LL | | +LL | | Unstable::func(); +LL | | // ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is +... | +LL | | // ^ fails, because the `foo` feature is not active +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr deleted file mode 100644 index d2ff4ce200130..0000000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: trait methods cannot be stable const fn - --> $DIR/staged-api.rs:22:5 - | -LL | / fn func() { -LL | | -LL | | } - | |_____^ - -error: aborting due to previous error - diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr deleted file mode 100644 index 91c5469bd90a5..0000000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: trait methods cannot be stable const fn - --> $DIR/staged-api.rs:22:5 - | -LL | / fn func() { -LL | | -LL | | } - | |_____^ - -error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:34:5 - | -LL | Unstable::func(); - | ^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(staged)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.unstable.stderr new file mode 100644 index 0000000000000..c38d1a81ae77b --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.unstable.stderr @@ -0,0 +1,42 @@ +error: `::func` is not yet stable as a const fn + --> $DIR/staged-api.rs:35:5 + | +LL | Foo::func(); + | ^^^^^^^^^^^ + | + = help: add `#![feature(foo)]` to the crate attributes to enable + +error: `::func` is not yet stable as a const fn + --> $DIR/staged-api.rs:47:5 + | +LL | Foo::func(); + | ^^^^^^^^^^^ + | + = help: add `#![feature(foo)]` to the crate attributes to enable + +error: `::func` is not yet stable as a const fn + --> $DIR/staged-api.rs:55:5 + | +LL | Unstable::func(); + | ^^^^^^^^^^^^^^^^ + | + = help: const-stable functions can only call other const-stable functions + +error: `::func` is not yet stable as a const fn + --> $DIR/staged-api.rs:57:5 + | +LL | Foo::func(); + | ^^^^^^^^^^^ + | + = help: const-stable functions can only call other const-stable functions + +error: `const_context_not_const_stable` is not yet stable as a const fn + --> $DIR/staged-api.rs:59:5 + | +LL | const_context_not_const_stable() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: const-stable functions can only call other const-stable functions + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/stability-attribute/missing-const-stability.rs b/src/test/ui/stability-attribute/missing-const-stability.rs index 57e64737d0faa..d89886af314a4 100644 --- a/src/test/ui/stability-attribute/missing-const-stability.rs +++ b/src/test/ui/stability-attribute/missing-const-stability.rs @@ -18,9 +18,15 @@ impl Foo { pub const fn bar() {} // ok because function is unstable } -// FIXME Once #![feature(const_trait_impl)] is allowed to be stable, add a test -// for const trait impls. Right now, a "trait methods cannot be stable const fn" -// error is emitted. This occurs prior to the lint being tested here, such that -// the lint cannot currently be tested on this use case. +#[stable(feature = "stable", since = "1.0.0")] +pub trait Bar { + #[stable(feature = "stable", since = "1.0.0")] + fn fun(); +} +#[stable(feature = "stable", since = "1.0.0")] +impl const Bar for Foo { + //~^ ERROR implementation has missing const stability attribute + fn fun() {} +} fn main() {} diff --git a/src/test/ui/stability-attribute/missing-const-stability.stderr b/src/test/ui/stability-attribute/missing-const-stability.stderr index 7eba99a477abe..6f2ade0d0abf4 100644 --- a/src/test/ui/stability-attribute/missing-const-stability.stderr +++ b/src/test/ui/stability-attribute/missing-const-stability.stderr @@ -10,5 +10,14 @@ error: associated function has missing const stability attribute LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: implementation has missing const stability attribute + --> $DIR/missing-const-stability.rs:27:1 + | +LL | / impl const Bar for Foo { +LL | | +LL | | fn fun() {} +LL | | } + | |_^ + +error: aborting due to 3 previous errors