Rollup merge of #99704 - fee1-dead-contrib:add_self_tilde_const_trait, r=oli-obk
Add `Self: ~const Trait` to traits with `#[const_trait]` r? `@oli-obk`
This commit is contained in:
commit
28b44ff5d4
30 changed files with 199 additions and 209 deletions
|
@ -23,8 +23,8 @@ use rustc_trait_selection::traits::SelectionContext;
|
||||||
|
|
||||||
use super::ConstCx;
|
use super::ConstCx;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrComparisonErr, RawPtrToIntErr,
|
MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr,
|
||||||
StaticAccessErr, TransientMutBorrowErr, TransientMutBorrowErrRaw,
|
TransientMutBorrowErr, TransientMutBorrowErrRaw,
|
||||||
};
|
};
|
||||||
use crate::util::{call_kind, CallDesugaringKind, CallKind};
|
use crate::util::{call_kind, CallDesugaringKind, CallKind};
|
||||||
|
|
||||||
|
@ -654,10 +654,10 @@ pub struct RawPtrComparison;
|
||||||
impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
|
impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
|
||||||
fn build_error(
|
fn build_error(
|
||||||
&self,
|
&self,
|
||||||
ccx: &ConstCx<'_, 'tcx>,
|
_: &ConstCx<'_, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||||
ccx.tcx.sess.create_err(RawPtrComparisonErr { span })
|
span_bug!(span, "raw ptr comparison should already be caught in the trait system");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -829,6 +829,14 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||||
pub fn is_const_if_const(self) -> bool {
|
pub fn is_const_if_const(self) -> bool {
|
||||||
self.constness == BoundConstness::ConstIfConst
|
self.constness == BoundConstness::ConstIfConst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_constness_satisfied_by(self, constness: hir::Constness) -> bool {
|
||||||
|
match (self.constness, constness) {
|
||||||
|
(BoundConstness::NotConst, _)
|
||||||
|
| (BoundConstness::ConstIfConst, hir::Constness::Const) => true,
|
||||||
|
(BoundConstness::ConstIfConst, hir::Constness::NotConst) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PolyTraitPredicate<'tcx> {
|
impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||||
|
|
|
@ -2556,7 +2556,7 @@ define_print_and_forward_display! {
|
||||||
|
|
||||||
ty::TraitPredicate<'tcx> {
|
ty::TraitPredicate<'tcx> {
|
||||||
p!(print(self.trait_ref.self_ty()), ": ");
|
p!(print(self.trait_ref.self_ty()), ": ");
|
||||||
if let ty::BoundConstness::ConstIfConst = self.constness {
|
if let ty::BoundConstness::ConstIfConst = self.constness && cx.tcx().features().const_trait_impl {
|
||||||
p!("~const ");
|
p!("~const ");
|
||||||
}
|
}
|
||||||
p!(print(self.trait_ref.print_only_trait_path()))
|
p!(print(self.trait_ref.print_only_trait_path()))
|
||||||
|
|
|
@ -666,7 +666,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
} else if !suggested {
|
} else if !suggested {
|
||||||
// Can't show anything else useful, try to find similar impls.
|
// Can't show anything else useful, try to find similar impls.
|
||||||
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
|
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
|
||||||
if !self.report_similar_impl_candidates(
|
if !self.report_similar_impl_candidates(
|
||||||
impl_candidates,
|
impl_candidates,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
@ -701,7 +701,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
let trait_ref = trait_pred.to_poly_trait_ref();
|
let trait_ref = trait_pred.to_poly_trait_ref();
|
||||||
let impl_candidates =
|
let impl_candidates =
|
||||||
self.find_similar_impl_candidates(trait_ref);
|
self.find_similar_impl_candidates(trait_pred);
|
||||||
self.report_similar_impl_candidates(
|
self.report_similar_impl_candidates(
|
||||||
impl_candidates,
|
impl_candidates,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
@ -1325,7 +1325,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
|
||||||
|
|
||||||
fn find_similar_impl_candidates(
|
fn find_similar_impl_candidates(
|
||||||
&self,
|
&self,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
) -> Vec<ImplCandidate<'tcx>>;
|
) -> Vec<ImplCandidate<'tcx>>;
|
||||||
|
|
||||||
fn report_similar_impl_candidates(
|
fn report_similar_impl_candidates(
|
||||||
|
@ -1694,18 +1694,22 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
fn find_similar_impl_candidates(
|
fn find_similar_impl_candidates(
|
||||||
&self,
|
&self,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
) -> Vec<ImplCandidate<'tcx>> {
|
) -> Vec<ImplCandidate<'tcx>> {
|
||||||
self.tcx
|
self.tcx
|
||||||
.all_impls(trait_ref.def_id())
|
.all_impls(trait_pred.def_id())
|
||||||
.filter_map(|def_id| {
|
.filter_map(|def_id| {
|
||||||
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative {
|
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative
|
||||||
|
|| !trait_pred
|
||||||
|
.skip_binder()
|
||||||
|
.is_constness_satisfied_by(self.tcx.constness(def_id))
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let imp = self.tcx.impl_trait_ref(def_id).unwrap();
|
let imp = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||||
|
|
||||||
self.fuzzy_match_tys(trait_ref.skip_binder().self_ty(), imp.self_ty(), false)
|
self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false)
|
||||||
.map(|similarity| ImplCandidate { trait_ref: imp, similarity })
|
.map(|similarity| ImplCandidate { trait_ref: imp, similarity })
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -2090,10 +2090,17 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
|
||||||
// from the trait itself that *shouldn't* be shown as the source of
|
// from the trait itself that *shouldn't* be shown as the source of
|
||||||
// an obligation and instead be skipped. Otherwise we'd use
|
// an obligation and instead be skipped. Otherwise we'd use
|
||||||
// `tcx.def_span(def_id);`
|
// `tcx.def_span(def_id);`
|
||||||
|
|
||||||
|
let constness = if tcx.has_attr(def_id, sym::const_trait) {
|
||||||
|
ty::BoundConstness::ConstIfConst
|
||||||
|
} else {
|
||||||
|
ty::BoundConstness::NotConst
|
||||||
|
};
|
||||||
|
|
||||||
let span = rustc_span::DUMMY_SP;
|
let span = rustc_span::DUMMY_SP;
|
||||||
result.predicates =
|
result.predicates =
|
||||||
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
|
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
|
||||||
ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(tcx),
|
ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
|
||||||
span,
|
span,
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1503,9 +1503,10 @@ mod impls {
|
||||||
// & pointers
|
// & pointers
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A
|
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
|
||||||
|
impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A
|
||||||
where
|
where
|
||||||
A: PartialEq<B>,
|
A: ~const PartialEq<B>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &&B) -> bool {
|
fn eq(&self, other: &&B) -> bool {
|
||||||
|
|
|
@ -12,16 +12,14 @@ impl True for If<true> {}
|
||||||
fn consume<T: 'static>(_val: T)
|
fn consume<T: 'static>(_val: T)
|
||||||
where
|
where
|
||||||
If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
||||||
//~^ ERROR: overly complex generic constant
|
//~^ ERROR: can't compare
|
||||||
//~| ERROR: cannot call non-const operator in constants
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test<T: 'static>()
|
fn test<T: 'static>()
|
||||||
where
|
where
|
||||||
If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
||||||
//~^ ERROR: overly complex generic constant
|
//~^ ERROR: can't compare
|
||||||
//~| ERROR: cannot call non-const operator in constants
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,53 +1,29 @@
|
||||||
error: overly complex generic constant
|
error[E0277]: can't compare `TypeId` with `_` in const contexts
|
||||||
--> $DIR/issue-90318.rs:14:8
|
--> $DIR/issue-90318.rs:14:28
|
||||||
|
|
|
|
||||||
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
||||||
| ^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^ no implementation for `TypeId == _`
|
||||||
| |
|
|
||||||
| borrowing is not supported in generic constants
|
|
||||||
|
|
|
|
||||||
= help: consider moving this anonymous constant into a `const` function
|
= help: the trait `~const PartialEq<_>` is not implemented for `TypeId`
|
||||||
= note: this operation may be supported in the future
|
note: the trait `PartialEq<_>` is implemented for `TypeId`, but that implementation is not `const`
|
||||||
|
--> $DIR/issue-90318.rs:14:28
|
||||||
error[E0015]: cannot call non-const operator in constants
|
|
||||||
--> $DIR/issue-90318.rs:14:10
|
|
||||||
|
|
|
|
||||||
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^
|
||||||
|
|
|
||||||
note: impl defined here, but it is not `const`
|
|
||||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
|
||||||
| ^^^^^^^^^
|
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
|
||||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: overly complex generic constant
|
error[E0277]: can't compare `TypeId` with `_` in const contexts
|
||||||
--> $DIR/issue-90318.rs:22:8
|
--> $DIR/issue-90318.rs:21:28
|
||||||
|
|
|
|
||||||
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
||||||
| ^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^ no implementation for `TypeId == _`
|
||||||
| |
|
|
||||||
| borrowing is not supported in generic constants
|
|
||||||
|
|
|
|
||||||
= help: consider moving this anonymous constant into a `const` function
|
= help: the trait `~const PartialEq<_>` is not implemented for `TypeId`
|
||||||
= note: this operation may be supported in the future
|
note: the trait `PartialEq<_>` is implemented for `TypeId`, but that implementation is not `const`
|
||||||
|
--> $DIR/issue-90318.rs:21:28
|
||||||
error[E0015]: cannot call non-const operator in constants
|
|
||||||
--> $DIR/issue-90318.rs:22:10
|
|
||||||
|
|
|
|
||||||
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^
|
||||||
|
|
|
||||||
note: impl defined here, but it is not `const`
|
|
||||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
|
||||||
| ^^^^^^^^^
|
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
|
||||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0015`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
// unconst and bad, will thus error in miri
|
// unconst and bad, will thus error in miri
|
||||||
const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR cannot be reliably
|
const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR can't compare
|
||||||
// unconst and bad, will thus error in miri
|
// unconst and bad, will thus error in miri
|
||||||
const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR cannot be reliably
|
const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR can't compare
|
||||||
|
|
|
@ -1,18 +1,49 @@
|
||||||
error: pointers cannot be reliably compared during const eval
|
error[E0277]: can't compare `*const i32` with `_` in const contexts
|
||||||
--> $DIR/const_raw_ptr_ops.rs:4:26
|
--> $DIR/const_raw_ptr_ops.rs:4:43
|
||||||
|
|
|
|
||||||
LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 };
|
LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^ no implementation for `*const i32 == _`
|
||||||
|
|
|
|
||||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
= help: the trait `~const PartialEq<_>` is not implemented for `*const i32`
|
||||||
|
note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const`
|
||||||
|
--> $DIR/const_raw_ptr_ops.rs:4:43
|
||||||
|
|
|
||||||
|
LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 };
|
||||||
|
| ^^
|
||||||
|
= help: the following other types implement trait `PartialEq<Rhs>`:
|
||||||
|
f32
|
||||||
|
f64
|
||||||
|
i128
|
||||||
|
i16
|
||||||
|
i32
|
||||||
|
i64
|
||||||
|
i8
|
||||||
|
isize
|
||||||
|
and 6 others
|
||||||
|
|
||||||
error: pointers cannot be reliably compared during const eval
|
error[E0277]: can't compare `*const i32` with `_` in const contexts
|
||||||
--> $DIR/const_raw_ptr_ops.rs:6:27
|
--> $DIR/const_raw_ptr_ops.rs:6:44
|
||||||
|
|
|
|
||||||
LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
|
LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^ no implementation for `*const i32 == _`
|
||||||
|
|
|
|
||||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
= help: the trait `~const PartialEq<_>` is not implemented for `*const i32`
|
||||||
|
note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const`
|
||||||
|
--> $DIR/const_raw_ptr_ops.rs:6:44
|
||||||
|
|
|
||||||
|
LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
|
||||||
|
| ^^
|
||||||
|
= help: the following other types implement trait `PartialEq<Rhs>`:
|
||||||
|
f32
|
||||||
|
f64
|
||||||
|
i128
|
||||||
|
i16
|
||||||
|
i32
|
||||||
|
i64
|
||||||
|
i8
|
||||||
|
isize
|
||||||
|
and 6 others
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
fn id<T>(t: T) -> T { t }
|
fn id<T>(t: T) -> T { t }
|
||||||
fn main() {
|
fn main() {
|
||||||
const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||||
//~^ ERROR pointers cannot be reliably compared during const eval
|
//~^ ERROR can't compare
|
||||||
println!("{}", A);
|
println!("{}", A);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
error: pointers cannot be reliably compared during const eval
|
error[E0277]: can't compare `*const ()` with `*const ()` in const contexts
|
||||||
--> $DIR/issue-25826.rs:3:30
|
--> $DIR/issue-25826.rs:3:52
|
||||||
|
|
|
|
||||||
LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ no implementation for `*const () < *const ()` and `*const () > *const ()`
|
||||||
|
|
|
|
||||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
= help: the trait `~const PartialOrd` is not implemented for `*const ()`
|
||||||
|
note: the trait `PartialOrd` is implemented for `*const ()`, but that implementation is not `const`
|
||||||
|
--> $DIR/issue-25826.rs:3:52
|
||||||
|
|
|
||||||
|
LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||||
|
| ^
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | fn main() where *const (): ~const PartialOrd {
|
||||||
|
| ++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const fn cmp(x: fn(), y: fn()) -> bool {
|
const fn cmp(x: fn(), y: fn()) -> bool {
|
||||||
unsafe { x == y }
|
unsafe { x == y }
|
||||||
//~^ ERROR pointers cannot be reliably compared
|
//~^ ERROR can't compare
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
error: pointers cannot be reliably compared during const eval
|
error[E0277]: can't compare `fn()` with `_` in const contexts
|
||||||
--> $DIR/cmp_fn_pointers.rs:2:14
|
--> $DIR/cmp_fn_pointers.rs:2:16
|
||||||
|
|
|
|
||||||
LL | unsafe { x == y }
|
LL | unsafe { x == y }
|
||||||
| ^^^^^^
|
| ^^ no implementation for `fn() == _`
|
||||||
|
|
|
|
||||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
= help: the trait `~const PartialEq<_>` is not implemented for `fn()`
|
||||||
|
note: the trait `PartialEq<_>` is implemented for `fn()`, but that implementation is not `const`
|
||||||
|
--> $DIR/cmp_fn_pointers.rs:2:16
|
||||||
|
|
|
||||||
|
LL | unsafe { x == y }
|
||||||
|
| ^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -2,14 +2,8 @@
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![allow(const_err)]
|
#![allow(const_err)]
|
||||||
|
|
||||||
// During CTFE, we prevent pointer comparison and pointer-to-int casts.
|
// During CTFE, we prevent pointer-to-int casts.
|
||||||
|
// Pointer comparisons are prevented in the trait system.
|
||||||
static CMP: () = {
|
|
||||||
let x = &0 as *const _;
|
|
||||||
let _v = x == x;
|
|
||||||
//~^ ERROR could not evaluate static initializer
|
|
||||||
//~| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
|
||||||
};
|
|
||||||
|
|
||||||
static PTR_INT_CAST: () = {
|
static PTR_INT_CAST: () = {
|
||||||
let x = &0 as *const _ as usize;
|
let x = &0 as *const _ as usize;
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
error[E0080]: could not evaluate static initializer
|
error[E0080]: could not evaluate static initializer
|
||||||
--> $DIR/ptr_arith.rs:9:14
|
--> $DIR/ptr_arith.rs:9:13
|
||||||
|
|
|
||||||
LL | let _v = x == x;
|
|
||||||
| ^^^^^^ "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
|
||||||
|
|
||||||
error[E0080]: could not evaluate static initializer
|
|
||||||
--> $DIR/ptr_arith.rs:15:13
|
|
||||||
|
|
|
|
||||||
LL | let x = &0 as *const _ as usize;
|
LL | let x = &0 as *const _ as usize;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ "exposing pointers" needs an rfc before being allowed inside constants
|
| ^^^^^^^^^^^^^^^^^^^^^^^ "exposing pointers" needs an rfc before being allowed inside constants
|
||||||
|
|
||||||
error[E0080]: could not evaluate static initializer
|
error[E0080]: could not evaluate static initializer
|
||||||
--> $DIR/ptr_arith.rs:23:14
|
--> $DIR/ptr_arith.rs:17:14
|
||||||
|
|
|
|
||||||
LL | let _v = x + 0;
|
LL | let _v = x + 0;
|
||||||
| ^ unable to turn pointer into raw bytes
|
| ^ unable to turn pointer into raw bytes
|
||||||
|
@ -19,16 +13,11 @@ LL | let _v = x + 0;
|
||||||
warning: skipping const checks
|
warning: skipping const checks
|
||||||
|
|
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/ptr_arith.rs:9:14
|
--> $DIR/ptr_arith.rs:9:13
|
||||||
|
|
|
||||||
LL | let _v = x == x;
|
|
||||||
| ^^^^^^
|
|
||||||
help: skipping check that does not even have a feature gate
|
|
||||||
--> $DIR/ptr_arith.rs:15:13
|
|
||||||
|
|
|
|
||||||
LL | let x = &0 as *const _ as usize;
|
LL | let x = &0 as *const _ as usize;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors; 1 warning emitted
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
static FOO: i32 = 42;
|
|
||||||
static BAR: i32 = 42;
|
|
||||||
|
|
||||||
static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) };
|
|
||||||
//~^ ERROR pointers cannot be reliably compared during const eval
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
error: pointers cannot be reliably compared during const eval
|
|
||||||
--> $DIR/E0395.rs:4:29
|
|
||||||
|
|
|
||||||
LL | static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]: ~const FnOnce<()>` is not satisfied
|
error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]: FnOnce<()>` is not satisfied
|
||||||
--> $DIR/const-eval-select-bad.rs:7:27
|
--> $DIR/const-eval-select-bad.rs:7:27
|
||||||
|
|
|
|
||||||
LL | const_eval_select((), || {}, || {});
|
LL | const_eval_select((), || {}, || {});
|
||||||
|
@ -19,7 +19,7 @@ note: required by a bound in `const_eval_select`
|
||||||
LL | F: ~const FnOnce<ARG, Output = RET>,
|
LL | F: ~const FnOnce<ARG, Output = RET>,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||||
|
|
||||||
error[E0277]: the trait bound `{integer}: ~const FnOnce<()>` is not satisfied
|
error[E0277]: the trait bound `{integer}: FnOnce<()>` is not satisfied
|
||||||
--> $DIR/const-eval-select-bad.rs:9:27
|
--> $DIR/const-eval-select-bad.rs:9:27
|
||||||
|
|
|
|
||||||
LL | const_eval_select((), 42, 0xDEADBEEF);
|
LL | const_eval_select((), 42, 0xDEADBEEF);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
|
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
|
||||||
*t == *t
|
*t == *t
|
||||||
//~^ ERROR can't compare
|
//~^ ERROR can't compare
|
||||||
//~| ERROR cannot call non-const
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,28 +1,16 @@
|
||||||
error[E0277]: can't compare `T` with `T` in const contexts
|
error[E0277]: can't compare `T` with `_` in const contexts
|
||||||
--> $DIR/call-generic-method-fail.rs:4:5
|
--> $DIR/call-generic-method-fail.rs:4:8
|
||||||
|
|
|
|
||||||
LL | *t == *t
|
LL | *t == *t
|
||||||
| ^^^^^^^^ no implementation for `T == T`
|
| ^^ no implementation for `T == _`
|
||||||
|
|
|
|
||||||
note: the trait `PartialEq` is implemented for `T`, but that implementation is not `const`
|
note: the trait `PartialEq<_>` is implemented for `T`, but that implementation is not `const`
|
||||||
--> $DIR/call-generic-method-fail.rs:4:5
|
--> $DIR/call-generic-method-fail.rs:4:8
|
||||||
|
|
|
|
||||||
LL | *t == *t
|
LL | *t == *t
|
||||||
| ^^^^^^^^
|
| ^^
|
||||||
|
= help: the trait `PartialEq<&B>` is implemented for `&A`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error: aborting due to previous error
|
||||||
--> $DIR/call-generic-method-fail.rs:4:5
|
|
||||||
|
|
|
||||||
LL | *t == *t
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool {
|
|
||||||
| ++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ impl const ConstDefaultFn for ConstImpl {
|
||||||
const fn test() {
|
const fn test() {
|
||||||
NonConstImpl.a();
|
NonConstImpl.a();
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR the trait bound
|
||||||
//~| ERROR cannot call non-const fn
|
|
||||||
ConstImpl.a();
|
ConstImpl.a();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,18 @@ error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satis
|
||||||
--> $DIR/const-default-method-bodies.rs:24:18
|
--> $DIR/const-default-method-bodies.rs:24:18
|
||||||
|
|
|
|
||||||
LL | NonConstImpl.a();
|
LL | NonConstImpl.a();
|
||||||
| ^^^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
| ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
||||||
|
|
|
|
||||||
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
|
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
|
||||||
--> $DIR/const-default-method-bodies.rs:24:18
|
--> $DIR/const-default-method-bodies.rs:24:18
|
||||||
|
|
|
|
||||||
LL | NonConstImpl.a();
|
LL | NonConstImpl.a();
|
||||||
| ^^^
|
| ^
|
||||||
|
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 `<NonConstImpl as ConstDefaultFn>::a` in constant functions
|
|
||||||
--> $DIR/const-default-method-bodies.rs:24:18
|
|
||||||
|
|
|
|
||||||
LL | NonConstImpl.a();
|
LL | const fn test() where NonConstImpl: ~const ConstDefaultFn {
|
||||||
| ^^^
|
| +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
|
||||||
= 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`.
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
|
||||||
--> $DIR/cross-crate.rs:15:14
|
|
||||||
|
|
|
||||||
LL | NonConst.func();
|
|
||||||
| ^^^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
|
||||||
|
|
|
||||||
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
|
||||||
--> $DIR/cross-crate.rs:15:14
|
|
||||||
|
|
|
||||||
LL | NonConst.func();
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
|
|
||||||
--> $DIR/cross-crate.rs:15:14
|
|
||||||
|
|
|
||||||
LL | NonConst.func();
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
||||||
|
--> $DIR/cross-crate.rs:17:14
|
||||||
|
|
|
||||||
|
LL | NonConst.func();
|
||||||
|
| ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||||
|
|
|
||||||
|
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
||||||
|
--> $DIR/cross-crate.rs:17:14
|
||||||
|
|
|
||||||
|
LL | NonConst.func();
|
||||||
|
| ^^^^
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait {
|
||||||
|
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,5 +1,6 @@
|
||||||
// revisions: stock gated
|
// revisions: stock gated stocknc gatednc
|
||||||
#![cfg_attr(gated, feature(const_trait_impl))]
|
// [gated] check-pass
|
||||||
|
#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))]
|
||||||
|
|
||||||
// aux-build: cross-crate.rs
|
// aux-build: cross-crate.rs
|
||||||
extern crate cross_crate;
|
extern crate cross_crate;
|
||||||
|
@ -12,10 +13,12 @@ fn non_const_context() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn const_context() {
|
const fn const_context() {
|
||||||
NonConst.func(); //~ ERROR: cannot call non-const fn
|
#[cfg(any(stocknc, gatednc))]
|
||||||
//[gated]~^ ERROR: the trait bound
|
NonConst.func();
|
||||||
|
//[stocknc]~^ ERROR: the trait bound
|
||||||
|
//[gatednc]~^^ ERROR: the trait bound
|
||||||
Const.func();
|
Const.func();
|
||||||
//[stock]~^ ERROR: cannot call non-const fn
|
//[stock]~^ ERROR: cannot call
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
|
|
||||||
--> $DIR/cross-crate.rs:15:14
|
|
||||||
|
|
|
||||||
LL | NonConst.func();
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
|
error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
|
||||||
--> $DIR/cross-crate.rs:17:11
|
--> $DIR/cross-crate.rs:20:11
|
||||||
|
|
|
|
||||||
LL | Const.func();
|
LL | Const.func();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= 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
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0015`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied
|
||||||
|
--> $DIR/cross-crate.rs:17:14
|
||||||
|
|
|
||||||
|
LL | NonConst.func();
|
||||||
|
| ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||||
|
|
|
||||||
|
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
||||||
|
--> $DIR/cross-crate.rs:17:14
|
||||||
|
|
|
||||||
|
LL | NonConst.func();
|
||||||
|
| ^^^^
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait {
|
||||||
|
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -7,7 +7,6 @@ pub trait Tr {
|
||||||
fn b(&self) {
|
fn b(&self) {
|
||||||
().a()
|
().a()
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR the trait bound
|
||||||
//~| ERROR cannot call
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,18 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
||||||
|
|
|
|
||||||
LL | ().a()
|
LL | ().a()
|
||||||
| ^^^ the trait `~const Tr` is not implemented for `()`
|
| ^ the trait `~const Tr` is not implemented for `()`
|
||||||
|
|
|
|
||||||
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
||||||
|
|
|
|
||||||
LL | ().a()
|
LL | ().a()
|
||||||
| ^^^
|
| ^
|
||||||
|
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 `<() as Tr>::a` in constant functions
|
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
|
||||||
|
|
|
|
||||||
LL | ().a()
|
LL | pub trait Tr where (): ~const Tr {
|
||||||
| ^^^
|
| +++++++++++++++++++
|
||||||
|
|
|
||||||
= 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`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue