Rollup merge of #143925 - oli-obk:slice-const-partialeq, r=fee1-dead
Make slice comparisons const This needed a fix for `derive_const`, too, as it wasn't usable in libcore anymore as trait impls need const stability attributes. I think we can't use the same system as normal trait impls while `const_trait_impl` is still unstable. r? ```@fee1-dead``` cc rust-lang/rust#143800
This commit is contained in:
commit
82fbbddf63
31 changed files with 134 additions and 49 deletions
|
|
@ -23,6 +23,7 @@ pub(crate) fn expand_deriving_copy(
|
|||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
@ -46,6 +47,7 @@ pub(crate) fn expand_deriving_const_param_ty(
|
|||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
@ -60,6 +62,7 @@ pub(crate) fn expand_deriving_const_param_ty(
|
|||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
@ -83,6 +86,7 @@ pub(crate) fn expand_deriving_unsized_const_param_ty(
|
|||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ pub(crate) fn expand_deriving_clone(
|
|||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand_ext(cx, mitem, item, push, is_simple)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ pub(crate) fn expand_deriving_eq(
|
|||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
trait_def.expand_ext(cx, mitem, item, push, true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ pub(crate) fn expand_deriving_ord(
|
|||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub(crate) fn expand_deriving_partial_eq(
|
|||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const: false,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
structural_trait_def.expand(cx, mitem, item, push);
|
||||
|
||||
|
|
@ -58,6 +59,7 @@ pub(crate) fn expand_deriving_partial_eq(
|
|||
methods,
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ pub(crate) fn expand_deriving_partial_ord(
|
|||
methods: vec![partial_cmp_def],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ pub(crate) fn expand_deriving_debug(
|
|||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ pub(crate) fn expand_deriving_default(
|
|||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,9 +181,11 @@ use std::{iter, vec};
|
|||
pub(crate) use StaticFields::*;
|
||||
pub(crate) use SubstructureFields::*;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{IdentIsRaw, LitKind, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree};
|
||||
use rustc_ast::{
|
||||
self as ast, AnonConst, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind,
|
||||
Generics, Mutability, PatKind, VariantData,
|
||||
self as ast, AnonConst, AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg,
|
||||
GenericParamKind, Generics, Mutability, PatKind, Safety, VariantData,
|
||||
};
|
||||
use rustc_attr_data_structures::{AttributeKind, ReprPacked};
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
|
|
@ -222,6 +224,8 @@ pub(crate) struct TraitDef<'a> {
|
|||
pub associated_types: Vec<(Ident, Ty)>,
|
||||
|
||||
pub is_const: bool,
|
||||
|
||||
pub is_staged_api_crate: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct MethodDef<'a> {
|
||||
|
|
@ -784,8 +788,45 @@ impl<'a> TraitDef<'a> {
|
|||
// Create the type of `self`.
|
||||
let path = cx.path_all(self.span, false, vec![type_ident], self_params);
|
||||
let self_type = cx.ty_path(path);
|
||||
let rustc_const_unstable =
|
||||
cx.path_ident(self.span, Ident::new(sym::rustc_const_unstable, self.span));
|
||||
|
||||
let mut attrs = thin_vec![cx.attr_word(sym::automatically_derived, self.span),];
|
||||
|
||||
// Only add `rustc_const_unstable` attributes if `derive_const` is used within libcore/libstd,
|
||||
// Other crates don't need stability attributes, so adding them is not useful, but libcore needs them
|
||||
// on all const trait impls.
|
||||
if self.is_const && self.is_staged_api_crate {
|
||||
attrs.push(
|
||||
cx.attr_nested(
|
||||
rustc_ast::AttrItem {
|
||||
unsafety: Safety::Default,
|
||||
path: rustc_const_unstable,
|
||||
args: AttrArgs::Delimited(DelimArgs {
|
||||
dspan: DelimSpan::from_single(self.span),
|
||||
delim: rustc_ast::token::Delimiter::Parenthesis,
|
||||
tokens: [
|
||||
TokenKind::Ident(sym::feature, IdentIsRaw::No),
|
||||
TokenKind::Eq,
|
||||
TokenKind::lit(LitKind::Str, sym::derive_const, None),
|
||||
TokenKind::Comma,
|
||||
TokenKind::Ident(sym::issue, IdentIsRaw::No),
|
||||
TokenKind::Eq,
|
||||
TokenKind::lit(LitKind::Str, sym::derive_const_issue, None),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|kind| {
|
||||
TokenTree::Token(Token { kind, span: self.span }, Spacing::Alone)
|
||||
})
|
||||
.collect(),
|
||||
}),
|
||||
tokens: None,
|
||||
},
|
||||
self.span,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
let attrs = thin_vec![cx.attr_word(sym::automatically_derived, self.span),];
|
||||
let opt_trait_ref = Some(trait_ref);
|
||||
|
||||
cx.item(
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ pub(crate) fn expand_deriving_hash(
|
|||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
hash_trait_def.expand(cx, mitem, item, push);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use rustc_ast::token::Delimiter;
|
|||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::util::literal;
|
||||
use rustc_ast::{
|
||||
self as ast, AnonConst, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp,
|
||||
attr, token, tokenstream,
|
||||
self as ast, AnonConst, AttrItem, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind,
|
||||
UnOp, attr, token, tokenstream,
|
||||
};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||
|
|
@ -766,4 +766,10 @@ impl<'a> ExtCtxt<'a> {
|
|||
span,
|
||||
)
|
||||
}
|
||||
|
||||
// Builds an attribute fully manually.
|
||||
pub fn attr_nested(&self, inner: AttrItem, span: Span) -> ast::Attribute {
|
||||
let g = &self.sess.psess.attr_id_generator;
|
||||
attr::mk_attr_from_item(g, inner, None, ast::AttrStyle::Outer, span)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -840,6 +840,7 @@ symbols! {
|
|||
derive,
|
||||
derive_coerce_pointee,
|
||||
derive_const,
|
||||
derive_const_issue: "118304",
|
||||
derive_default_enum,
|
||||
derive_smart_pointer,
|
||||
destruct,
|
||||
|
|
|
|||
|
|
@ -381,7 +381,8 @@ pub struct AssertParamIsEq<T: Eq + PointeeSized> {
|
|||
///
|
||||
/// assert_eq!(2.cmp(&1), Ordering::Greater);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
#[derive(Clone, Copy, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
#[derive_const(PartialEq)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
// This is a lang item only so that `BinOp::Cmp` in MIR can return it.
|
||||
// It has no special behavior, but does require that the three variants
|
||||
|
|
|
|||
|
|
@ -17,11 +17,15 @@ use crate::num::NonZero;
|
|||
/// - Neither `Self` nor `Rhs` have provenance, so integer comparisons are correct.
|
||||
/// - `<Self as PartialEq<Rhs>>::{eq,ne}` are equivalent to comparing the bytes.
|
||||
#[rustc_specialization_trait]
|
||||
pub(crate) unsafe trait BytewiseEq<Rhs = Self>: PartialEq<Rhs> + Sized {}
|
||||
#[const_trait]
|
||||
pub(crate) unsafe trait BytewiseEq<Rhs = Self>:
|
||||
~const PartialEq<Rhs> + Sized
|
||||
{
|
||||
}
|
||||
|
||||
macro_rules! is_bytewise_comparable {
|
||||
($($t:ty),+ $(,)?) => {$(
|
||||
unsafe impl BytewiseEq for $t {}
|
||||
unsafe impl const BytewiseEq for $t {}
|
||||
)+};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2208,6 +2208,7 @@ pub const unsafe fn raw_eq<T>(a: &T, b: &T) -> bool;
|
|||
/// [valid]: crate::ptr#safety
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
pub const unsafe fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32;
|
||||
|
||||
/// See documentation of [`std::hint::black_box`] for details.
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
#![feature(cfg_select)]
|
||||
#![feature(cfg_target_has_reliable_f16_f128)]
|
||||
#![feature(const_carrying_mul_add)]
|
||||
#![feature(const_cmp)]
|
||||
#![feature(const_destruct)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
|
@ -146,6 +147,7 @@
|
|||
#![feature(const_trait_impl)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(deprecated_suggestion)]
|
||||
#![feature(derive_const)]
|
||||
#![feature(doc_cfg)]
|
||||
#![feature(doc_cfg_hide)]
|
||||
#![feature(doc_notable_trait)]
|
||||
|
|
|
|||
|
|
@ -1615,7 +1615,7 @@ pub(crate) mod builtin {
|
|||
/// See [the reference] for more info.
|
||||
///
|
||||
/// [the reference]: ../../../reference/attributes/derive.html
|
||||
#[unstable(feature = "derive_const", issue = "none")]
|
||||
#[unstable(feature = "derive_const", issue = "118304")]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro derive_const($item:item) {
|
||||
/* compiler built-in */
|
||||
|
|
|
|||
|
|
@ -200,9 +200,10 @@ impl<T> UseCloned for NonZero<T> where T: ZeroablePrimitive {}
|
|||
impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {}
|
||||
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
impl<T> PartialEq for NonZero<T>
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
impl<T> const PartialEq for NonZero<T>
|
||||
where
|
||||
T: ZeroablePrimitive + PartialEq,
|
||||
T: ZeroablePrimitive + ~const PartialEq,
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
|
|
|||
|
|
@ -2300,7 +2300,8 @@ impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> crate::marker::StructuralPartialEq for Option<T> {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: PartialEq> PartialEq for Option<T> {
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
impl<T: ~const PartialEq> const PartialEq for Option<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// Spelling out the cases explicitly optimizes better than
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ pub use crate::macros::builtin::{
|
|||
alloc_error_handler, bench, derive, global_allocator, test, test_case,
|
||||
};
|
||||
|
||||
#[unstable(feature = "derive_const", issue = "none")]
|
||||
#[unstable(feature = "derive_const", issue = "118304")]
|
||||
pub use crate::macros::builtin::derive_const;
|
||||
|
||||
#[unstable(
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ use crate::num::NonZero;
|
|||
use crate::ops::ControlFlow;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T, U> PartialEq<[U]> for [T]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
impl<T, U> const PartialEq<[U]> for [T]
|
||||
where
|
||||
T: PartialEq<U>,
|
||||
T: ~const PartialEq<U>,
|
||||
{
|
||||
fn eq(&self, other: &[U]) -> bool {
|
||||
SlicePartialEq::equal(self, other)
|
||||
|
|
@ -94,6 +95,8 @@ impl<T: PartialOrd> PartialOrd for [T] {
|
|||
|
||||
#[doc(hidden)]
|
||||
// intermediate trait for specialization of slice's PartialEq
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
trait SlicePartialEq<B> {
|
||||
fn equal(&self, other: &[B]) -> bool;
|
||||
|
||||
|
|
@ -103,9 +106,10 @@ trait SlicePartialEq<B> {
|
|||
}
|
||||
|
||||
// Generic slice equality
|
||||
impl<A, B> SlicePartialEq<B> for [A]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
impl<A, B> const SlicePartialEq<B> for [A]
|
||||
where
|
||||
A: PartialEq<B>,
|
||||
A: ~const PartialEq<B>,
|
||||
{
|
||||
default fn equal(&self, other: &[B]) -> bool {
|
||||
if self.len() != other.len() {
|
||||
|
|
@ -115,11 +119,14 @@ where
|
|||
// Implemented as explicit indexing rather
|
||||
// than zipped iterators for performance reasons.
|
||||
// See PR https://github.com/rust-lang/rust/pull/116846
|
||||
for idx in 0..self.len() {
|
||||
// FIXME(const_hack): make this a `for idx in 0..self.len()` loop.
|
||||
let mut idx = 0;
|
||||
while idx < self.len() {
|
||||
// bound checks are optimized away
|
||||
if self[idx] != other[idx] {
|
||||
return false;
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
true
|
||||
|
|
@ -128,9 +135,10 @@ where
|
|||
|
||||
// When each element can be compared byte-wise, we can compare all the bytes
|
||||
// from the whole size in one call to the intrinsics.
|
||||
impl<A, B> SlicePartialEq<B> for [A]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
impl<A, B> const SlicePartialEq<B> for [A]
|
||||
where
|
||||
A: BytewiseEq<B>,
|
||||
A: ~const BytewiseEq<B>,
|
||||
{
|
||||
fn equal(&self, other: &[B]) -> bool {
|
||||
if self.len() != other.len() {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ impl Ord for str {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl PartialEq for str {
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
impl const PartialEq for str {
|
||||
#[inline]
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
self.as_bytes() == other.as_bytes()
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ pub use core::prelude::v1::{
|
|||
alloc_error_handler, bench, derive, global_allocator, test, test_case,
|
||||
};
|
||||
|
||||
#[unstable(feature = "derive_const", issue = "none")]
|
||||
#[unstable(feature = "derive_const", issue = "118304")]
|
||||
pub use core::prelude::v1::derive_const;
|
||||
|
||||
// Do not `doc(no_inline)` either.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ check-fail
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_intrinsics, const_cmp)]
|
||||
use std::intrinsics::compare_bytes;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ run-pass
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_intrinsics, const_cmp)]
|
||||
use std::intrinsics::compare_bytes;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
// Crate that exports a const fn. Used for testing cross-crate.
|
||||
|
||||
#![crate_type="rlib"]
|
||||
#![crate_type = "rlib"]
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
#![feature(staged_api)]
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature="foo", issue = "none")]
|
||||
pub const fn foo() -> u32 { 42 }
|
||||
#[rustc_const_unstable(feature = "foo", issue = "none")]
|
||||
pub const fn foo() -> u32 {
|
||||
42
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//@ compile-flags: -Znext-solver
|
||||
//@ known-bug: #110395
|
||||
|
||||
// Broken until we have `const PartialEq` impl in stdlib
|
||||
// Broken until `(): const PartialEq`
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_trait_impl, const_cmp, const_destruct)]
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ error[E0658]: use of unstable library feature `derive_const`
|
|||
LL | #[derive_const(Debug)]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #118304 <https://github.com/rust-lang/rust/issues/118304> for more information
|
||||
= help: add `#![feature(derive_const)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
error[E0015]: cannot match on `str` in constant functions
|
||||
--> $DIR/match-non-const-eq.rs:7:9
|
||||
|
|
||||
LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||
| ^^^
|
||||
|
|
||||
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
//@ known-bug: #110395
|
||||
//@ revisions: stock gated
|
||||
#![cfg_attr(gated, feature(const_trait_impl))]
|
||||
#![cfg_attr(gated, feature(const_trait_impl, const_cmp))]
|
||||
//@[gated] check-pass
|
||||
|
||||
const fn foo(input: &'static str) {
|
||||
match input {
|
||||
"a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||
//FIXME ~^ ERROR cannot match on `str` in constant functions
|
||||
"a" => (),
|
||||
//[stock]~^ ERROR cannot match on `str` in constant functions
|
||||
//[stock]~| ERROR `PartialEq` is not yet stable as a const trait
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,26 @@
|
|||
error[E0015]: cannot match on `str` in constant functions
|
||||
error[E0658]: cannot match on `str` in constant functions
|
||||
--> $DIR/match-non-const-eq.rs:7:9
|
||||
|
|
||||
LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||
LL | "a" => (),
|
||||
| ^^^
|
||||
|
|
||||
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` 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 1 previous error
|
||||
error: `PartialEq` is not yet stable as a const trait
|
||||
--> $DIR/match-non-const-eq.rs:7:9
|
||||
|
|
||||
LL | "a" => (),
|
||||
| ^^^
|
||||
|
|
||||
help: add `#![feature(const_cmp)]` to the crate attributes to enable
|
||||
|
|
||||
LL + #![feature(const_cmp)]
|
||||
|
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue