Auto merge of #100982 - fee1-dead-contrib:const-impl-requires-const-trait, r=oli-obk
Require `#[const_trait]` on `Trait` for `impl const Trait` r? `@oli-obk`
This commit is contained in:
commit
7a8636c843
80 changed files with 433 additions and 245 deletions
|
@ -428,12 +428,18 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
|
if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
|
||||||
|
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
|
||||||
|
// this is because the well-formedness of the function does not need to be proved to have `const`
|
||||||
|
// impls for trait bounds.
|
||||||
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
|
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
|
||||||
|
let prev = self.cx.param_env;
|
||||||
|
self.cx.param_env = prev.without_const();
|
||||||
self.cx.normalize_and_prove_instantiated_predicates(
|
self.cx.normalize_and_prove_instantiated_predicates(
|
||||||
def_id,
|
def_id,
|
||||||
instantiated_predicates,
|
instantiated_predicates,
|
||||||
locations,
|
locations,
|
||||||
);
|
);
|
||||||
|
self.cx.param_env = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,11 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
|
||||||
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable};
|
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable};
|
||||||
use rustc_mir_dataflow::{self, Analysis};
|
use rustc_mir_dataflow::{self, Analysis};
|
||||||
use rustc_span::{sym, Span, Symbol};
|
use rustc_span::{sym, Span, Symbol};
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::SelectionContext;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
||||||
|
use rustc_trait_selection::traits::{
|
||||||
|
self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt,
|
||||||
|
};
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -739,6 +742,43 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
selcx.select(&obligation)
|
selcx.select(&obligation)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// do a well-formedness check on the trait method being called. This is because typeck only does a
|
||||||
|
// "non-const" check. This is required for correctness here.
|
||||||
|
tcx.infer_ctxt().enter(|infcx| {
|
||||||
|
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||||
|
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
|
||||||
|
let hir_id = tcx
|
||||||
|
.hir()
|
||||||
|
.local_def_id_to_hir_id(self.body.source.def_id().expect_local());
|
||||||
|
let cause = || {
|
||||||
|
ObligationCause::new(
|
||||||
|
terminator.source_info.span,
|
||||||
|
hir_id,
|
||||||
|
ObligationCauseCode::ItemObligation(callee),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let normalized = infcx.partially_normalize_associated_types_in(
|
||||||
|
cause(),
|
||||||
|
param_env,
|
||||||
|
predicates,
|
||||||
|
);
|
||||||
|
|
||||||
|
for p in normalized.obligations {
|
||||||
|
fulfill_cx.register_predicate_obligation(&infcx, p);
|
||||||
|
}
|
||||||
|
for obligation in traits::predicates_for_generics(
|
||||||
|
|_, _| cause(),
|
||||||
|
self.param_env,
|
||||||
|
normalized.value,
|
||||||
|
) {
|
||||||
|
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||||
|
}
|
||||||
|
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||||
|
if !errors.is_empty() {
|
||||||
|
infcx.report_fulfillment_errors(&errors, None, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
match implsrc {
|
match implsrc {
|
||||||
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
|
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -468,7 +468,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
// RFC 2632
|
// RFC 2632
|
||||||
gated!(
|
gated!(
|
||||||
const_trait, Normal, template!(Word), WarnFollowing, const_trait_impl,
|
const_trait, Normal, template!(Word), WarnFollowing, const_trait_impl,
|
||||||
"`const` is a temporary placeholder for marking a trait that is suitable for `const` \
|
"`const_trait` is a temporary placeholder for marking a trait that is suitable for `const` \
|
||||||
`impls` and all default bodies as `const`, which may be removed or renamed in the \
|
`impls` and all default bodies as `const`, which may be removed or renamed in the \
|
||||||
future."
|
future."
|
||||||
),
|
),
|
||||||
|
|
|
@ -67,6 +67,14 @@ impl<'tcx> PredicateObligation<'tcx> {
|
||||||
recursion_depth: self.recursion_depth,
|
recursion_depth: self.recursion_depth,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
|
||||||
|
self.param_env = self.param_env.without_const();
|
||||||
|
if let ty::PredicateKind::Trait(trait_pred) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
|
||||||
|
self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Trait(trait_pred.without_const())));
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TraitObligation<'tcx> {
|
impl<'tcx> TraitObligation<'tcx> {
|
||||||
|
|
|
@ -861,6 +861,11 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||||
(BoundConstness::ConstIfConst, hir::Constness::NotConst) => false,
|
(BoundConstness::ConstIfConst, hir::Constness::NotConst) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn without_const(mut self) -> Self {
|
||||||
|
self.constness = BoundConstness::NotConst;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PolyTraitPredicate<'tcx> {
|
impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||||
|
|
|
@ -192,6 +192,28 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||||
|
let tcx = self.tcx;
|
||||||
|
if let hir::ItemKind::Impl(hir::Impl {
|
||||||
|
constness: hir::Constness::Const,
|
||||||
|
of_trait: Some(trait_ref),
|
||||||
|
..
|
||||||
|
}) = item.kind
|
||||||
|
{
|
||||||
|
let def_id = trait_ref.trait_def_id().unwrap();
|
||||||
|
let source_map = tcx.sess.source_map();
|
||||||
|
if !tcx.has_attr(def_id, sym::const_trait) {
|
||||||
|
tcx.sess
|
||||||
|
.struct_span_err(
|
||||||
|
source_map.guess_head_span(item.span),
|
||||||
|
"const `impl`s must be for traits marked with `#[const_trait]`",
|
||||||
|
)
|
||||||
|
.span_note(
|
||||||
|
source_map.guess_head_span(tcx.def_span(def_id)),
|
||||||
|
"this trait must be annotated with `#[const_trait]`",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
intravisit::walk_item(self, item);
|
intravisit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ pub fn predicates_for_generics<'tcx>(
|
||||||
move |(idx, (predicate, span))| Obligation {
|
move |(idx, (predicate, span))| Obligation {
|
||||||
cause: cause(idx, span),
|
cause: cause(idx, span),
|
||||||
recursion_depth: 0,
|
recursion_depth: 0,
|
||||||
param_env: param_env,
|
param_env,
|
||||||
predicate,
|
predicate,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -392,7 +392,8 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||||
// `i32: Clone`
|
// `i32: Clone`
|
||||||
// `i32: Copy`
|
// `i32: Copy`
|
||||||
// ]
|
// ]
|
||||||
let obligations = self.nominal_obligations(data.item_def_id, data.substs);
|
// Projection types do not require const predicates.
|
||||||
|
let obligations = self.nominal_obligations_without_const(data.item_def_id, data.substs);
|
||||||
self.out.extend(obligations);
|
self.out.extend(obligations);
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
|
@ -1406,7 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, code, span, def_id, substs))]
|
#[instrument(level = "debug", skip(self, code, span, substs))]
|
||||||
fn add_required_obligations_with_code(
|
fn add_required_obligations_with_code(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -1414,15 +1414,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
|
code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
|
||||||
) {
|
) {
|
||||||
|
let param_env = self.param_env;
|
||||||
|
|
||||||
|
let remap = match self.tcx.def_kind(def_id) {
|
||||||
|
// Associated consts have `Self: ~const Trait` bounds that should be satisfiable when
|
||||||
|
// `Self: Trait` is satisfied because it does not matter whether the impl is `const`.
|
||||||
|
// Therefore we have to remap the param env here to be non-const.
|
||||||
|
hir::def::DefKind::AssocConst => true,
|
||||||
|
hir::def::DefKind::AssocFn
|
||||||
|
if self.tcx.def_kind(self.tcx.parent(def_id)) == hir::def::DefKind::Trait =>
|
||||||
|
{
|
||||||
|
// N.B.: All callsites to this function involve checking a path expression.
|
||||||
|
//
|
||||||
|
// When instantiating a trait method as a function item, it does not actually matter whether
|
||||||
|
// the trait is `const` or not, or whether `where T: ~const Tr` needs to be satisfied as
|
||||||
|
// `const`. If we were to introduce instantiating trait methods as `const fn`s, we would
|
||||||
|
// check that after this, either via a bound `where F: ~const FnOnce` or when coercing to a
|
||||||
|
// `const fn` pointer.
|
||||||
|
//
|
||||||
|
// FIXME(fee1-dead) FIXME(const_trait_impl): update this doc when trait methods can satisfy
|
||||||
|
// `~const FnOnce` or can be coerced to `const fn` pointer.
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
|
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
|
||||||
|
|
||||||
for obligation in traits::predicates_for_generics(
|
for mut obligation in traits::predicates_for_generics(
|
||||||
|idx, predicate_span| {
|
|idx, predicate_span| {
|
||||||
traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
|
traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
|
||||||
},
|
},
|
||||||
self.param_env,
|
param_env,
|
||||||
bounds,
|
bounds,
|
||||||
) {
|
) {
|
||||||
|
if remap {
|
||||||
|
obligation = obligation.without_const(self.tcx);
|
||||||
|
}
|
||||||
self.register_predicate(obligation);
|
self.register_predicate(obligation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,7 +366,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
|
|
||||||
let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
|
let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
let fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
let mut fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
||||||
let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
|
let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
|
||||||
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
||||||
<dyn AstConv<'_>>::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None)
|
<dyn AstConv<'_>>::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None)
|
||||||
|
@ -459,7 +459,11 @@ fn typeck_with_fallback<'tcx>(
|
||||||
|
|
||||||
// Closure and generator analysis may run after fallback
|
// Closure and generator analysis may run after fallback
|
||||||
// because they don't constrain other type variables.
|
// because they don't constrain other type variables.
|
||||||
|
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
|
||||||
|
let prev_constness = fcx.param_env.constness();
|
||||||
|
fcx.param_env = fcx.param_env.without_const();
|
||||||
fcx.closure_analyze(body);
|
fcx.closure_analyze(body);
|
||||||
|
fcx.param_env = fcx.param_env.with_constness(prev_constness);
|
||||||
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
|
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
|
||||||
// Before the generator analysis, temporary scopes shall be marked to provide more
|
// Before the generator analysis, temporary scopes shall be marked to provide more
|
||||||
// precise information on types to be captured.
|
// precise information on types to be captured.
|
||||||
|
|
|
@ -2037,8 +2037,7 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
|
||||||
* could have a method to project a Pin<T> from it.
|
* could have a method to project a Pin<T> from it.
|
||||||
*/
|
*/
|
||||||
#[stable(feature = "pin", since = "1.33.0")]
|
#[stable(feature = "pin", since = "1.33.0")]
|
||||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
|
||||||
impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static {}
|
|
||||||
|
|
||||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||||
impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>
|
impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>
|
||||||
|
|
|
@ -107,6 +107,7 @@ impl fmt::Display for AllocError {
|
||||||
///
|
///
|
||||||
/// [*currently allocated*]: #currently-allocated-memory
|
/// [*currently allocated*]: #currently-allocated-memory
|
||||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
#[const_trait]
|
||||||
pub unsafe trait Allocator {
|
pub unsafe trait Allocator {
|
||||||
/// Attempts to allocate a block of memory.
|
/// Attempts to allocate a block of memory.
|
||||||
///
|
///
|
||||||
|
|
|
@ -154,6 +154,7 @@
|
||||||
/// [`String`]: ../../std/string/struct.String.html
|
/// [`String`]: ../../std/string/struct.String.html
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_diagnostic_item = "Borrow"]
|
#[rustc_diagnostic_item = "Borrow"]
|
||||||
|
#[const_trait]
|
||||||
pub trait Borrow<Borrowed: ?Sized> {
|
pub trait Borrow<Borrowed: ?Sized> {
|
||||||
/// Immutably borrows from an owned value.
|
/// Immutably borrows from an owned value.
|
||||||
///
|
///
|
||||||
|
@ -184,6 +185,7 @@ pub trait Borrow<Borrowed: ?Sized> {
|
||||||
/// an underlying type by providing a mutable reference. See [`Borrow<T>`]
|
/// an underlying type by providing a mutable reference. See [`Borrow<T>`]
|
||||||
/// for more information on borrowing as another type.
|
/// for more information on borrowing as another type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
|
pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
|
||||||
/// Mutably borrows from an owned value.
|
/// Mutably borrows from an owned value.
|
||||||
///
|
///
|
||||||
|
|
|
@ -204,20 +204,10 @@ use self::Ordering::*;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[doc(alias = "==")]
|
#[doc(alias = "==")]
|
||||||
#[doc(alias = "!=")]
|
#[doc(alias = "!=")]
|
||||||
#[cfg_attr(
|
#[rustc_on_unimplemented(
|
||||||
bootstrap,
|
|
||||||
rustc_on_unimplemented(
|
|
||||||
message = "can't compare `{Self}` with `{Rhs}`",
|
|
||||||
label = "no implementation for `{Self} == {Rhs}`"
|
|
||||||
)
|
|
||||||
)]
|
|
||||||
#[cfg_attr(
|
|
||||||
not(bootstrap),
|
|
||||||
rustc_on_unimplemented(
|
|
||||||
message = "can't compare `{Self}` with `{Rhs}`",
|
message = "can't compare `{Self}` with `{Rhs}`",
|
||||||
label = "no implementation for `{Self} == {Rhs}`",
|
label = "no implementation for `{Self} == {Rhs}`",
|
||||||
append_const_msg,
|
append_const_msg
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
#[rustc_diagnostic_item = "PartialEq"]
|
#[rustc_diagnostic_item = "PartialEq"]
|
||||||
|
@ -1076,20 +1066,10 @@ impl const PartialOrd for Ordering {
|
||||||
#[doc(alias = "<")]
|
#[doc(alias = "<")]
|
||||||
#[doc(alias = "<=")]
|
#[doc(alias = "<=")]
|
||||||
#[doc(alias = ">=")]
|
#[doc(alias = ">=")]
|
||||||
#[cfg_attr(
|
#[rustc_on_unimplemented(
|
||||||
bootstrap,
|
|
||||||
rustc_on_unimplemented(
|
|
||||||
message = "can't compare `{Self}` with `{Rhs}`",
|
message = "can't compare `{Self}` with `{Rhs}`",
|
||||||
label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
|
label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
|
||||||
)
|
append_const_msg
|
||||||
)]
|
|
||||||
#[cfg_attr(
|
|
||||||
not(bootstrap),
|
|
||||||
rustc_on_unimplemented(
|
|
||||||
message = "can't compare `{Self}` with `{Rhs}`",
|
|
||||||
label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
|
|
||||||
append_const_msg,
|
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
#[rustc_diagnostic_item = "PartialOrd"]
|
#[rustc_diagnostic_item = "PartialOrd"]
|
||||||
|
|
|
@ -155,6 +155,7 @@ pub const fn identity<T>(x: T) -> T {
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")]
|
||||||
|
#[const_trait]
|
||||||
pub trait AsRef<T: ?Sized> {
|
pub trait AsRef<T: ?Sized> {
|
||||||
/// Converts this type into a shared reference of the (usually inferred) input type.
|
/// Converts this type into a shared reference of the (usually inferred) input type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -197,6 +198,7 @@ pub trait AsRef<T: ?Sized> {
|
||||||
/// [`Box<T>`]: ../../std/boxed/struct.Box.html
|
/// [`Box<T>`]: ../../std/boxed/struct.Box.html
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
|
||||||
|
#[const_trait]
|
||||||
pub trait AsMut<T: ?Sized> {
|
pub trait AsMut<T: ?Sized> {
|
||||||
/// Converts this type into a mutable reference of the (usually inferred) input type.
|
/// Converts this type into a mutable reference of the (usually inferred) input type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -273,6 +275,7 @@ pub trait AsMut<T: ?Sized> {
|
||||||
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
||||||
#[rustc_diagnostic_item = "Into"]
|
#[rustc_diagnostic_item = "Into"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Into<T>: Sized {
|
pub trait Into<T>: Sized {
|
||||||
/// Converts this type into the (usually inferred) input type.
|
/// Converts this type into the (usually inferred) input type.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -368,6 +371,7 @@ pub trait Into<T>: Sized {
|
||||||
all(_Self = "&str", T = "std::string::String"),
|
all(_Self = "&str", T = "std::string::String"),
|
||||||
note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
|
note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
|
||||||
))]
|
))]
|
||||||
|
#[const_trait]
|
||||||
pub trait From<T>: Sized {
|
pub trait From<T>: Sized {
|
||||||
/// Converts to this type from the input type.
|
/// Converts to this type from the input type.
|
||||||
#[lang = "from"]
|
#[lang = "from"]
|
||||||
|
@ -392,6 +396,7 @@ pub trait From<T>: Sized {
|
||||||
/// [`Into`], see there for details.
|
/// [`Into`], see there for details.
|
||||||
#[rustc_diagnostic_item = "TryInto"]
|
#[rustc_diagnostic_item = "TryInto"]
|
||||||
#[stable(feature = "try_from", since = "1.34.0")]
|
#[stable(feature = "try_from", since = "1.34.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait TryInto<T>: Sized {
|
pub trait TryInto<T>: Sized {
|
||||||
/// The type returned in the event of a conversion error.
|
/// The type returned in the event of a conversion error.
|
||||||
#[stable(feature = "try_from", since = "1.34.0")]
|
#[stable(feature = "try_from", since = "1.34.0")]
|
||||||
|
@ -468,6 +473,7 @@ pub trait TryInto<T>: Sized {
|
||||||
/// [`try_from`]: TryFrom::try_from
|
/// [`try_from`]: TryFrom::try_from
|
||||||
#[rustc_diagnostic_item = "TryFrom"]
|
#[rustc_diagnostic_item = "TryFrom"]
|
||||||
#[stable(feature = "try_from", since = "1.34.0")]
|
#[stable(feature = "try_from", since = "1.34.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait TryFrom<T>: Sized {
|
pub trait TryFrom<T>: Sized {
|
||||||
/// The type returned in the event of a conversion error.
|
/// The type returned in the event of a conversion error.
|
||||||
#[stable(feature = "try_from", since = "1.34.0")]
|
#[stable(feature = "try_from", since = "1.34.0")]
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait Default: Sized {
|
pub trait Default: Sized {
|
||||||
/// Returns the "default value" for a type.
|
/// Returns the "default value" for a type.
|
||||||
///
|
///
|
||||||
|
|
|
@ -228,6 +228,7 @@ pub trait FromIterator<A>: Sized {
|
||||||
#[rustc_diagnostic_item = "IntoIterator"]
|
#[rustc_diagnostic_item = "IntoIterator"]
|
||||||
#[rustc_skip_array_during_method_dispatch]
|
#[rustc_skip_array_during_method_dispatch]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait IntoIterator {
|
pub trait IntoIterator {
|
||||||
/// The type of the elements being iterated over.
|
/// The type of the elements being iterated over.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
|
@ -141,6 +141,7 @@
|
||||||
#![feature(const_str_from_utf8_unchecked_mut)]
|
#![feature(const_str_from_utf8_unchecked_mut)]
|
||||||
#![feature(const_swap)]
|
#![feature(const_swap)]
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(const_try)]
|
||||||
#![feature(const_type_id)]
|
#![feature(const_type_id)]
|
||||||
#![feature(const_type_name)]
|
#![feature(const_type_name)]
|
||||||
#![feature(const_default_impls)]
|
#![feature(const_default_impls)]
|
||||||
|
|
|
@ -65,38 +65,15 @@
|
||||||
/// ```
|
/// ```
|
||||||
#[lang = "add"]
|
#[lang = "add"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(
|
#[rustc_on_unimplemented(
|
||||||
bootstrap,
|
on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
|
||||||
rustc_on_unimplemented(
|
on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
|
||||||
on(
|
|
||||||
all(_Self = "{integer}", Rhs = "{float}"),
|
|
||||||
message = "cannot add a float to an integer",
|
|
||||||
),
|
|
||||||
on(
|
|
||||||
all(_Self = "{float}", Rhs = "{integer}"),
|
|
||||||
message = "cannot add an integer to a float",
|
|
||||||
),
|
|
||||||
message = "cannot add `{Rhs}` to `{Self}`",
|
|
||||||
label = "no implementation for `{Self} + {Rhs}`"
|
|
||||||
)
|
|
||||||
)]
|
|
||||||
#[cfg_attr(
|
|
||||||
not(bootstrap),
|
|
||||||
rustc_on_unimplemented(
|
|
||||||
on(
|
|
||||||
all(_Self = "{integer}", Rhs = "{float}"),
|
|
||||||
message = "cannot add a float to an integer",
|
|
||||||
),
|
|
||||||
on(
|
|
||||||
all(_Self = "{float}", Rhs = "{integer}"),
|
|
||||||
message = "cannot add an integer to a float",
|
|
||||||
),
|
|
||||||
message = "cannot add `{Rhs}` to `{Self}`",
|
message = "cannot add `{Rhs}` to `{Self}`",
|
||||||
label = "no implementation for `{Self} + {Rhs}`",
|
label = "no implementation for `{Self} + {Rhs}`",
|
||||||
append_const_msg,
|
append_const_msg
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "+")]
|
#[doc(alias = "+")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Add<Rhs = Self> {
|
pub trait Add<Rhs = Self> {
|
||||||
/// The resulting type after applying the `+` operator.
|
/// The resulting type after applying the `+` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -201,9 +178,11 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "cannot subtract `{Rhs}` from `{Self}`",
|
message = "cannot subtract `{Rhs}` from `{Self}`",
|
||||||
label = "no implementation for `{Self} - {Rhs}`"
|
label = "no implementation for `{Self} - {Rhs}`",
|
||||||
|
append_const_msg
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "-")]
|
#[doc(alias = "-")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Sub<Rhs = Self> {
|
pub trait Sub<Rhs = Self> {
|
||||||
/// The resulting type after applying the `-` operator.
|
/// The resulting type after applying the `-` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -333,6 +312,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
label = "no implementation for `{Self} * {Rhs}`"
|
label = "no implementation for `{Self} * {Rhs}`"
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "*")]
|
#[doc(alias = "*")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Mul<Rhs = Self> {
|
pub trait Mul<Rhs = Self> {
|
||||||
/// The resulting type after applying the `*` operator.
|
/// The resulting type after applying the `*` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -466,6 +446,7 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
label = "no implementation for `{Self} / {Rhs}`"
|
label = "no implementation for `{Self} / {Rhs}`"
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "/")]
|
#[doc(alias = "/")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Div<Rhs = Self> {
|
pub trait Div<Rhs = Self> {
|
||||||
/// The resulting type after applying the `/` operator.
|
/// The resulting type after applying the `/` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -568,6 +549,7 @@ div_impl_float! { f32 f64 }
|
||||||
label = "no implementation for `{Self} % {Rhs}`"
|
label = "no implementation for `{Self} % {Rhs}`"
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "%")]
|
#[doc(alias = "%")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Rem<Rhs = Self> {
|
pub trait Rem<Rhs = Self> {
|
||||||
/// The resulting type after applying the `%` operator.
|
/// The resulting type after applying the `%` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -682,6 +664,7 @@ rem_impl_float! { f32 f64 }
|
||||||
#[lang = "neg"]
|
#[lang = "neg"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[doc(alias = "-")]
|
#[doc(alias = "-")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Neg {
|
pub trait Neg {
|
||||||
/// The resulting type after applying the `-` operator.
|
/// The resulting type after applying the `-` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -755,6 +738,7 @@ neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "+")]
|
#[doc(alias = "+")]
|
||||||
#[doc(alias = "+=")]
|
#[doc(alias = "+=")]
|
||||||
|
#[const_trait]
|
||||||
pub trait AddAssign<Rhs = Self> {
|
pub trait AddAssign<Rhs = Self> {
|
||||||
/// Performs the `+=` operation.
|
/// Performs the `+=` operation.
|
||||||
///
|
///
|
||||||
|
@ -822,6 +806,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "-")]
|
#[doc(alias = "-")]
|
||||||
#[doc(alias = "-=")]
|
#[doc(alias = "-=")]
|
||||||
|
#[const_trait]
|
||||||
pub trait SubAssign<Rhs = Self> {
|
pub trait SubAssign<Rhs = Self> {
|
||||||
/// Performs the `-=` operation.
|
/// Performs the `-=` operation.
|
||||||
///
|
///
|
||||||
|
@ -880,6 +865,7 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "*")]
|
#[doc(alias = "*")]
|
||||||
#[doc(alias = "*=")]
|
#[doc(alias = "*=")]
|
||||||
|
#[const_trait]
|
||||||
pub trait MulAssign<Rhs = Self> {
|
pub trait MulAssign<Rhs = Self> {
|
||||||
/// Performs the `*=` operation.
|
/// Performs the `*=` operation.
|
||||||
///
|
///
|
||||||
|
@ -938,6 +924,7 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "/")]
|
#[doc(alias = "/")]
|
||||||
#[doc(alias = "/=")]
|
#[doc(alias = "/=")]
|
||||||
|
#[const_trait]
|
||||||
pub trait DivAssign<Rhs = Self> {
|
pub trait DivAssign<Rhs = Self> {
|
||||||
/// Performs the `/=` operation.
|
/// Performs the `/=` operation.
|
||||||
///
|
///
|
||||||
|
@ -999,6 +986,7 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "%")]
|
#[doc(alias = "%")]
|
||||||
#[doc(alias = "%=")]
|
#[doc(alias = "%=")]
|
||||||
|
#[const_trait]
|
||||||
pub trait RemAssign<Rhs = Self> {
|
pub trait RemAssign<Rhs = Self> {
|
||||||
/// Performs the `%=` operation.
|
/// Performs the `%=` operation.
|
||||||
///
|
///
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#[lang = "not"]
|
#[lang = "not"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[doc(alias = "!")]
|
#[doc(alias = "!")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Not {
|
pub trait Not {
|
||||||
/// The resulting type after applying the `!` operator.
|
/// The resulting type after applying the `!` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -143,6 +144,7 @@ impl const Not for ! {
|
||||||
message = "no implementation for `{Self} & {Rhs}`",
|
message = "no implementation for `{Self} & {Rhs}`",
|
||||||
label = "no implementation for `{Self} & {Rhs}`"
|
label = "no implementation for `{Self} & {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait BitAnd<Rhs = Self> {
|
pub trait BitAnd<Rhs = Self> {
|
||||||
/// The resulting type after applying the `&` operator.
|
/// The resulting type after applying the `&` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -244,6 +246,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||||
message = "no implementation for `{Self} | {Rhs}`",
|
message = "no implementation for `{Self} | {Rhs}`",
|
||||||
label = "no implementation for `{Self} | {Rhs}`"
|
label = "no implementation for `{Self} | {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait BitOr<Rhs = Self> {
|
pub trait BitOr<Rhs = Self> {
|
||||||
/// The resulting type after applying the `|` operator.
|
/// The resulting type after applying the `|` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -345,6 +348,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||||
message = "no implementation for `{Self} ^ {Rhs}`",
|
message = "no implementation for `{Self} ^ {Rhs}`",
|
||||||
label = "no implementation for `{Self} ^ {Rhs}`"
|
label = "no implementation for `{Self} ^ {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait BitXor<Rhs = Self> {
|
pub trait BitXor<Rhs = Self> {
|
||||||
/// The resulting type after applying the `^` operator.
|
/// The resulting type after applying the `^` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -445,6 +449,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||||
message = "no implementation for `{Self} << {Rhs}`",
|
message = "no implementation for `{Self} << {Rhs}`",
|
||||||
label = "no implementation for `{Self} << {Rhs}`"
|
label = "no implementation for `{Self} << {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait Shl<Rhs = Self> {
|
pub trait Shl<Rhs = Self> {
|
||||||
/// The resulting type after applying the `<<` operator.
|
/// The resulting type after applying the `<<` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -564,6 +569,7 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
|
||||||
message = "no implementation for `{Self} >> {Rhs}`",
|
message = "no implementation for `{Self} >> {Rhs}`",
|
||||||
label = "no implementation for `{Self} >> {Rhs}`"
|
label = "no implementation for `{Self} >> {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait Shr<Rhs = Self> {
|
pub trait Shr<Rhs = Self> {
|
||||||
/// The resulting type after applying the `>>` operator.
|
/// The resulting type after applying the `>>` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -692,6 +698,7 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
||||||
message = "no implementation for `{Self} &= {Rhs}`",
|
message = "no implementation for `{Self} &= {Rhs}`",
|
||||||
label = "no implementation for `{Self} &= {Rhs}`"
|
label = "no implementation for `{Self} &= {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait BitAndAssign<Rhs = Self> {
|
pub trait BitAndAssign<Rhs = Self> {
|
||||||
/// Performs the `&=` operation.
|
/// Performs the `&=` operation.
|
||||||
///
|
///
|
||||||
|
@ -764,6 +771,7 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||||
message = "no implementation for `{Self} |= {Rhs}`",
|
message = "no implementation for `{Self} |= {Rhs}`",
|
||||||
label = "no implementation for `{Self} |= {Rhs}`"
|
label = "no implementation for `{Self} |= {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait BitOrAssign<Rhs = Self> {
|
pub trait BitOrAssign<Rhs = Self> {
|
||||||
/// Performs the `|=` operation.
|
/// Performs the `|=` operation.
|
||||||
///
|
///
|
||||||
|
@ -836,6 +844,7 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||||
message = "no implementation for `{Self} ^= {Rhs}`",
|
message = "no implementation for `{Self} ^= {Rhs}`",
|
||||||
label = "no implementation for `{Self} ^= {Rhs}`"
|
label = "no implementation for `{Self} ^= {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait BitXorAssign<Rhs = Self> {
|
pub trait BitXorAssign<Rhs = Self> {
|
||||||
/// Performs the `^=` operation.
|
/// Performs the `^=` operation.
|
||||||
///
|
///
|
||||||
|
@ -906,6 +915,7 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||||
message = "no implementation for `{Self} <<= {Rhs}`",
|
message = "no implementation for `{Self} <<= {Rhs}`",
|
||||||
label = "no implementation for `{Self} <<= {Rhs}`"
|
label = "no implementation for `{Self} <<= {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait ShlAssign<Rhs = Self> {
|
pub trait ShlAssign<Rhs = Self> {
|
||||||
/// Performs the `<<=` operation.
|
/// Performs the `<<=` operation.
|
||||||
///
|
///
|
||||||
|
@ -989,6 +999,7 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
||||||
message = "no implementation for `{Self} >>= {Rhs}`",
|
message = "no implementation for `{Self} >>= {Rhs}`",
|
||||||
label = "no implementation for `{Self} >>= {Rhs}`"
|
label = "no implementation for `{Self} >>= {Rhs}`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub trait ShrAssign<Rhs = Self> {
|
pub trait ShrAssign<Rhs = Self> {
|
||||||
/// Performs the `>>=` operation.
|
/// Performs the `>>=` operation.
|
||||||
///
|
///
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#[doc(alias = "&*")]
|
#[doc(alias = "&*")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_diagnostic_item = "Deref"]
|
#[rustc_diagnostic_item = "Deref"]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait Deref {
|
pub trait Deref {
|
||||||
/// The resulting type after dereferencing.
|
/// The resulting type after dereferencing.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -169,6 +170,7 @@ impl<T: ?Sized> const Deref for &mut T {
|
||||||
#[lang = "deref_mut"]
|
#[lang = "deref_mut"]
|
||||||
#[doc(alias = "*")]
|
#[doc(alias = "*")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait DerefMut: Deref {
|
pub trait DerefMut: Deref {
|
||||||
/// Mutably dereferences the value.
|
/// Mutably dereferences the value.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
|
@ -134,6 +134,7 @@
|
||||||
/// these types cannot have destructors.
|
/// these types cannot have destructors.
|
||||||
#[lang = "drop"]
|
#[lang = "drop"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Drop {
|
pub trait Drop {
|
||||||
/// Executes the destructor for this type.
|
/// Executes the destructor for this type.
|
||||||
///
|
///
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
)]
|
)]
|
||||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||||
#[must_use = "closures are lazy and do nothing unless called"]
|
#[must_use = "closures are lazy and do nothing unless called"]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait Fn<Args>: FnMut<Args> {
|
pub trait Fn<Args>: FnMut<Args> {
|
||||||
/// Performs the call operation.
|
/// Performs the call operation.
|
||||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||||
|
@ -158,6 +159,7 @@ pub trait Fn<Args>: FnMut<Args> {
|
||||||
)]
|
)]
|
||||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||||
#[must_use = "closures are lazy and do nothing unless called"]
|
#[must_use = "closures are lazy and do nothing unless called"]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait FnMut<Args>: FnOnce<Args> {
|
pub trait FnMut<Args>: FnOnce<Args> {
|
||||||
/// Performs the call operation.
|
/// Performs the call operation.
|
||||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||||
|
@ -237,6 +239,7 @@ pub trait FnMut<Args>: FnOnce<Args> {
|
||||||
)]
|
)]
|
||||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||||
#[must_use = "closures are lazy and do nothing unless called"]
|
#[must_use = "closures are lazy and do nothing unless called"]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait FnOnce<Args> {
|
pub trait FnOnce<Args> {
|
||||||
/// The returned type after the call operator is used.
|
/// The returned type after the call operator is used.
|
||||||
#[lang = "fn_once_output"]
|
#[lang = "fn_once_output"]
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#[doc(alias = "]")]
|
#[doc(alias = "]")]
|
||||||
#[doc(alias = "[")]
|
#[doc(alias = "[")]
|
||||||
#[doc(alias = "[]")]
|
#[doc(alias = "[]")]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait Index<Idx: ?Sized> {
|
pub trait Index<Idx: ?Sized> {
|
||||||
/// The returned type after indexing.
|
/// The returned type after indexing.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -163,6 +164,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
|
||||||
#[doc(alias = "[")]
|
#[doc(alias = "[")]
|
||||||
#[doc(alias = "]")]
|
#[doc(alias = "]")]
|
||||||
#[doc(alias = "[]")]
|
#[doc(alias = "[]")]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
|
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
|
||||||
/// Performs the mutable indexing (`container[index]`) operation.
|
/// Performs the mutable indexing (`container[index]`) operation.
|
||||||
///
|
///
|
||||||
|
|
|
@ -128,6 +128,7 @@ use crate::ops::ControlFlow;
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "?")]
|
#[doc(alias = "?")]
|
||||||
#[lang = "Try"]
|
#[lang = "Try"]
|
||||||
|
#[const_trait]
|
||||||
pub trait Try: FromResidual {
|
pub trait Try: FromResidual {
|
||||||
/// The type of the value produced by `?` when *not* short-circuiting.
|
/// The type of the value produced by `?` when *not* short-circuiting.
|
||||||
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
||||||
|
@ -384,6 +385,7 @@ pub trait Try: FromResidual {
|
||||||
))]
|
))]
|
||||||
#[rustc_diagnostic_item = "FromResidual"]
|
#[rustc_diagnostic_item = "FromResidual"]
|
||||||
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
||||||
|
#[const_trait]
|
||||||
pub trait FromResidual<R = <Self as Try>::Residual> {
|
pub trait FromResidual<R = <Self as Try>::Residual> {
|
||||||
/// Constructs the type from a compatible `Residual` type.
|
/// Constructs the type from a compatible `Residual` type.
|
||||||
///
|
///
|
||||||
|
|
|
@ -160,6 +160,7 @@ mod private_slice_index {
|
||||||
message = "the type `{T}` cannot be indexed by `{Self}`",
|
message = "the type `{T}` cannot be indexed by `{Self}`",
|
||||||
label = "slice indices are of type `usize` or ranges of `usize`"
|
label = "slice indices are of type `usize` or ranges of `usize`"
|
||||||
)]
|
)]
|
||||||
|
#[const_trait]
|
||||||
pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
|
pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
|
||||||
/// The output type returned by methods.
|
/// The output type returned by methods.
|
||||||
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Func<T> {
|
trait Func<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
struct X<const N: usize = {
|
struct X<const N: usize = {
|
||||||
(||1usize)()
|
(||1usize)()
|
||||||
//~^ ERROR cannot call
|
//~^ ERROR cannot call non-const closure
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(const_trait_impl, generic_const_exprs)]
|
#![feature(const_trait_impl, generic_const_exprs)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait ConstName {
|
trait ConstName {
|
||||||
const NAME_BYTES: &'static [u8];
|
const NAME_BYTES: &'static [u8];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Trait {
|
trait Trait {
|
||||||
const N: usize;
|
const N: usize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0046]: not all trait items implemented, missing: `N`
|
error[E0046]: not all trait items implemented, missing: `N`
|
||||||
--> $DIR/issue-98629.rs:7:1
|
--> $DIR/issue-98629.rs:8:1
|
||||||
|
|
|
|
||||||
LL | const N: usize;
|
LL | const N: usize;
|
||||||
| -------------- `N` from trait
|
| -------------- `N` from trait
|
||||||
|
|
|
@ -4,13 +4,13 @@ error[E0308]: mismatched types
|
||||||
LL | = [0; (i8::MAX + 1u8) as usize];
|
LL | = [0; (i8::MAX + 1u8) as usize];
|
||||||
| ^^^ expected `i8`, found `u8`
|
| ^^^ expected `i8`, found `u8`
|
||||||
|
|
||||||
error[E0277]: cannot add `u8` to `i8`
|
error[E0277]: cannot add `u8` to `i8` in const contexts
|
||||||
--> $DIR/const-eval-overflow-3b.rs:16:20
|
--> $DIR/const-eval-overflow-3b.rs:16:20
|
||||||
|
|
|
|
||||||
LL | = [0; (i8::MAX + 1u8) as usize];
|
LL | = [0; (i8::MAX + 1u8) as usize];
|
||||||
| ^ no implementation for `i8 + u8`
|
| ^ no implementation for `i8 + u8`
|
||||||
|
|
|
|
||||||
= help: the trait `Add<u8>` is not implemented for `i8`
|
= help: the trait `~const Add<u8>` is not implemented for `i8`
|
||||||
= help: the following other types implement trait `Add<Rhs>`:
|
= help: the following other types implement trait `Add<Rhs>`:
|
||||||
<&'a f32 as Add<f32>>
|
<&'a f32 as Add<f32>>
|
||||||
<&'a f64 as Add<f64>>
|
<&'a f64 as Add<f64>>
|
||||||
|
|
|
@ -4,13 +4,13 @@ error[E0308]: mismatched types
|
||||||
LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
|
LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
|
||||||
| ^^^ expected `i8`, found `u8`
|
| ^^^ expected `i8`, found `u8`
|
||||||
|
|
||||||
error[E0277]: cannot add `u8` to `i8`
|
error[E0277]: cannot add `u8` to `i8` in const contexts
|
||||||
--> $DIR/const-eval-overflow-4b.rs:9:28
|
--> $DIR/const-eval-overflow-4b.rs:9:28
|
||||||
|
|
|
|
||||||
LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
|
LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
|
||||||
| ^ no implementation for `i8 + u8`
|
| ^ no implementation for `i8 + u8`
|
||||||
|
|
|
|
||||||
= help: the trait `Add<u8>` is not implemented for `i8`
|
= help: the trait `~const Add<u8>` is not implemented for `i8`
|
||||||
= help: the following other types implement trait `Add<Rhs>`:
|
= help: the following other types implement trait `Add<Rhs>`:
|
||||||
<&'a f32 as Add<f32>>
|
<&'a f32 as Add<f32>>
|
||||||
<&'a f64 as Add<f64>>
|
<&'a f64 as Add<f64>>
|
||||||
|
|
|
@ -3,10 +3,10 @@ const X : usize = 2;
|
||||||
const fn f(x: usize) -> usize {
|
const fn f(x: usize) -> usize {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
for i in 0..x {
|
for i in 0..x {
|
||||||
//~^ ERROR mutable references
|
//~^ ERROR cannot convert
|
||||||
//~| ERROR cannot convert
|
|
||||||
//~| ERROR cannot call non-const fn
|
|
||||||
//~| ERROR `for` is not allowed in a `const fn`
|
//~| ERROR `for` is not allowed in a `const fn`
|
||||||
|
//~| ERROR mutable references are not allowed in constant functions
|
||||||
|
//~| ERROR cannot call non-const fn
|
||||||
sum += i;
|
sum += i;
|
||||||
}
|
}
|
||||||
sum
|
sum
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
for _ in 0..5 {}
|
for _ in 0..5 {}
|
||||||
//~^ error: cannot convert
|
//~^ error: cannot call
|
||||||
//~| error: cannot call non-const fn
|
//~| error: cannot convert
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const fn foo() { (||{})() }
|
const fn foo() { (||{})() }
|
||||||
//~^ ERROR cannot call non-const closure
|
//~^ ERROR cannot call non-const closure
|
||||||
//~| ERROR erroneous constant used [const_err]
|
//~| ERROR erroneous constant
|
||||||
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
//~| WARN this was previously accepted
|
||||||
|
|
||||||
const fn bad(input: fn()) {
|
const fn bad(input: fn()) {
|
||||||
input()
|
input()
|
||||||
//~^ ERROR function pointer
|
//~^ ERROR function pointer calls are not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -7,9 +7,8 @@ struct Foo<'a> {
|
||||||
impl<'a> Foo<'a> {
|
impl<'a> Foo<'a> {
|
||||||
const fn spam(&mut self, baz: &mut Vec<u32>) {
|
const fn spam(&mut self, baz: &mut Vec<u32>) {
|
||||||
self.bar[0] = baz.len();
|
self.bar[0] = baz.len();
|
||||||
//~^ ERROR cannot call non-const fn `Vec::<u32>::len` in constant functions
|
//~^ the trait bound `Vec<usize>: ~const Index<_>` is not satisfied
|
||||||
//~| ERROR the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
|
//~| the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
|
||||||
//~| ERROR cannot call non-const operator in constant functions
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions
|
error[E0277]: the trait bound `Vec<usize>: ~const Index<_>` is not satisfied
|
||||||
--> $DIR/issue-94675.rs:9:27
|
--> $DIR/issue-94675.rs:9:9
|
||||||
|
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
LL | self.bar[0] = baz.len();
|
||||||
| ^^^^^
|
| ^^^^^^^^^^^ vector indices are of type `usize` or ranges of `usize`
|
||||||
|
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= help: the trait `~const Index<_>` is not implemented for `Vec<usize>`
|
||||||
|
note: the trait `Index<_>` is implemented for `Vec<usize>`, but that implementation is not `const`
|
||||||
|
--> $DIR/issue-94675.rs:9:9
|
||||||
|
|
|
||||||
|
LL | self.bar[0] = baz.len();
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
|
error[E0277]: the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
|
||||||
--> $DIR/issue-94675.rs:9:9
|
--> $DIR/issue-94675.rs:9:9
|
||||||
|
@ -18,21 +23,11 @@ note: the trait `IndexMut<usize>` is implemented for `Vec<usize>`, but that impl
|
||||||
|
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
LL | self.bar[0] = baz.len();
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
|
||||||
--> $DIR/issue-94675.rs:9:9
|
|
||||||
|
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
LL | impl<'a> Foo<'a> where Vec<usize>: ~const IndexMut<usize> {
|
||||||
| ^^^^^^^^^^^
|
| ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
|
||||||
note: impl defined here, but it is not `const`
|
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// gate was not enabled in libcore.
|
// gate was not enabled in libcore.
|
||||||
|
|
||||||
#![stable(feature = "core", since = "1.6.0")]
|
#![stable(feature = "core", since = "1.6.0")]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api, const_trait_impl)]
|
||||||
|
|
||||||
enum Opt<T> {
|
enum Opt<T> {
|
||||||
Some(T),
|
Some(T),
|
||||||
|
@ -14,12 +14,12 @@ enum Opt<T> {
|
||||||
impl<T> Opt<T> {
|
impl<T> Opt<T> {
|
||||||
#[rustc_const_unstable(feature = "foo", issue = "none")]
|
#[rustc_const_unstable(feature = "foo", issue = "none")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
|
const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||||
//~| ERROR destructors cannot be evaluated at compile-time
|
//~| ERROR destructors cannot be evaluated at compile-time
|
||||||
match self {
|
match self {
|
||||||
Opt::Some(t) => t,
|
Opt::Some(t) => t,
|
||||||
Opt::None => f(), //~ ERROR E0015
|
Opt::None => f(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,21 @@
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
|
||||||
--> $DIR/unstable-const-fn-in-libcore.rs:22:26
|
|
||||||
|
|
|
||||||
LL | Opt::None => f(),
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn unwrap_or_else<F: FnOnce() -> T + ~const std::ops::FnOnce<()>>(self, f: F) -> T {
|
|
||||||
| +++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
error[E0493]: destructors cannot be evaluated at compile-time
|
||||||
--> $DIR/unstable-const-fn-in-libcore.rs:17:53
|
--> $DIR/unstable-const-fn-in-libcore.rs:17:60
|
||||||
|
|
|
|
||||||
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
|
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||||
| ^ constant functions cannot evaluate destructors
|
| ^ constant functions cannot evaluate destructors
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - value is dropped here
|
| - value is dropped here
|
||||||
|
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
error[E0493]: destructors cannot be evaluated at compile-time
|
||||||
--> $DIR/unstable-const-fn-in-libcore.rs:17:47
|
--> $DIR/unstable-const-fn-in-libcore.rs:17:54
|
||||||
|
|
|
|
||||||
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
|
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||||
| ^^^^ constant functions cannot evaluate destructors
|
| ^^^^ constant functions cannot evaluate destructors
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - value is dropped here
|
| - value is dropped here
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0493.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -15,13 +15,13 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it
|
||||||
LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻²
|
LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻²
|
||||||
| ~
|
| ~
|
||||||
|
|
||||||
error[E0277]: cannot subtract `{integer}` from `{float}`
|
error[E0277]: cannot subtract `{integer}` from `{float}` in const contexts
|
||||||
--> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
|
--> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
|
||||||
|
|
|
|
||||||
LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
|
LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
|
||||||
| ^ no implementation for `{float} - {integer}`
|
| ^ no implementation for `{float} - {integer}`
|
||||||
|
|
|
|
||||||
= help: the trait `Sub<{integer}>` is not implemented for `{float}`
|
= help: the trait `~const Sub<{integer}>` is not implemented for `{float}`
|
||||||
= help: the following other types implement trait `Sub<Rhs>`:
|
= help: the following other types implement trait `Sub<Rhs>`:
|
||||||
<&'a f32 as Sub<f32>>
|
<&'a f32 as Sub<f32>>
|
||||||
<&'a f64 as Sub<f64>>
|
<&'a f64 as Sub<f64>>
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct A;
|
||||||
struct B;
|
struct B;
|
||||||
|
|
||||||
static S: &'static B = &A;
|
static S: &'static B = &A;
|
||||||
//~^ ERROR cannot perform deref coercion on `A` in statics
|
//~^ ERROR the trait bound
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,15 @@
|
||||||
error[E0015]: cannot perform deref coercion on `A` in statics
|
error[E0277]: the trait bound `A: Deref` is not satisfied
|
||||||
|
--> $DIR/issue-25901.rs:4:24
|
||||||
|
|
|
||||||
|
LL | static S: &'static B = &A;
|
||||||
|
| ^^ the trait `~const Deref` is not implemented for `A`
|
||||||
|
|
|
||||||
|
note: the trait `Deref` is implemented for `A`, but that implementation is not `const`
|
||||||
--> $DIR/issue-25901.rs:4:24
|
--> $DIR/issue-25901.rs:4:24
|
||||||
|
|
|
|
||||||
LL | static S: &'static B = &A;
|
LL | static S: &'static B = &A;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
= note: attempting to deref into `B`
|
|
||||||
note: deref defined here
|
|
||||||
--> $DIR/issue-25901.rs:10:5
|
|
||||||
|
|
|
||||||
LL | type Target = B;
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
note: impl defined here, but it is not `const`
|
|
||||||
--> $DIR/issue-25901.rs:9:1
|
|
||||||
|
|
|
||||||
LL | impl Deref for A {
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
|
||||||
= note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0015`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -7,13 +7,13 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new();
|
||||||
= note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
|
= note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
|
||||||
= help: add `#![feature(const_for)]` to the crate attributes to enable
|
= help: add `#![feature(const_for)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0277]: cannot add `()` to `{integer}`
|
error[E0277]: cannot add `()` to `{integer}` in const contexts
|
||||||
--> $DIR/issue-50582.rs:2:18
|
--> $DIR/issue-50582.rs:2:18
|
||||||
|
|
|
|
||||||
LL | Vec::<[(); 1 + for x in 0..1 {}]>::new();
|
LL | Vec::<[(); 1 + for x in 0..1 {}]>::new();
|
||||||
| ^ no implementation for `{integer} + ()`
|
| ^ no implementation for `{integer} + ()`
|
||||||
|
|
|
|
||||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
= help: the trait `~const Add<()>` is not implemented for `{integer}`
|
||||||
= help: the following other types implement trait `Add<Rhs>`:
|
= help: the following other types implement trait `Add<Rhs>`:
|
||||||
<&'a f32 as Add<f32>>
|
<&'a f32 as Add<f32>>
|
||||||
<&'a f64 as Add<f64>>
|
<&'a f64 as Add<f64>>
|
||||||
|
|
|
@ -9,6 +9,6 @@ fn main() {
|
||||||
[(); { for _ in 0usize.. {}; 0}];
|
[(); { for _ in 0usize.. {}; 0}];
|
||||||
//~^ ERROR `for` is not allowed in a `const`
|
//~^ ERROR `for` is not allowed in a `const`
|
||||||
//~| ERROR cannot convert
|
//~| ERROR cannot convert
|
||||||
//~| ERROR mutable references are not allowed in constants
|
//~| ERROR mutable references
|
||||||
//~| ERROR cannot call non-const fn
|
//~| ERROR cannot call
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ impl std::ops::Add for NonConstAdd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Foo {
|
trait Foo {
|
||||||
type Bar: ~const std::ops::Add;
|
type Bar: ~const std::ops::Add;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +20,7 @@ impl const Foo for NonConstAdd {
|
||||||
//~^ ERROR: cannot add `NonConstAdd` to `NonConstAdd` in const contexts
|
//~^ ERROR: cannot add `NonConstAdd` to `NonConstAdd` in const contexts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Baz {
|
trait Baz {
|
||||||
type Qux: std::ops::Add;
|
type Qux: std::ops::Add;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
error[E0277]: cannot add `NonConstAdd` to `NonConstAdd` in const contexts
|
error[E0277]: cannot add `NonConstAdd` to `NonConstAdd` in const contexts
|
||||||
--> $DIR/assoc-type.rs:18:16
|
--> $DIR/assoc-type.rs:19:16
|
||||||
|
|
|
|
||||||
LL | type Bar = NonConstAdd;
|
LL | type Bar = NonConstAdd;
|
||||||
| ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
|
| ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
|
||||||
|
|
|
|
||||||
= help: the trait `~const Add` is not implemented for `NonConstAdd`
|
= help: the trait `~const Add` is not implemented for `NonConstAdd`
|
||||||
note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const`
|
note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const`
|
||||||
--> $DIR/assoc-type.rs:18:16
|
--> $DIR/assoc-type.rs:19:16
|
||||||
|
|
|
|
||||||
LL | type Bar = NonConstAdd;
|
LL | type Bar = NonConstAdd;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
note: required by a bound in `Foo::Bar`
|
note: required by a bound in `Foo::Bar`
|
||||||
--> $DIR/assoc-type.rs:14:15
|
--> $DIR/assoc-type.rs:15:15
|
||||||
|
|
|
|
||||||
LL | type Bar: ~const std::ops::Add;
|
LL | type Bar: ~const std::ops::Add;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
|
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait MyTrait {
|
pub trait MyTrait {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
fn func();
|
fn func();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
pub trait Plus {
|
pub trait Plus {
|
||||||
fn plus(self, rhs: Self) -> Self;
|
fn plus(self, rhs: Self) -> Self;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +24,6 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
|
||||||
pub const fn add_u32(a: u32, b: u32) -> u32 {
|
pub const fn add_u32(a: u32, b: u32) -> u32 {
|
||||||
a.plus(b)
|
a.plus(b)
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR the trait bound
|
||||||
//~| ERROR cannot call non-const fn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,24 +1,19 @@
|
||||||
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
|
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
|
||||||
--> $DIR/call-const-trait-method-fail.rs:24:7
|
--> $DIR/call-const-trait-method-fail.rs:25:7
|
||||||
|
|
|
|
||||||
LL | a.plus(b)
|
LL | a.plus(b)
|
||||||
| ^^^^^^^ the trait `~const Plus` is not implemented for `u32`
|
| ^^^^ the trait `~const Plus` is not implemented for `u32`
|
||||||
|
|
|
|
||||||
note: the trait `Plus` is implemented for `u32`, but that implementation is not `const`
|
note: the trait `Plus` is implemented for `u32`, but that implementation is not `const`
|
||||||
--> $DIR/call-const-trait-method-fail.rs:24:7
|
--> $DIR/call-const-trait-method-fail.rs:25:7
|
||||||
|
|
|
|
||||||
LL | a.plus(b)
|
LL | a.plus(b)
|
||||||
| ^^^^^^^
|
| ^^^^
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
|
|
||||||
--> $DIR/call-const-trait-method-fail.rs:24:7
|
|
||||||
|
|
|
|
||||||
LL | a.plus(b)
|
LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: ~const Plus {
|
||||||
| ^^^^^^^
|
| ++++++++++++++++++++++
|
||||||
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ impl const PartialEq for Int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
pub trait Plus {
|
pub trait Plus {
|
||||||
fn plus(self, rhs: Self) -> Self;
|
fn plus(self, rhs: Self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait MyPartialEq {
|
trait MyPartialEq {
|
||||||
fn eq(&self, other: &Self) -> bool;
|
fn eq(&self, other: &Self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
#[const_trait]
|
||||||
trait T {
|
trait T {
|
||||||
fn foo();
|
fn foo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0015]: cannot call non-const fn `non_const` in constant functions
|
error[E0015]: cannot call non-const fn `non_const` in constant functions
|
||||||
--> $DIR/const-check-fns-in-const-impl.rs:11:16
|
--> $DIR/const-check-fns-in-const-impl.rs:12:16
|
||||||
|
|
|
|
||||||
LL | fn foo() { non_const() }
|
LL | fn foo() { non_const() }
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
@ -48,6 +48,7 @@ mod t {
|
||||||
pub struct HasConstDrop(pub ConstDrop);
|
pub struct HasConstDrop(pub ConstDrop);
|
||||||
pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize);
|
pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize);
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
pub trait SomeTrait {
|
pub trait SomeTrait {
|
||||||
fn foo();
|
fn foo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
|
|
||||||
const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword
|
const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Bar {}
|
trait Bar {}
|
||||||
|
|
||||||
const impl<T: Foo> Bar for T {} //~ ERROR: expected identifier, found keyword
|
const impl<T: Foo> Bar for T {} //~ ERROR: expected identifier, found keyword
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: expected identifier, found keyword `impl`
|
error: expected identifier, found keyword `impl`
|
||||||
--> $DIR/const-impl-recovery.rs:5:7
|
--> $DIR/const-impl-recovery.rs:6:7
|
||||||
|
|
|
|
||||||
LL | const impl Foo for i32 {}
|
LL | const impl Foo for i32 {}
|
||||||
| ^^^^ expected identifier, found keyword
|
| ^^^^ expected identifier, found keyword
|
||||||
|
@ -11,7 +11,7 @@ LL + impl const Foo for i32 {}
|
||||||
|
|
|
|
||||||
|
|
||||||
error: expected identifier, found keyword `impl`
|
error: expected identifier, found keyword `impl`
|
||||||
--> $DIR/const-impl-recovery.rs:9:7
|
--> $DIR/const-impl-recovery.rs:11:7
|
||||||
|
|
|
|
||||||
LL | const impl<T: Foo> Bar for T {}
|
LL | const impl<T: Foo> Bar for T {}
|
||||||
| ^^^^ expected identifier, found keyword
|
| ^^^^ expected identifier, found keyword
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
pub trait A {}
|
||||||
|
//~^ NOTE: this trait must be annotated with `#[const_trait]`
|
||||||
|
|
||||||
|
impl const A for () {}
|
||||||
|
//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]`
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error: const `impl`s must be for traits marked with `#[const_trait]`
|
||||||
|
--> $DIR/const-impl-requires-const-trait.rs:6:1
|
||||||
|
|
|
||||||
|
LL | impl const A for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: this trait must be annotated with `#[const_trait]`
|
||||||
|
--> $DIR/const-impl-requires-const-trait.rs:3:1
|
||||||
|
|
|
||||||
|
LL | pub trait A {}
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: fatal error triggered by #[rustc_error]
|
error: fatal error triggered by #[rustc_error]
|
||||||
--> $DIR/feature-gate.rs:13:1
|
--> $DIR/feature-gate.rs:14:1
|
||||||
|
|
|
|
||||||
LL | fn main() {}
|
LL | fn main() {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
#[const_trait] //[stock]~ ERROR `const_trait` is a temporary placeholder
|
||||||
trait T {}
|
trait T {}
|
||||||
impl const T for S {}
|
impl const T for S {}
|
||||||
//[stock]~^ ERROR const trait impls are experimental
|
//[stock]~^ ERROR const trait impls are experimental
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0658]: const trait impls are experimental
|
error[E0658]: const trait impls are experimental
|
||||||
--> $DIR/feature-gate.rs:9:6
|
--> $DIR/feature-gate.rs:10:6
|
||||||
|
|
|
|
||||||
LL | impl const T for S {}
|
LL | impl const T for S {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -7,6 +7,15 @@ LL | impl const T for S {}
|
||||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future.
|
||||||
|
--> $DIR/feature-gate.rs:8:1
|
||||||
|
|
|
||||||
|
LL | #[const_trait]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||||
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
pub trait MyTrait {
|
pub trait MyTrait {
|
||||||
fn method(&self) -> Option<()>;
|
fn method(&self) -> Option<()>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0658]: `?` is not allowed in a `const fn`
|
error[E0658]: `?` is not allowed in a `const fn`
|
||||||
--> $DIR/hir-const-check.rs:11:9
|
--> $DIR/hir-const-check.rs:12:9
|
||||||
|
|
|
|
||||||
LL | Some(())?;
|
LL | Some(())?;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait A {}
|
trait A {}
|
||||||
|
#[const_trait]
|
||||||
trait B {}
|
trait B {}
|
||||||
|
|
||||||
impl const A for S {}
|
impl const A for S {}
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub trait IndexMut where Self: Index {
|
||||||
|
|
||||||
impl Index for () { type Output = (); }
|
impl Index for () { type Output = (); }
|
||||||
|
|
||||||
|
#[cfg(not(any(nn, yn)))]
|
||||||
impl const IndexMut for <() as Index>::Output {
|
impl const IndexMut for <() as Index>::Output {
|
||||||
const C: <Self as Index>::Output = ();
|
const C: <Self as Index>::Output = ();
|
||||||
type Assoc = <Self as Index>::Output;
|
type Assoc = <Self as Index>::Output;
|
||||||
|
@ -24,6 +25,15 @@ impl const IndexMut for <() as Index>::Output {
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(nn, yn))]
|
||||||
|
impl IndexMut for <() as Index>::Output {
|
||||||
|
const C: <Self as Index>::Output = ();
|
||||||
|
type Assoc = <Self as Index>::Output;
|
||||||
|
fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
||||||
|
where <Self as Index>::Output:,
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
const C: <() as Index>::Output = ();
|
const C: <() as Index>::Output = ();
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
pub trait Super {}
|
pub trait Super {}
|
||||||
|
#[const_trait]
|
||||||
pub trait Sub: Super {}
|
pub trait Sub: Super {}
|
||||||
|
|
||||||
impl<A> const Super for &A where A: ~const Super {}
|
impl<A> const Super for &A where A: ~const Super {}
|
||||||
|
|
12
src/test/ui/rfc-2632-const-trait-impl/nested-closure.rs
Normal file
12
src/test/ui/rfc-2632-const-trait-impl/nested-closure.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(const_trait_impl, once_cell)]
|
||||||
|
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
static EXTERN_FLAGS: LazyLock<String> = LazyLock::new(|| {
|
||||||
|
let x = || String::new();
|
||||||
|
x()
|
||||||
|
});
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Convert<T> {
|
trait Convert<T> {
|
||||||
fn to(self) -> T;
|
fn to(self) -> T;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// check-pass
|
||||||
|
pub struct S<T, F: FnOnce() -> T = fn() -> T> {
|
||||||
|
f: F,
|
||||||
|
x: Option<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, F: FnOnce() -> T> S<T, F> {
|
||||||
|
pub const fn new(f: F) -> Self {
|
||||||
|
Self { f, x: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
static LOCKED_CALLSITES: S<Foo> = S::new(Default::default);
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,8 +1,10 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Foo {
|
trait Foo {
|
||||||
fn a(&self);
|
fn a(&self);
|
||||||
}
|
}
|
||||||
|
#[const_trait]
|
||||||
trait Bar: ~const Foo {}
|
trait Bar: ~const Foo {}
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
|
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
|
||||||
--> $DIR/super-traits-fail.rs:13:12
|
--> $DIR/super-traits-fail.rs:15:12
|
||||||
|
|
|
|
||||||
LL | impl const Bar for S {}
|
LL | impl const Bar for S {}
|
||||||
| ^^^ the trait `~const Foo` is not implemented for `S`
|
| ^^^ the trait `~const Foo` is not implemented for `S`
|
||||||
|
|
|
|
||||||
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
|
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
|
||||||
--> $DIR/super-traits-fail.rs:13:12
|
--> $DIR/super-traits-fail.rs:15:12
|
||||||
|
|
|
|
||||||
LL | impl const Bar for S {}
|
LL | impl const Bar for S {}
|
||||||
| ^^^
|
| ^^^
|
||||||
note: required by a bound in `Bar`
|
note: required by a bound in `Bar`
|
||||||
--> $DIR/super-traits-fail.rs:6:12
|
--> $DIR/super-traits-fail.rs:8:12
|
||||||
|
|
|
|
||||||
LL | trait Bar: ~const Foo {}
|
LL | trait Bar: ~const Foo {}
|
||||||
| ^^^^^^^^^^ required by this bound in `Bar`
|
| ^^^^^^^^^^ required by this bound in `Bar`
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Foo {
|
trait Foo {
|
||||||
fn a(&self);
|
fn a(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Bar: ~const Foo {}
|
trait Bar: ~const Foo {}
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Like trait-where-clause.rs, but we are calling from a const context.
|
||||||
|
// Checking the validity of traits' where clauses happen at a later stage.
|
||||||
|
// (`rustc_const_eval` instead of `rustc_typeck`) Therefore one file as a
|
||||||
|
// test is not enough.
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
trait Bar {}
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn a();
|
||||||
|
fn b() where Self: ~const Bar;
|
||||||
|
fn c<T: ~const Bar>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn test1<T: ~const Foo + Bar>() {
|
||||||
|
T::a();
|
||||||
|
T::b();
|
||||||
|
//~^ ERROR the trait bound
|
||||||
|
T::c::<T>();
|
||||||
|
//~^ ERROR the trait bound
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn test2<T: ~const Foo + ~const Bar>() {
|
||||||
|
T::a();
|
||||||
|
T::b();
|
||||||
|
T::c::<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,35 @@
|
||||||
|
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
||||||
|
--> $DIR/trait-where-clause-const.rs:17:5
|
||||||
|
|
|
||||||
|
LL | T::b();
|
||||||
|
| ^^^^^^ the trait `~const Bar` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
|
||||||
|
--> $DIR/trait-where-clause-const.rs:17:5
|
||||||
|
|
|
||||||
|
LL | T::b();
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
|
||||||
|
| ++++++++++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
||||||
|
--> $DIR/trait-where-clause-const.rs:19:5
|
||||||
|
|
|
||||||
|
LL | T::c::<T>();
|
||||||
|
| ^^^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
|
||||||
|
--> $DIR/trait-where-clause-const.rs:19:5
|
||||||
|
|
|
||||||
|
LL | T::c::<T>();
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
|
||||||
|
| ++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
trait Bar {
|
trait Bar {
|
||||||
fn bar() -> u8;
|
fn bar() -> u8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ trait Foo {
|
||||||
fn c<T: ~const Bar>();
|
fn c<T: ~const Bar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn test1<T: ~const Foo + Bar>() {
|
fn test1<T: Foo>() {
|
||||||
T::a();
|
T::a();
|
||||||
T::b();
|
T::b();
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR the trait bound
|
||||||
|
@ -16,21 +16,7 @@ const fn test1<T: ~const Foo + Bar>() {
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR the trait bound
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn test2<T: ~const Foo + ~const Bar>() {
|
fn test2<T: Foo + Bar>() {
|
||||||
T::a();
|
|
||||||
T::b();
|
|
||||||
T::c::<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test3<T: Foo>() {
|
|
||||||
T::a();
|
|
||||||
T::b();
|
|
||||||
//~^ ERROR the trait bound
|
|
||||||
T::c::<T>();
|
|
||||||
//~^ ERROR the trait bound
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test4<T: Foo + Bar>() {
|
|
||||||
T::a();
|
T::a();
|
||||||
T::b();
|
T::b();
|
||||||
T::c::<T>();
|
T::c::<T>();
|
||||||
|
|
|
@ -1,47 +1,5 @@
|
||||||
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
|
||||||
--> $DIR/trait-where-clause.rs:13:5
|
|
||||||
|
|
|
||||||
LL | T::b();
|
|
||||||
| ^^^^ the trait `~const Bar` is not implemented for `T`
|
|
||||||
|
|
|
||||||
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
|
|
||||||
--> $DIR/trait-where-clause.rs:13:5
|
|
||||||
|
|
|
||||||
LL | T::b();
|
|
||||||
| ^^^^
|
|
||||||
note: required by a bound in `Foo::b`
|
|
||||||
--> $DIR/trait-where-clause.rs:7:24
|
|
||||||
|
|
|
||||||
LL | fn b() where Self: ~const Bar;
|
|
||||||
| ^^^^^^^^^^ required by this bound in `Foo::b`
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
|
||||||
--> $DIR/trait-where-clause.rs:15:12
|
|
||||||
|
|
|
||||||
LL | T::c::<T>();
|
|
||||||
| ^ the trait `~const Bar` is not implemented for `T`
|
|
||||||
|
|
|
||||||
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
|
|
||||||
--> $DIR/trait-where-clause.rs:15:12
|
|
||||||
|
|
|
||||||
LL | T::c::<T>();
|
|
||||||
| ^
|
|
||||||
note: required by a bound in `Foo::c`
|
|
||||||
--> $DIR/trait-where-clause.rs:8:13
|
|
||||||
|
|
|
||||||
LL | fn c<T: ~const Bar>();
|
|
||||||
| ^^^^^^^^^^ required by this bound in `Foo::c`
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: Bar` is not satisfied
|
error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||||
--> $DIR/trait-where-clause.rs:27:5
|
--> $DIR/trait-where-clause.rs:13:5
|
||||||
|
|
|
|
||||||
LL | T::b();
|
LL | T::b();
|
||||||
| ^^^^ the trait `Bar` is not implemented for `T`
|
| ^^^^ the trait `Bar` is not implemented for `T`
|
||||||
|
@ -53,11 +11,11 @@ LL | fn b() where Self: ~const Bar;
|
||||||
| ^^^^^^^^^^ required by this bound in `Foo::b`
|
| ^^^^^^^^^^ required by this bound in `Foo::b`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | fn test3<T: Foo + Bar>() {
|
LL | fn test1<T: Foo + Bar>() {
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: Bar` is not satisfied
|
error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||||
--> $DIR/trait-where-clause.rs:29:12
|
--> $DIR/trait-where-clause.rs:15:12
|
||||||
|
|
|
|
||||||
LL | T::c::<T>();
|
LL | T::c::<T>();
|
||||||
| ^ the trait `Bar` is not implemented for `T`
|
| ^ the trait `Bar` is not implemented for `T`
|
||||||
|
@ -69,9 +27,9 @@ LL | fn c<T: ~const Bar>();
|
||||||
| ^^^^^^^^^^ required by this bound in `Foo::c`
|
| ^^^^^^^^^^ required by this bound in `Foo::c`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | fn test3<T: Foo + Bar>() {
|
LL | fn test1<T: Foo + Bar>() {
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -19,6 +19,7 @@ impl Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "stable", since = "1.0.0")]
|
#[stable(feature = "stable", since = "1.0.0")]
|
||||||
|
#[const_trait]
|
||||||
pub trait Bar {
|
pub trait Bar {
|
||||||
#[stable(feature = "stable", since = "1.0.0")]
|
#[stable(feature = "stable", since = "1.0.0")]
|
||||||
fn fun();
|
fn fun();
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | pub const fn foo() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: implementation has missing const stability attribute
|
error: implementation has missing const stability attribute
|
||||||
--> $DIR/missing-const-stability.rs:27:1
|
--> $DIR/missing-const-stability.rs:28:1
|
||||||
|
|
|
|
||||||
LL | / impl const Bar for Foo {
|
LL | / impl const Bar for Foo {
|
||||||
LL | |
|
LL | |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue