diff options
| author | bors <bors@rust-lang.org> | 2022-05-22 06:47:36 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-22 06:47:36 +0000 |
| commit | acfd327fd4e3a302ebb0a077f422a527a7935333 (patch) | |
| tree | 0fc26d507911459b9a9ac91b65c4f8cbe10a5ba3 | |
| parent | bb5e6c984de2fbabba37655551f4bab16fbd9e5e (diff) | |
| parent | f9c4f2b7ad431c6658682724a057b4a36920fdb4 (diff) | |
| download | rust-acfd327fd4e3a302ebb0a077f422a527a7935333.tar.gz rust-acfd327fd4e3a302ebb0a077f422a527a7935333.zip | |
Auto merge of #97177 - oli-obk:const-stability, r=davidtwco
Implement proper stability check for const impl Trait, fall back to unstable const when undeclared Continuation of #93960 `@jhpratt` it looks to me like the test was simply not testing for the failure you were looking for? Your checks actually do the right thing for const traits?
22 files changed, 259 insertions, 168 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 3d4bd222715..2704cb8d785 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 777f4393458..d6f62062d1f 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<Symbol> { 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 1104bbf4716..2c669dd6d9a 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 23e2afae791..0f79fe5513d 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 31e131182cc..1b466910633 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 58195fce281..70cb1f2a281 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 <https://github.com/rust-lang/rust/issues/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 1b6658bb4ca..e7b966758d6 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -344,7 +344,7 @@ pub(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 @@ pub(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 3123ece3773..a832d03a501 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 12e6115e6fe..2c0b8d7bde1 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 e3fda57548e..0c18efa0a02 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 80e61ab0a9e..19e9006094b 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 906956f5eba..00000000000 --- 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 7473b801cce..00000000000 --- 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: `<Int as Add>::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 00000000000..fc0d82727b5 --- /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 `<staged_api::Unstable as staged_api::MyTrait>::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 00000000000..61f9840e0d0 --- /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 `<staged_api::Unstable as staged_api::MyTrait>::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 39a1b6066de..1d79f5adf93 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 `<staged_api::Unstable as staged_api::MyTrait>::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 00000000000..a1aca762ef4 --- /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 <https://github.com/rust-lang/rust/issues/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 d2ff4ce2001..00000000000 --- 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 91c5469bd90..00000000000 --- 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: `<staged_api::Unstable as staged_api::MyTrait>::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 00000000000..c38d1a81ae7 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.unstable.stderr @@ -0,0 +1,42 @@ +error: `<Foo as staged_api::MyTrait>::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: `<Foo as staged_api::MyTrait>::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: `<staged_api::Unstable as staged_api::MyTrait>::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: `<Foo as staged_api::MyTrait>::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 57e64737d0f..d89886af314 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 7eba99a477a..6f2ade0d0ab 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 |
