Separate contract feature gates for the internal machinery
The extended syntax for function signature that includes contract clauses should never be user exposed versus the interface we want to ship externally eventually.
This commit is contained in:
parent
b279ff9dcf
commit
6a6c6b891b
20 changed files with 210 additions and 28 deletions
|
@ -548,6 +548,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
|||
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
|
||||
gate_all!(unsafe_fields, "`unsafe` fields are experimental");
|
||||
gate_all!(unsafe_binders, "unsafe binder types are experimental");
|
||||
gate_all!(rustc_contracts, "contracts are experimental");
|
||||
gate_all!(rustc_contracts_internals, "contract internal machinery is for internal use only");
|
||||
|
||||
if !visitor.features.never_patterns() {
|
||||
if let Some(spans) = spans.get(&sym::never_patterns) {
|
||||
|
|
|
@ -36,17 +36,17 @@ impl AttrProcMacro for ExpandEnsures {
|
|||
}
|
||||
|
||||
fn expand_injecting_circa_where_clause(
|
||||
_ecx: &mut ExtCtxt<'_>,
|
||||
ecx: &mut ExtCtxt<'_>,
|
||||
attr_span: Span,
|
||||
annotated: TokenStream,
|
||||
inject: impl FnOnce(&mut Vec<TokenTree>) -> Result<(), ErrorGuaranteed>,
|
||||
) -> Result<TokenStream, ErrorGuaranteed> {
|
||||
let mut new_tts = Vec::with_capacity(annotated.len());
|
||||
let mut cursor = annotated.into_trees();
|
||||
let mut cursor = annotated.iter();
|
||||
|
||||
// Find the `fn name<G,...>(x:X,...)` and inject the AST contract forms right after
|
||||
// the formal parameters (and return type if any).
|
||||
while let Some(tt) = cursor.next_ref() {
|
||||
while let Some(tt) = cursor.next() {
|
||||
new_tts.push(tt.clone());
|
||||
if let TokenTree::Token(tok, _) = tt
|
||||
&& tok.is_ident_named(kw::Fn)
|
||||
|
@ -58,7 +58,7 @@ fn expand_injecting_circa_where_clause(
|
|||
// Found the `fn` keyword, now find the formal parameters.
|
||||
//
|
||||
// FIXME: can this fail if you have parentheticals in a generics list, like `fn foo<F: Fn(X) -> Y>` ?
|
||||
while let Some(tt) = cursor.next_ref() {
|
||||
while let Some(tt) = cursor.next() {
|
||||
new_tts.push(tt.clone());
|
||||
|
||||
if let TokenTree::Delimited(_, _, token::Delimiter::Parenthesis, _) = tt {
|
||||
|
@ -81,7 +81,7 @@ fn expand_injecting_circa_where_clause(
|
|||
// parse the type expression itself. But rather than try to fix things with hacks like that,
|
||||
// time might be better spent extending the attribute expander to suport tt-annotation atop
|
||||
// ast-annotated, which would be an elegant way to sidestep all of this.
|
||||
let mut opt_next_tt = cursor.next_ref();
|
||||
let mut opt_next_tt = cursor.next();
|
||||
while let Some(next_tt) = opt_next_tt {
|
||||
if let TokenTree::Token(tok, _) = next_tt
|
||||
&& tok.is_ident_named(kw::Where)
|
||||
|
@ -97,8 +97,7 @@ fn expand_injecting_circa_where_clause(
|
|||
|
||||
// for anything else, transcribe the tt and keep looking.
|
||||
new_tts.push(next_tt.clone());
|
||||
opt_next_tt = cursor.next_ref();
|
||||
continue;
|
||||
opt_next_tt = cursor.next();
|
||||
}
|
||||
|
||||
// At this point, we've transcribed everything from the `fn` through the formal parameter list
|
||||
|
@ -118,10 +117,15 @@ fn expand_injecting_circa_where_clause(
|
|||
if let Some(tt) = opt_next_tt {
|
||||
new_tts.push(tt.clone());
|
||||
}
|
||||
while let Some(tt) = cursor.next_ref() {
|
||||
while let Some(tt) = cursor.next() {
|
||||
new_tts.push(tt.clone());
|
||||
}
|
||||
|
||||
// Record the span as a contract attribute expansion.
|
||||
// This is used later to stop users from using the extended syntax directly
|
||||
// which is gated via `rustc_contracts_internals`.
|
||||
ecx.psess().contract_attribute_spans.push(attr_span);
|
||||
|
||||
Ok(TokenStream::new(new_tts))
|
||||
}
|
||||
|
||||
|
|
|
@ -608,6 +608,10 @@ declare_features! (
|
|||
(unstable, return_type_notation, "1.70.0", Some(109417)),
|
||||
/// Allows `extern "rust-cold"`.
|
||||
(unstable, rust_cold_cc, "1.63.0", Some(97544)),
|
||||
/// Allows use of contracts attributes.
|
||||
(unstable, rustc_contracts, "CURRENT_RUSTC_VERSION", Some(133866)),
|
||||
/// Allows access to internal machinery used to implement contracts.
|
||||
(unstable, rustc_contracts_internals, "CURRENT_RUSTC_VERSION", Some(133866)),
|
||||
/// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics
|
||||
(unstable, sha512_sm_x86, "1.82.0", Some(126624)),
|
||||
/// Allows the use of SIMD types in functions declared in `extern` blocks.
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_ast::{
|
|||
WhereClause, token,
|
||||
};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_span::{Ident, Span, kw};
|
||||
use rustc_span::{Ident, Span, kw, sym};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use super::{ForceCollect, Parser, Trailing, UsePreAttrPos};
|
||||
|
@ -302,13 +302,27 @@ impl<'a> Parser<'a> {
|
|||
pub(super) fn parse_contract(
|
||||
&mut self,
|
||||
) -> PResult<'a, Option<rustc_ast::ptr::P<ast::FnContract>>> {
|
||||
let gate = |span| {
|
||||
if self.psess.contract_attribute_spans.contains(span) {
|
||||
// span was generated via a builtin contracts attribute, so gate as end-user visible
|
||||
self.psess.gated_spans.gate(sym::rustc_contracts, span);
|
||||
} else {
|
||||
// span was not generated via a builtin contracts attribute, so gate as internal machinery
|
||||
self.psess.gated_spans.gate(sym::rustc_contracts_internals, span);
|
||||
}
|
||||
};
|
||||
|
||||
let requires = if self.eat_keyword_noexpect(exp!(RustcContractRequires).kw) {
|
||||
Some(self.parse_expr()?)
|
||||
let precond = self.parse_expr()?;
|
||||
gate(precond.span);
|
||||
Some(precond)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let ensures = if self.eat_keyword_noexpect(exp!(RustcContractEnsures).kw) {
|
||||
Some(self.parse_expr()?)
|
||||
let postcond = self.parse_expr()?;
|
||||
gate(postcond.span);
|
||||
Some(postcond)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
@ -207,6 +207,10 @@ pub struct ParseSess {
|
|||
pub config: Cfg,
|
||||
pub check_config: CheckCfg,
|
||||
pub edition: Edition,
|
||||
/// Places where contract attributes were expanded into unstable AST forms.
|
||||
/// This is used to allowlist those spans (so that we only check them against the feature
|
||||
/// gate for the externally visible interface, and not internal implmentation machinery).
|
||||
pub contract_attribute_spans: AppendOnlyVec<Span>,
|
||||
/// Places where raw identifiers were used. This is used to avoid complaining about idents
|
||||
/// clashing with keywords in new editions.
|
||||
pub raw_identifier_spans: AppendOnlyVec<Span>,
|
||||
|
@ -255,6 +259,7 @@ impl ParseSess {
|
|||
config: Cfg::default(),
|
||||
check_config: CheckCfg::default(),
|
||||
edition: ExpnId::root().expn_data().edition,
|
||||
contract_attribute_spans: Default::default(),
|
||||
raw_identifier_spans: Default::default(),
|
||||
bad_unicode_identifiers: Lock::new(Default::default()),
|
||||
source_map,
|
||||
|
|
|
@ -1716,6 +1716,8 @@ symbols! {
|
|||
rustc_const_stable,
|
||||
rustc_const_stable_indirect,
|
||||
rustc_const_unstable,
|
||||
rustc_contracts,
|
||||
rustc_contracts_internals,
|
||||
rustc_conversion_suggestion,
|
||||
rustc_deallocator,
|
||||
rustc_def_path,
|
||||
|
|
|
@ -8,7 +8,7 @@ pub use crate::macros::builtin::contracts_requires as requires;
|
|||
/// Emitted by rustc as a desugaring of `#[requires(PRED)] fn foo(x: X) { ... }`
|
||||
/// into: `fn foo(x: X) { check_requires(|| PRED) ... }`
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
|
||||
#[unstable(feature = "rustc_contracts_internals", issue = "133866" /* compiler-team#759 */)]
|
||||
#[lang = "contract_check_requires"]
|
||||
#[track_caller]
|
||||
pub fn check_requires<C: FnOnce() -> bool>(c: C) {
|
||||
|
@ -21,7 +21,7 @@ pub fn check_requires<C: FnOnce() -> bool>(c: C) {
|
|||
/// into: `fn foo() { let _check = build_check_ensures(|ret| PRED) ... [return _check(R);] ... }`
|
||||
/// (including the implicit return of the tail expression, if any).
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
|
||||
#[unstable(feature = "rustc_contracts_internals", issue = "133866" /* compiler-team#759 */)]
|
||||
#[lang = "contract_build_check_ensures"]
|
||||
#[track_caller]
|
||||
pub fn build_check_ensures<Ret, C>(c: C) -> impl (FnOnce(Ret) -> Ret) + Copy
|
||||
|
|
|
@ -4051,8 +4051,8 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
|
|||
/// checking is turned on, so that we can specify contracts in libstd
|
||||
/// and let an end user opt into turning them on.
|
||||
#[cfg(not(bootstrap))]
|
||||
#[rustc_const_unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
|
||||
#[rustc_const_unstable(feature = "rustc_contracts_internals", issue = "133866" /* compiler-team#759 */)]
|
||||
#[unstable(feature = "rustc_contracts_internals", issue = "133866" /* compiler-team#759 */)]
|
||||
#[inline(always)]
|
||||
#[rustc_intrinsic]
|
||||
pub const fn contract_checks() -> bool {
|
||||
|
@ -4063,14 +4063,14 @@ pub const fn contract_checks() -> bool {
|
|||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
|
||||
#[unstable(feature = "rustc_contracts_internals", issue = "133866" /* compiler-team#759 */)]
|
||||
#[rustc_intrinsic]
|
||||
pub fn contract_check_requires<C: FnOnce() -> bool>(c: C) -> bool {
|
||||
c()
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
|
||||
#[unstable(feature = "rustc_contracts_internals", issue = "133866" /* compiler-team#759 */)]
|
||||
#[rustc_intrinsic]
|
||||
pub fn contract_check_ensures<'a, Ret, C: FnOnce(&'a Ret) -> bool>(ret: &'a Ret, c: C) -> bool {
|
||||
c(ret)
|
||||
|
|
|
@ -248,7 +248,7 @@ pub mod autodiff {
|
|||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none")]
|
||||
#[unstable(feature = "rustc_contracts", issue = "133866")]
|
||||
pub mod contracts;
|
||||
|
||||
#[unstable(feature = "cfg_match", issue = "115585")]
|
||||
|
|
|
@ -1783,8 +1783,8 @@ pub(crate) mod builtin {
|
|||
/// eventually parsed as a unary closure expression that is
|
||||
/// invoked on a reference to the return value.
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
#[unstable(feature = "rustc_contracts", issue = "133866")]
|
||||
#[allow_internal_unstable(rustc_contracts_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro contracts_ensures($item:item) {
|
||||
/* compiler built-in */
|
||||
|
@ -1796,8 +1796,8 @@ pub(crate) mod builtin {
|
|||
/// eventually parsed as an boolean expression with access to the
|
||||
/// function's formal parameters
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "rustc_contracts", issue = "none")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
#[unstable(feature = "rustc_contracts", issue = "133866")]
|
||||
#[allow_internal_unstable(rustc_contracts_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro contracts_requires($item:item) {
|
||||
/* compiler built-in */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
|
||||
//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
|
||||
|
||||
#![feature(rustc_contracts)]
|
||||
#![feature(rustc_contracts_internals)]
|
||||
|
||||
fn nest(x: Baz) -> i32
|
||||
rustc_contract_requires(|| x.baz > 0)
|
|
@ -16,7 +16,7 @@
|
|||
//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
|
||||
//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
|
||||
|
||||
#![feature(rustc_contracts)]
|
||||
#![feature(rustc_contracts_internals)]
|
||||
|
||||
fn tail(x: Baz) -> i32
|
||||
rustc_contract_requires(|| x.baz > 0)
|
|
@ -2,7 +2,7 @@
|
|||
//@ revisions: yes no none
|
||||
//@ [yes] compile-flags: -Zcontract-checks=yes
|
||||
//@ [no] compile-flags: -Zcontract-checks=no
|
||||
#![feature(cfg_contract_checks, rustc_contracts, core_intrinsics)]
|
||||
#![feature(cfg_contract_checks, rustc_contracts_internals, core_intrinsics)]
|
||||
|
||||
fn main() {
|
||||
#[cfg(none)] // default: disabled
|
|
@ -16,7 +16,8 @@
|
|||
//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
|
||||
//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
|
||||
|
||||
#![feature(rustc_contracts)]
|
||||
#![feature(rustc_contracts)] // to access core::contracts
|
||||
#![feature(rustc_contracts_internals)] // to access check_requires lang item
|
||||
|
||||
fn foo(x: Baz) -> i32 {
|
||||
core::contracts::check_requires(|| x.baz > 0);
|
|
@ -1,6 +1,6 @@
|
|||
//@ run-pass
|
||||
//@ compile-flags: -Zcontract-checks=yes
|
||||
#![feature(rustc_contracts)]
|
||||
#![feature(rustc_contracts_internals)]
|
||||
|
||||
fn outer() -> i32
|
||||
rustc_contract_ensures(|ret| *ret > 0)
|
|
@ -1,6 +1,6 @@
|
|||
//@ run-pass
|
||||
//@ compile-flags: -Zcontract-checks=yes
|
||||
#![feature(rustc_contracts)]
|
||||
#![feature(rustc_contracts_internals)]
|
||||
|
||||
struct Outer { outer: std::cell::Cell<i32> }
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// gate-test-rustc_contracts_internals
|
||||
|
||||
fn main() {
|
||||
// intrinsics are guarded by rustc_contracts_internals feature gate.
|
||||
core::intrinsics::contract_checks();
|
||||
//~^ ERROR use of unstable library feature `rustc_contracts_internals`
|
||||
core::intrinsics::contract_check_requires(|| true);
|
||||
//~^ ERROR use of unstable library feature `rustc_contracts_internals`
|
||||
core::intrinsics::contract_check_ensures(&1, |_|true);
|
||||
//~^ ERROR use of unstable library feature `rustc_contracts_internals`
|
||||
|
||||
// lang items are guarded by rustc_contracts_internals feature gate.
|
||||
core::contracts::check_requires(|| true);
|
||||
//~^ ERROR use of unstable library feature `rustc_contracts_internals`
|
||||
core::contracts::build_check_ensures(|_: &()| true);
|
||||
//~^ ERROR use of unstable library feature `rustc_contracts_internals`
|
||||
|
||||
// ast extensions are guarded by rustc_contracts_internals feature gate
|
||||
fn identity_1() -> i32 rustc_contract_requires(|| true) { 10 }
|
||||
//~^ ERROR contract internal machinery is for internal use only
|
||||
fn identity_2() -> i32 rustc_contract_ensures(|_| true) { 10 }
|
||||
//~^ ERROR contract internal machinery is for internal use only
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
error[E0658]: contract internal machinery is for internal use only
|
||||
--> $DIR/internal-feature-gating.rs:19:51
|
||||
|
|
||||
LL | fn identity_1() -> i32 rustc_contract_requires(|| true) { 10 }
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: contract internal machinery is for internal use only
|
||||
--> $DIR/internal-feature-gating.rs:21:50
|
||||
|
|
||||
LL | fn identity_2() -> i32 rustc_contract_ensures(|_| true) { 10 }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `rustc_contracts_internals`
|
||||
--> $DIR/internal-feature-gating.rs:5:5
|
||||
|
|
||||
LL | core::intrinsics::contract_checks();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `rustc_contracts_internals`
|
||||
--> $DIR/internal-feature-gating.rs:7:5
|
||||
|
|
||||
LL | core::intrinsics::contract_check_requires(|| true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `rustc_contracts_internals`
|
||||
--> $DIR/internal-feature-gating.rs:9:5
|
||||
|
|
||||
LL | core::intrinsics::contract_check_ensures(&1, |_|true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `rustc_contracts_internals`
|
||||
--> $DIR/internal-feature-gating.rs:13:5
|
||||
|
|
||||
LL | core::contracts::check_requires(|| true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `rustc_contracts_internals`
|
||||
--> $DIR/internal-feature-gating.rs:15:5
|
||||
|
|
||||
LL | core::contracts::build_check_ensures(|_: &()| true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts_internals)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
11
tests/ui/feature-gates/feature-gate-rustc-contracts.rs
Normal file
11
tests/ui/feature-gates/feature-gate-rustc-contracts.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
#[core::contracts::requires(x > 0)]
|
||||
pub fn requires_needs_it(x: i32) { }
|
||||
//~^^ ERROR use of unstable library feature `rustc_contracts`
|
||||
//~^^^ ERROR contracts are experimental
|
||||
|
||||
#[core::contracts::ensures(|ret| *ret > 0)]
|
||||
pub fn ensures_needs_it() -> i32 { 10 }
|
||||
//~^^ ERROR use of unstable library feature `rustc_contracts`
|
||||
//~^^^ ERROR contracts are experimental
|
43
tests/ui/feature-gates/feature-gate-rustc-contracts.stderr
Normal file
43
tests/ui/feature-gates/feature-gate-rustc-contracts.stderr
Normal file
|
@ -0,0 +1,43 @@
|
|||
error[E0658]: use of unstable library feature `rustc_contracts`
|
||||
--> $DIR/feature-gate-rustc-contracts.rs:3:3
|
||||
|
|
||||
LL | #[core::contracts::requires(x > 0)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `rustc_contracts`
|
||||
--> $DIR/feature-gate-rustc-contracts.rs:8:3
|
||||
|
|
||||
LL | #[core::contracts::ensures(|ret| *ret > 0)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: contracts are experimental
|
||||
--> $DIR/feature-gate-rustc-contracts.rs:3:1
|
||||
|
|
||||
LL | #[core::contracts::requires(x > 0)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: contracts are experimental
|
||||
--> $DIR/feature-gate-rustc-contracts.rs:8:1
|
||||
|
|
||||
LL | #[core::contracts::ensures(|ret| *ret > 0)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #133866 <https://github.com/rust-lang/rust/issues/133866> for more information
|
||||
= help: add `#![feature(rustc_contracts)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Add table
Add a link
Reference in a new issue