Rollup merge of #86838 - lambinoo:I-69630-rust_const_unstable_check_const, r=oli-obk
Checking that function is const if marked with rustc_const_unstable Fixes #69630 This one is still missing tests to check the behavior but I checked by hand and it seemed to work. I would not mind some direction for writing those unit tests!
This commit is contained in:
commit
d85718ad01
7 changed files with 220 additions and 7 deletions
|
@ -10,7 +10,7 @@ Erroneous code example:
|
||||||
fn _stable_fn() {}
|
fn _stable_fn() {}
|
||||||
|
|
||||||
#[rustc_const_stable(feature = "_stable_const_fn")] // invalid
|
#[rustc_const_stable(feature = "_stable_const_fn")] // invalid
|
||||||
fn _stable_const_fn() {}
|
const fn _stable_const_fn() {}
|
||||||
|
|
||||||
#[stable(feature = "_deprecated_fn", since = "0.1.0")]
|
#[stable(feature = "_deprecated_fn", since = "0.1.0")]
|
||||||
#[rustc_deprecated(
|
#[rustc_deprecated(
|
||||||
|
@ -29,7 +29,7 @@ To fix this issue, you need to provide the `since` field. Example:
|
||||||
fn _stable_fn() {}
|
fn _stable_fn() {}
|
||||||
|
|
||||||
#[rustc_const_stable(feature = "_stable_const_fn", since = "1.0.0")] // ok!
|
#[rustc_const_stable(feature = "_stable_const_fn", since = "1.0.0")] // ok!
|
||||||
fn _stable_const_fn() {}
|
const fn _stable_const_fn() {}
|
||||||
|
|
||||||
#[stable(feature = "_deprecated_fn", since = "0.1.0")]
|
#[stable(feature = "_deprecated_fn", since = "0.1.0")]
|
||||||
#[rustc_deprecated(
|
#[rustc_deprecated(
|
||||||
|
|
|
@ -10,7 +10,7 @@ Erroneous code example:
|
||||||
fn _unstable_fn() {}
|
fn _unstable_fn() {}
|
||||||
|
|
||||||
#[rustc_const_unstable(feature = "_unstable_const_fn", issue = "0")] // invalid
|
#[rustc_const_unstable(feature = "_unstable_const_fn", issue = "0")] // invalid
|
||||||
fn _unstable_const_fn() {}
|
const fn _unstable_const_fn() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
To fix this issue, you need to provide a correct value in the `issue` field.
|
To fix this issue, you need to provide a correct value in the `issue` field.
|
||||||
|
@ -24,7 +24,7 @@ Example:
|
||||||
fn _unstable_fn() {}
|
fn _unstable_fn() {}
|
||||||
|
|
||||||
#[rustc_const_unstable(feature = "_unstable_const_fn", issue = "1")] // ok!
|
#[rustc_const_unstable(feature = "_unstable_const_fn", issue = "1")] // ok!
|
||||||
fn _unstable_const_fn() {}
|
const fn _unstable_const_fn() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
|
See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
|
||||||
|
|
|
@ -10,7 +10,7 @@ Erroneous code example:
|
||||||
fn _unstable_fn() {}
|
fn _unstable_fn() {}
|
||||||
|
|
||||||
#[rustc_const_unstable(feature = "_unstable_const_fn")] // invalid
|
#[rustc_const_unstable(feature = "_unstable_const_fn")] // invalid
|
||||||
fn _unstable_const_fn() {}
|
const fn _unstable_const_fn() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
To fix this issue, you need to provide the `issue` field. Example:
|
To fix this issue, you need to provide the `issue` field. Example:
|
||||||
|
@ -26,7 +26,7 @@ fn _unstable_fn() {}
|
||||||
feature = "_unstable_const_fn",
|
feature = "_unstable_const_fn",
|
||||||
issue = "none"
|
issue = "none"
|
||||||
)] // ok!
|
)] // ok!
|
||||||
fn _unstable_const_fn() {}
|
const fn _unstable_const_fn() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
|
See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
|
||||||
|
|
|
@ -20,6 +20,7 @@ use rustc_session::parse::feature_err;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -95,10 +96,12 @@ struct Annotator<'a, 'tcx> {
|
||||||
impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
// Determine the stability for a node based on its attributes and inherited
|
// Determine the stability for a node based on its attributes and inherited
|
||||||
// stability. The stability is recorded in the index and used as the parent.
|
// stability. The stability is recorded in the index and used as the parent.
|
||||||
|
// If the node is a function, `fn_sig` is its signature
|
||||||
fn annotate<F>(
|
fn annotate<F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
item_sp: Span,
|
item_sp: Span,
|
||||||
|
fn_sig: Option<&'tcx hir::FnSig<'tcx>>,
|
||||||
kind: AnnotationKind,
|
kind: AnnotationKind,
|
||||||
inherit_deprecation: InheritDeprecation,
|
inherit_deprecation: InheritDeprecation,
|
||||||
inherit_const_stability: InheritConstStability,
|
inherit_const_stability: InheritConstStability,
|
||||||
|
@ -163,13 +166,30 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
|
let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
|
||||||
|
let mut const_span = None;
|
||||||
|
|
||||||
let const_stab = const_stab.map(|(const_stab, _)| {
|
let const_stab = const_stab.map(|(const_stab, const_span_node)| {
|
||||||
let const_stab = self.tcx.intern_const_stability(const_stab);
|
let const_stab = self.tcx.intern_const_stability(const_stab);
|
||||||
self.index.const_stab_map.insert(hir_id, const_stab);
|
self.index.const_stab_map.insert(hir_id, const_stab);
|
||||||
|
const_span = Some(const_span_node);
|
||||||
const_stab
|
const_stab
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI,
|
||||||
|
// check if the function/method is const or the parent impl block is const
|
||||||
|
if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) {
|
||||||
|
if fn_sig.header.abi != Abi::RustIntrinsic
|
||||||
|
&& fn_sig.header.abi != Abi::PlatformIntrinsic
|
||||||
|
&& !fn_sig.header.is_const()
|
||||||
|
{
|
||||||
|
if !self.in_trait_impl
|
||||||
|
|| (self.in_trait_impl && !self.tcx.is_const_fn_raw(hir_id.owner.to_def_id()))
|
||||||
|
{
|
||||||
|
missing_const_err(&self.tcx.sess, fn_sig.span, const_span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// `impl const Trait for Type` items forward their const stability to their
|
// `impl const Trait for Type` items forward their const stability to their
|
||||||
// immediate children.
|
// immediate children.
|
||||||
if const_stab.is_none() {
|
if const_stab.is_none() {
|
||||||
|
@ -367,6 +387,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
let orig_in_trait_impl = self.in_trait_impl;
|
let orig_in_trait_impl = self.in_trait_impl;
|
||||||
let mut kind = AnnotationKind::Required;
|
let mut kind = AnnotationKind::Required;
|
||||||
let mut const_stab_inherit = InheritConstStability::No;
|
let mut const_stab_inherit = InheritConstStability::No;
|
||||||
|
let mut fn_sig = None;
|
||||||
|
|
||||||
match i.kind {
|
match i.kind {
|
||||||
// Inherent impls and foreign modules serve only as containers for other items,
|
// Inherent impls and foreign modules serve only as containers for other items,
|
||||||
// they don't have their own stability. They still can be annotated as unstable
|
// they don't have their own stability. They still can be annotated as unstable
|
||||||
|
@ -387,6 +409,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
self.annotate(
|
self.annotate(
|
||||||
ctor_hir_id,
|
ctor_hir_id,
|
||||||
i.span,
|
i.span,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -395,12 +418,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::ItemKind::Fn(ref item_fn_sig, _, _) => {
|
||||||
|
fn_sig = Some(item_fn_sig);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.annotate(
|
self.annotate(
|
||||||
i.hir_id(),
|
i.hir_id(),
|
||||||
i.span,
|
i.span,
|
||||||
|
fn_sig,
|
||||||
kind,
|
kind,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
const_stab_inherit,
|
const_stab_inherit,
|
||||||
|
@ -411,9 +438,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
|
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
|
||||||
|
let fn_sig = match ti.kind {
|
||||||
|
hir::TraitItemKind::Fn(ref fn_sig, _) => Some(fn_sig),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
self.annotate(
|
self.annotate(
|
||||||
ti.hir_id(),
|
ti.hir_id(),
|
||||||
ti.span,
|
ti.span,
|
||||||
|
fn_sig,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -427,9 +460,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
|
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
|
||||||
let kind =
|
let kind =
|
||||||
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
|
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
|
||||||
|
|
||||||
|
let fn_sig = match ii.kind {
|
||||||
|
hir::ImplItemKind::Fn(ref fn_sig, _) => Some(fn_sig),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
self.annotate(
|
self.annotate(
|
||||||
ii.hir_id(),
|
ii.hir_id(),
|
||||||
ii.span,
|
ii.span,
|
||||||
|
fn_sig,
|
||||||
kind,
|
kind,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -444,6 +484,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
self.annotate(
|
self.annotate(
|
||||||
var.id,
|
var.id,
|
||||||
var.span,
|
var.span,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -453,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
v.annotate(
|
v.annotate(
|
||||||
ctor_hir_id,
|
ctor_hir_id,
|
||||||
var.span,
|
var.span,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -470,6 +512,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
self.annotate(
|
self.annotate(
|
||||||
s.hir_id,
|
s.hir_id,
|
||||||
s.span,
|
s.span,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -484,6 +527,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
self.annotate(
|
self.annotate(
|
||||||
i.hir_id(),
|
i.hir_id(),
|
||||||
i.span,
|
i.span,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -498,6 +542,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
self.annotate(
|
self.annotate(
|
||||||
md.hir_id(),
|
md.hir_id(),
|
||||||
md.span,
|
md.span,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -517,6 +562,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
||||||
self.annotate(
|
self.annotate(
|
||||||
p.hir_id,
|
p.hir_id,
|
||||||
p.span,
|
p.span,
|
||||||
|
None,
|
||||||
kind,
|
kind,
|
||||||
InheritDeprecation::No,
|
InheritDeprecation::No,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -687,6 +733,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
|
||||||
annotator.annotate(
|
annotator.annotate(
|
||||||
hir::CRATE_HIR_ID,
|
hir::CRATE_HIR_ID,
|
||||||
krate.item.inner,
|
krate.item.inner,
|
||||||
|
None,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
InheritDeprecation::Yes,
|
InheritDeprecation::Yes,
|
||||||
InheritConstStability::No,
|
InheritConstStability::No,
|
||||||
|
@ -969,3 +1016,15 @@ fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) {
|
||||||
struct_span_err!(sess, span, E0636, "the feature `{}` has already been declared", feature)
|
struct_span_err!(sess, span, E0636, "the feature `{}` has already been declared", feature)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn missing_const_err(session: &Session, fn_sig_span: Span, const_span: Span) {
|
||||||
|
const ERROR_MSG: &'static str = "attributes `#[rustc_const_unstable]` \
|
||||||
|
and `#[rustc_const_stable]` require \
|
||||||
|
the function or method to be `const`";
|
||||||
|
|
||||||
|
session
|
||||||
|
.struct_span_err(fn_sig_span, ERROR_MSG)
|
||||||
|
.span_help(fn_sig_span, "make the function or method const")
|
||||||
|
.span_label(const_span, "attribute specified here")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
|
47
src/test/ui/consts/rustc-const-stability-require-const.rs
Normal file
47
src/test/ui/consts/rustc-const-stability-require-const.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(staged_api)]
|
||||||
|
#![stable(feature = "foo", since = "1.0.0")]
|
||||||
|
|
||||||
|
#[stable(feature = "foo", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_foo", issue = "none")]
|
||||||
|
pub fn foo() {}
|
||||||
|
//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
|
||||||
|
#[stable(feature = "bar", since = "1.0.0")]
|
||||||
|
#[rustc_const_stable(feature = "const_bar", since = "1.0.0")]
|
||||||
|
pub fn bar() {}
|
||||||
|
//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
|
||||||
|
#[stable(feature = "potato", since = "1.0.0")]
|
||||||
|
pub struct Potato;
|
||||||
|
|
||||||
|
impl Potato {
|
||||||
|
#[stable(feature = "salad", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_salad", issue = "none")]
|
||||||
|
pub fn salad(&self) -> &'static str { "mmmmmm" }
|
||||||
|
//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
|
||||||
|
#[stable(feature = "roasted", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_roasted", issue = "none")]
|
||||||
|
pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" }
|
||||||
|
//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "bar", since = "1.0.0")]
|
||||||
|
#[rustc_const_stable(feature = "const_bar", since = "1.0.0")]
|
||||||
|
pub extern "C" fn bar_c() {}
|
||||||
|
//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
|
||||||
|
#[stable(feature = "foo", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_foo", issue = "none")]
|
||||||
|
pub extern "C" fn foo_c() {}
|
||||||
|
//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
|
||||||
|
|
||||||
|
#[stable(feature = "foobar", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "foobar_const", issue = "none")]
|
||||||
|
pub const fn foobar() {}
|
||||||
|
|
||||||
|
#[stable(feature = "barfoo", since = "1.0.0")]
|
||||||
|
#[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")]
|
||||||
|
pub const fn barfoo() {}
|
|
@ -0,0 +1,86 @@
|
||||||
|
error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:7:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_const_unstable(feature = "const_foo", issue = "none")]
|
||||||
|
| -------------------------------------------------------------- attribute specified here
|
||||||
|
LL | pub fn foo() {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function or method const
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:7:1
|
||||||
|
|
|
||||||
|
LL | pub fn foo() {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:12:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_const_stable(feature = "const_bar", since = "1.0.0")]
|
||||||
|
| ------------------------------------------------------------- attribute specified here
|
||||||
|
LL | pub fn bar() {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function or method const
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:12:1
|
||||||
|
|
|
||||||
|
LL | pub fn bar() {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:21:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_const_unstable(feature = "const_salad", issue = "none")]
|
||||||
|
| ---------------------------------------------------------------- attribute specified here
|
||||||
|
LL | pub fn salad(&self) -> &'static str { "mmmmmm" }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function or method const
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:21:5
|
||||||
|
|
|
||||||
|
LL | pub fn salad(&self) -> &'static str { "mmmmmm" }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:26:5
|
||||||
|
|
|
||||||
|
LL | #[rustc_const_unstable(feature = "const_roasted", issue = "none")]
|
||||||
|
| ------------------------------------------------------------------ attribute specified here
|
||||||
|
LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function or method const
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:26:5
|
||||||
|
|
|
||||||
|
LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:32:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_const_stable(feature = "const_bar", since = "1.0.0")]
|
||||||
|
| ------------------------------------------------------------- attribute specified here
|
||||||
|
LL | pub extern "C" fn bar_c() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function or method const
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:32:1
|
||||||
|
|
|
||||||
|
LL | pub extern "C" fn bar_c() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:37:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_const_unstable(feature = "const_foo", issue = "none")]
|
||||||
|
| -------------------------------------------------------------- attribute specified here
|
||||||
|
LL | pub extern "C" fn foo_c() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function or method const
|
||||||
|
--> $DIR/rustc-const-stability-require-const.rs:37:1
|
||||||
|
|
|
||||||
|
LL | pub extern "C" fn foo_c() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
21
src/test/ui/consts/rustc-impl-const-stability.rs
Normal file
21
src/test/ui/consts/rustc-impl-const-stability.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// build-pass
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "potato", since = "1.27.0")]
|
||||||
|
impl const Default for Data {
|
||||||
|
#[rustc_const_unstable(feature = "data_foo", issue = "none")]
|
||||||
|
fn default() -> Data {
|
||||||
|
Data { _data: 42 }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue