未验证 提交 9d7166c6 编写于 作者: M Matthias Krüger 提交者: GitHub

Rollup merge of #93827 - eholk:stabilize-const_fn-features, r=wesleywiser

Stabilize const_fn_fn_ptr_basics, const_fn_trait_bound, and const_impl_trait

# Stabilization Report

This PR serves as a request for stabilization for three const evaluation features:

1. `const_fn_fn_ptr_basics`
2. `const_fn_trait_bound`
3. `const_impl_trait`

These are being stabilized together because they are relatively minor and related updates to existing functionality.

## `const_fn_fn_ptr_basics`

Allows creating, passing, and casting function pointers in a `const fn`.

The following is an example of what is now allowed:

```rust
const fn get_function() -> fn() {
    fn foo() {
        println!("Hello, World!");
    }

    foo
}
```

Casts between function pointer types are allowed, as well as transmuting from integers:

```rust
const fn get_function() -> fn() {
    unsafe {
        std::mem::transmute(0x1234usize)
    }
}
```

However, casting from a function pointer to an integer is not allowed:

```rust
const fn fn_to_usize(f: fn()) -> usize {
    f as usize  //~ pointers cannot be cast to integers during const eval
}
```

Calling function pointers is also not allowed.

```rust
const fn call_fn_ptr(f: fn()) {
    f() //~ function pointers are not allowed in const fn
}
```

### Test Coverage

The following tests include code that exercises this feature:

- `src/test/ui/consts/issue-37550.rs`
- `src/test/ui/consts/issue-46553.rs`
- `src/test/ui/consts/issue-56164.rs`
- `src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs`
- `src/test/ui/consts/min_const_fn/cast_fn.rs`
- `src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs`

## `const_fn_trait_bound`

Allows trait bounds in `const fn`. Additionally, this feature allows creating and passing `dyn Trait` objects.

Examples such as the following are allowed by this feature:

```rust
const fn do_thing<T: Foo>(_x: &T) {
    // ...
}
```

Previously only `Sized` was allowed as a trait bound.

There is no way to call methods from the trait because trait methods cannot currently be marked as const. Allowing trait bounds in const functions does allow the const function to use the trait's associated types and constants.

This feature also allowes `dyn Trait` types. These work equivalently to non-const code. Similar to other pointers in const code, the value of a `dyn Trait` pointer cannot be observed.

Note that due to https://github.com/rust-lang/rust/issues/90912, it was already possible to do the example above as follows:

```rust
const fn do_thing<T>(_x: &T) where (T,): Foo {
    // ...
}
```

### Test Coverage

The following tests include code that exercises `const_fn_trait_bound`:

- `src/test/ui/consts/const-fn.rs`
- `src/test/ui/consts/issue-88071.rs`
- `src/test/ui/consts/min_const_fn/min_const_fn.rs`
- `src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs`
- `src/test/ui/nll/issue-55825-const-fn.rs`
- Many of the tests in `src/test/ui/rfc-2632-const-trait-impl/` also exercise this feature.

## `const_impl_trait`

Allows argument and return position `impl Trait` in a `const fn`, such as in the following example:

```rust
const fn do_thing(x: impl Foo) -> impl Foo {
    x
}
```

Similar to generic parameters and function pointers, this allows the creation of such opaque types, but not doing anything with them beyond accessing associated types and constants.

### Test Coverage

The following tests exercise this feature:

- `src/test/ui/type-alias-impl-trait/issue-53096.rs`
- `src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs`

## Documentation

These features are documented along with the other const evaluation features in the Rust Reference at https://doc.rust-lang.org/stable/reference/const_eval.html.

There is a PR that updates this documentation to reflect the capabilities enabled by these features at https://github.com/rust-lang/reference/pull/1166.

Tracking issues: #57563, #63997, #93706
......@@ -230,8 +230,6 @@ pub fn check_body(&mut self) {
}
}
self.check_item_predicates();
for (idx, local) in body.local_decls.iter_enumerated() {
// Handle the return place below.
if idx == RETURN_PLACE || local.internal {
......@@ -358,83 +356,11 @@ fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>, local: Local) {
match *ty.kind() {
ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)),
ty::Opaque(..) => self.check_op(ops::ty::ImplTrait),
ty::FnPtr(..) => self.check_op(ops::ty::FnPtr(kind)),
ty::Dynamic(preds, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
ty::ExistentialPredicate::AutoTrait(_)
| ty::ExistentialPredicate::Projection(_) => {
self.check_op(ops::ty::DynTrait(kind))
}
ty::ExistentialPredicate::Trait(trait_ref) => {
if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() {
self.check_op(ops::ty::DynTrait(kind))
}
}
}
}
}
_ => {}
}
}
}
fn check_item_predicates(&mut self) {
let ConstCx { tcx, .. } = *self.ccx;
let mut current = self.def_id().to_def_id();
loop {
let predicates = tcx.predicates_of(current);
for (predicate, _) in predicates.predicates {
match predicate.kind().skip_binder() {
ty::PredicateKind::RegionOutlives(_)
| ty::PredicateKind::TypeOutlives(_)
| ty::PredicateKind::WellFormed(_)
| ty::PredicateKind::Projection(_)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
ty::PredicateKind::ObjectSafe(_) => {
bug!("object safe predicate on function: {:#?}", predicate)
}
ty::PredicateKind::ClosureKind(..) => {
bug!("closure kind predicate on function: {:#?}", predicate)
}
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
bug!("subtype/coerce predicate on function: {:#?}", predicate)
}
ty::PredicateKind::Trait(pred) => {
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
continue;
}
match pred.self_ty().kind() {
ty::Param(p) => {
let generics = tcx.generics_of(current);
let def = generics.type_param(p, tcx);
let span = tcx.def_span(def.def_id);
// These are part of the function signature, so treat them like
// arguments when determining importance.
let kind = LocalKind::Arg;
self.check_op_spanned(ops::ty::TraitBound(kind), span);
}
// other kinds of bounds are either tautologies
// or cause errors in other passes
_ => continue,
}
}
}
}
match predicates.parent {
Some(parent) => current = parent,
None => break,
}
}
}
fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) {
match self.const_kind() {
// In a const fn all borrows are transient or point to the places given via
......@@ -613,7 +539,9 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
),
_,
_,
) => self.check_op(ops::FnPtrCast),
) => {
// Nothing to do here. Function pointer casts are allowed now.
}
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
// Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur
......
......@@ -355,31 +355,6 @@ fn build_error(
}
}
#[derive(Debug)]
pub struct FnPtrCast;
impl<'tcx> NonConstOp<'tcx> for FnPtrCast {
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_fn_ptr_basics)
}
}
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_fn_ptr_basics,
span,
&format!("function pointer casts are not allowed in {}s", ccx.const_kind()),
)
}
}
#[derive(Debug)]
pub struct Generator(pub hir::GeneratorKind);
impl<'tcx> NonConstOp<'tcx> for Generator {
......@@ -820,167 +795,4 @@ fn build_error(
)
}
}
#[derive(Debug)]
pub struct FnPtr(pub mir::LocalKind);
impl<'tcx> NonConstOp<'tcx> for FnPtr {
fn importance(&self) -> DiagnosticImportance {
match self.0 {
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
DiagnosticImportance::Primary
}
}
}
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_fn_ptr_basics)
}
}
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_fn_ptr_basics,
span,
&format!("function pointers cannot appear in {}s", ccx.const_kind()),
)
}
}
#[derive(Debug)]
pub struct ImplTrait;
impl<'tcx> NonConstOp<'tcx> for ImplTrait {
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
Status::Unstable(sym::const_impl_trait)
}
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_impl_trait,
span,
&format!("`impl Trait` is not allowed in {}s", ccx.const_kind()),
)
}
}
#[derive(Debug)]
pub struct TraitBound(pub mir::LocalKind);
impl<'tcx> NonConstOp<'tcx> for TraitBound {
fn importance(&self) -> DiagnosticImportance {
match self.0 {
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
DiagnosticImportance::Primary
}
}
}
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_trait_bound)
}
}
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_trait_bound,
span,
"trait bounds other than `Sized` on const fn parameters are unstable",
);
match ccx.fn_sig() {
Some(fn_sig) if !fn_sig.span.contains(span) => {
err.span_label(fn_sig.span, "function declared as const here");
}
_ => {}
}
err
}
}
#[derive(Debug)]
pub struct DynTrait(pub mir::LocalKind);
impl<'tcx> NonConstOp<'tcx> for DynTrait {
fn importance(&self) -> DiagnosticImportance {
match self.0 {
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
DiagnosticImportance::Primary
}
}
}
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_trait_bound)
}
}
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_trait_bound,
span,
"trait objects in const fn are unstable",
);
match ccx.fn_sig() {
Some(fn_sig) if !fn_sig.span.contains(span) => {
err.span_label(fn_sig.span, "function declared as const here");
}
_ => {}
}
err
}
}
/// A trait bound with the `?const Trait` opt-out
#[derive(Debug)]
pub struct TraitBoundNotConst;
impl<'tcx> NonConstOp<'tcx> for TraitBoundNotConst {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_trait_bound_opt_out)
}
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_trait_bound_opt_out,
span,
"`?const Trait` syntax is unstable",
)
}
}
}
......@@ -86,6 +86,10 @@
(accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
/// Allows calling constructor functions in `const fn`.
(accepted, const_constructor, "1.40.0", Some(61456), None),
/// Allows using and casting function pointers in a `const fn`.
(accepted, const_fn_fn_ptr_basics, "1.61.0", Some(57563), None),
/// Allows trait bounds in `const fn`.
(accepted, const_fn_trait_bound, "1.61.0", Some(93706), None),
/// Allows calling `transmute` in const fn
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
/// Allows accessing fields of unions inside `const` functions.
......@@ -96,6 +100,8 @@
(accepted, const_generics_defaults, "1.59.0", Some(44580), None),
/// Allows the use of `if` and `match` in constants.
(accepted, const_if_match, "1.46.0", Some(49146), None),
/// Allows argument and return position `impl Trait` in a `const fn`.
(accepted, const_impl_trait, "1.61.0", Some(77463), None),
/// Allows indexing into constant arrays.
(accepted, const_indexing, "1.26.0", Some(29947), None),
/// Allows let bindings, assignments and destructuring in `const` functions and constants.
......
......@@ -338,14 +338,8 @@ pub fn set(&self, features: &mut Features, span: Span) {
(active, const_extern_fn, "1.40.0", Some(64926), None),
/// Allows basic arithmetic on floating point types in a `const fn`.
(active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
/// Allows using and casting function pointers in a `const fn`.
(active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
/// Allows trait bounds in `const fn`.
(active, const_fn_trait_bound, "1.53.0", Some(93706), None),
/// Allows `for _ in _` loops in const contexts.
(active, const_for, "1.56.0", Some(87575), None),
/// Allows argument and return position `impl Trait` in a `const fn`.
(active, const_impl_trait, "1.48.0", Some(77463), None),
/// Allows using `&mut` in constant functions.
(active, const_mut_refs, "1.41.0", Some(57349), None),
/// Be more precise when looking for live drops in a const context.
......
......@@ -140,7 +140,7 @@
#![feature(box_syntax)]
#![feature(cfg_sanitize)]
#![feature(const_deref)]
#![feature(const_fn_trait_bound)]
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
#![feature(const_mut_refs)]
#![feature(const_ptr_write)]
#![feature(const_precise_live_drops)]
......
......@@ -158,9 +158,9 @@
#![feature(cfg_target_has_atomic)]
#![feature(cfg_target_has_atomic_equal_alignment)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_fn_fn_ptr_basics)]
#![feature(const_fn_trait_bound)]
#![feature(const_impl_trait)]
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
#![cfg_attr(bootstrap, feature(const_impl_trait))]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_refs_to_cell)]
......
......@@ -20,8 +20,8 @@
#![feature(rustc_allow_const_fn_unstable)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(const_fn_trait_bound)]
#![feature(const_fn_fn_ptr_basics)]
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
#![feature(allow_internal_unstable)]
#![feature(decl_macro)]
#![feature(extern_types)]
......
......@@ -242,8 +242,8 @@
#![feature(char_internals)]
#![feature(concat_bytes)]
#![feature(concat_idents)]
#![feature(const_fn_fn_ptr_basics)]
#![feature(const_fn_trait_bound)]
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
#![feature(const_format_args)]
#![feature(const_io_structs)]
#![feature(const_ip)]
......
#![feature(const_fn_trait_bound)]
// Regression test related to issue 88434
const _CONST: &() = &f(&|_| {});
......
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-minimal-example.rs:10:5
--> $DIR/issue-88434-minimal-example.rs:9:5
|
LL | const _CONST: &() = &f(&|_| {});
| ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:4:22
| ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:3:22
...
LL | panic!()
| ^^^^^^^^
| |
| the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5
| inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:4:25: 4:31]>` at $SRC_DIR/std/src/panic.rs:LL:COL
| the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:9:5
| inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:31]>` at $SRC_DIR/std/src/panic.rs:LL:COL
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
......
#![feature(const_fn_trait_bound)]
// Regression test for issue 88434
const _CONST: &[u8] = &f(&[], |_| {});
......
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
--> $DIR/issue-88434-removal-index-should-be-less.rs:9:5
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:4:24
| -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:3:24
...
LL | panic!()
| ^^^^^^^^
| |
| the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5
| inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:4:31: 4:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL
| the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:9:5
| inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL
|
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
......
#![feature(const_fn_trait_bound, generic_const_exprs)]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
trait _Contains<T> {
......
#![feature(const_fn_trait_bound, generic_const_exprs)]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
trait MiniTypeId {
......
// Crate that exports a const fn. Used for testing cross-crate.
#![feature(const_fn_fn_ptr_basics)]
#![crate_type="rlib"]
pub const fn foo() -> usize { 22 }
......
#![allow(unused)]
#![feature(const_fn_trait_bound, const_trait_impl, inline_const, negative_impls)]
#![feature(const_trait_impl, inline_const, negative_impls)]
const fn f<T: ~const Drop>(x: T) {}
......
......@@ -10,23 +10,11 @@ help: skipping check that does not even have a feature gate
|
LL | X_CONST(x)
| ^^^^^^^^^^
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/const_fn_ptr.rs:18:14
|
LL | const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
| ^
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/const_fn_ptr.rs:19:5
|
LL | x(y)
| ^
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr.rs:19:5
|
LL | x(y)
| ^^^^
error: `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine
error: aborting due to previous error; 1 warning emitted
warning: 1 warning emitted
......@@ -12,16 +12,6 @@ LL | assert_eq!(Z, 4);
warning: skipping const checks
|
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/const_fn_ptr_fail2.rs:11:14
|
LL | const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
| ^
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/const_fn_ptr_fail2.rs:12:5
|
LL | x(y)
| ^
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr_fail2.rs:12:5
|
......
// issue-49296: Unsafe shenigans in constants can result in missing errors
#![feature(const_fn_trait_bound)]
use std::mem::transmute;
const fn wat(x: u64) -> &'static u64 {
......
error[E0080]: evaluation of constant value failed
--> $DIR/issue-49296.rs:11:16
--> $DIR/issue-49296.rs:9:16
|
LL | const X: u64 = *wat(42);
| ^^^^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
......
// check-pass
#![feature(const_fn_fn_ptr_basics)]
const fn nested(x: (for<'a> fn(&'a ()), String)) -> (fn(&'static ()), String) {
x
......
......@@ -2,8 +2,6 @@
const extern "C" fn unsize(x: &[u8; 3]) -> &[u8] { x }
const unsafe extern "C" fn closure() -> fn() { || {} }
//~^ ERROR function pointer
//~| ERROR function pointer cast
const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
//~^ ERROR floating point arithmetic
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
......
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/const-extern-fn-min-const-fn.rs:4:41
|
LL | const unsafe extern "C" fn closure() -> fn() { || {} }
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/const-extern-fn-min-const-fn.rs:4:48
|
LL | const unsafe extern "C" fn closure() -> fn() { || {} }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const-extern-fn-min-const-fn.rs:7:42
--> $DIR/const-extern-fn-min-const-fn.rs:5:42
|
LL | const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
| ^^^^^^^^^
......@@ -26,7 +8,7 @@ LL | const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error: pointers cannot be cast to integers during const eval
--> $DIR/const-extern-fn-min-const-fn.rs:9:48
--> $DIR/const-extern-fn-min-const-fn.rs:7:48
|
LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
| ^^^^^^^^^^^^
......@@ -34,6 +16,6 @@ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
= note: at compile-time, pointers do not have an integer value
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
......@@ -4,7 +4,6 @@
// A very basic test of const fn functionality.
#![feature(const_indexing)]
#![feature(const_fn_trait_bound)]
const fn add(x: u32, y: u32) -> u32 {
x + y
......
error: fatal error triggered by #[rustc_error]
--> $DIR/const_fn_trait_bound.rs:17:1
|
LL | fn main() {}
| ^^^^^^^^^
error: aborting due to previous error
// gate-test-const_fn_trait_bound
// revisions: stock gated
#![feature(rustc_attrs)]
#![cfg_attr(gated, feature(const_fn_trait_bound))]
const fn test1<T: std::ops::Add>() {}
//[stock]~^ trait bounds
const fn test2(_x: &dyn Send) {}
//[stock]~^ trait objects in const fn are unstable
const fn test3() -> &'static dyn Send { loop {} }
//[stock]~^ trait objects in const fn are unstable
#[rustc_error]
fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/const_fn_trait_bound.rs:8:16
|
LL | const fn test1<T: std::ops::Add>() {}
| ^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/const_fn_trait_bound.rs:10:16
|
LL | const fn test2(_x: &dyn Send) {}
| ^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/const_fn_trait_bound.rs:12:21
|
LL | const fn test3() -> &'static dyn Send { loop {} }
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.
// check-pass
const fn x() {
let t = true;
let x = || t; //~ ERROR function pointer
let x = || t;
}
fn main() {}
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/issue-37550-1.rs:3:9
|
LL | let x = || t;
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
......@@ -2,8 +2,6 @@
#![allow(dead_code)]
#![allow(unused_variables)]
#![feature(const_fn_fn_ptr_basics)]
const fn x() {
let t = true;
let x = || t;
......
// run-pass
#![feature(const_fn_fn_ptr_basics)]
#![deny(const_err)]
pub struct Data<T> {
......
#![feature(const_fn_fn_ptr_basics)]
const fn foo() { (||{})() }
//~^ ERROR cannot call non-const closure
......
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/issue-56164.rs:3:18
--> $DIR/issue-56164.rs:1:18
|
LL | const fn foo() { (||{})() }
| ^^^^^^^^
......@@ -8,7 +8,7 @@ LL | const fn foo() { (||{})() }
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: function pointers are not allowed in const fn
--> $DIR/issue-56164.rs:7:5
--> $DIR/issue-56164.rs:5:5
|
LL | input()
| ^^^^^^^
......
......@@ -3,7 +3,6 @@
// regression test for #88071
#![feature(const_btree_new)]
#![feature(const_fn_trait_bound)]
use std::collections::BTreeMap;
......
#![feature(rustc_attrs, staged_api, rustc_allow_const_fn_unstable)]
#![feature(const_fn_fn_ptr_basics)]
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(since="1.0.0", feature = "mep")]
const fn error(_: fn()) {}
//~^ ERROR const-stable function cannot use `#[feature(const_fn_fn_ptr_basics)]`
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(since="1.0.0", feature = "mep")]
#[rustc_allow_const_fn_unstable(const_fn_fn_ptr_basics)]
const fn compiles(_: fn()) {}
fn main() {}
error: const-stable function cannot use `#[feature(const_fn_fn_ptr_basics)]`
--> $DIR/allow_const_fn_ptr.rs:7:16
|
LL | const fn error(_: fn()) {}
| ^
|
help: if it is not part of the public API, make this function unstably const
|
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL | #[rustc_allow_const_fn_unstable(const_fn_fn_ptr_basics)]
|
error: aborting due to previous error
// run-pass
#![feature(rustc_allow_const_fn_unstable)]
#![feature(const_fn_fn_ptr_basics)]
#![feature(rustc_attrs, staged_api)]
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(since="1.0.0", feature = "mep")]
#[rustc_allow_const_fn_unstable(const_fn_fn_ptr_basics)]
const fn takes_fn_ptr(_: fn()) {}
const FN: fn() = || ();
......
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/cast_errors.rs:4:23
|
LL | const fn closure() -> fn() { || {} }
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/cast_errors.rs:4:30
|
LL | const fn closure() -> fn() { || {} }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/cast_errors.rs:8:5
|
LL | (|| {}) as fn();
| ^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/cast_errors.rs:11:16
|
LL | const fn reify(f: fn()) -> unsafe fn() { f }
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/cast_errors.rs:11:28
|
LL | const fn reify(f: fn()) -> unsafe fn() { f }
| ^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/cast_errors.rs:11:42
|
LL | const fn reify(f: fn()) -> unsafe fn() { f }
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/cast_errors.rs:15:21
|
LL | const fn reify2() { main as unsafe fn(); }
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/cast_errors.rs:15:21
|
LL | const fn reify2() { main as unsafe fn(); }
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0658`.
// check-pass
fn main() {}
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
const fn closure() -> fn() { || {} }
//~^ ERROR function pointer
//~| ERROR function pointer cast
const fn closure2() {
(|| {}) as fn();
//~^ ERROR function pointer
}
const fn reify(f: fn()) -> unsafe fn() { f }
//~^ ERROR function pointer
//~| ERROR function pointer
//~| ERROR function pointer cast
const fn reify2() { main as unsafe fn(); }
//~^ ERROR function pointer
//~| ERROR function pointer cast
const fn cmp(x: fn(), y: fn()) -> bool {
//~^ ERROR function pointer
//~| ERROR function pointer
unsafe { x == y }
//~^ ERROR pointers cannot be reliably compared
}
......
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/cmp_fn_pointers.rs:1:14
|
LL | const fn cmp(x: fn(), y: fn()) -> bool {
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/cmp_fn_pointers.rs:1:23
|
LL | const fn cmp(x: fn(), y: fn()) -> bool {
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error: pointers cannot be reliably compared during const eval
--> $DIR/cmp_fn_pointers.rs:4:14
--> $DIR/cmp_fn_pointers.rs:2:14
|
LL | unsafe { x == y }
| ^^^^^^
|
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
error: aborting due to 3 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
......@@ -80,11 +80,10 @@ const fn char_cast(u: u8) -> char { u as char }
const unsafe fn ret_null_ptr_no_unsafe<T>() -> *const T { core::ptr::null() }
const unsafe fn ret_null_mut_ptr_no_unsafe<T>() -> *mut T { core::ptr::null_mut() }
// not ok
const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo11_2<T: Send>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
// not ok
static BAR: u32 = 42;
const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics
......@@ -108,41 +107,28 @@ const fn foo37(a: bool, b: bool) -> bool { a || b }
fn main() {}
impl<T: std::fmt::Debug> Foo<T> {
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo(&self) {}
}
impl<T: std::fmt::Debug + Sized> Foo<T> {
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo2(&self) {}
}
impl<T: Sync + Sized> Foo<T> {
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo3(&self) {}
}
struct AlanTuring<T>(T);
const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
//~^ ERROR trait bounds other than `Sized`
//~| ERROR destructor
//~^ ERROR destructor
const fn no_apit(_x: impl std::fmt::Debug) {}
//~^ ERROR trait bounds other than `Sized`
//~| ERROR destructor
//~^ ERROR destructor
const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
//~^ ERROR trait objects in const fn are unstable
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
//~^ ERROR trait objects in const fn are unstable
const fn no_unsafe() { unsafe {} }
const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
//~^ ERROR trait objects in const fn are unstable
//~| ERROR trait objects in const fn are unstable
//~| ERROR trait objects in const fn are unstable
const fn traits_are_ok_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
const fn no_fn_ptrs(_x: fn()) {}
//~^ ERROR function pointer
const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
//~^ ERROR function pointer
//~| ERROR function pointer cast
const fn fn_ptrs(_x: fn()) {}
const fn fn_ptrs2() -> fn() { fn foo() {} foo }
......@@ -130,26 +130,8 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:84:16
|
LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
| ^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:86:18
|
LL | const fn foo11_2<T: Send>(t: T) -> T { t }
| ^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0013]: constant functions cannot refer to statics
--> $DIR/min_const_fn.rs:90:27
--> $DIR/min_const_fn.rs:89:27
|
LL | const fn foo25() -> u32 { BAR }
| ^^^
......@@ -157,7 +139,7 @@ LL | const fn foo25() -> u32 { BAR }
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constant functions cannot refer to statics
--> $DIR/min_const_fn.rs:91:37
--> $DIR/min_const_fn.rs:90:37
|
LL | const fn foo26() -> &'static u32 { &BAR }
| ^^^
......@@ -165,7 +147,7 @@ LL | const fn foo26() -> &'static u32 { &BAR }
= help: consider extracting the value of the `static` to a `const`, and referring to that
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:92:42
--> $DIR/min_const_fn.rs:91:42
|
LL | const fn foo30(x: *const u32) -> usize { x as usize }
| ^^^^^^^^^^
......@@ -174,7 +156,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:94:63
--> $DIR/min_const_fn.rs:93:63
|
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^
......@@ -183,7 +165,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:96:42
--> $DIR/min_const_fn.rs:95:42
|
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
| ^^^^^^^^^^
......@@ -192,7 +174,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:98:63
--> $DIR/min_const_fn.rs:97:63
|
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^
......@@ -201,7 +183,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:101:14
--> $DIR/min_const_fn.rs:100:14
|
LL | const fn inc(x: &mut i32) { *x += 1 }
| ^
......@@ -209,155 +191,23 @@ LL | const fn inc(x: &mut i32) { *x += 1 }
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:110:6
|
LL | impl<T: std::fmt::Debug> Foo<T> {
| ^
LL |
LL | const fn foo(&self) {}
| ------------------- function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:115:6
|
LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
| ^
LL |
LL | const fn foo2(&self) {}
| -------------------- function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:120:6
|
LL | impl<T: Sync + Sized> Foo<T> {
| ^
LL |
LL | const fn foo3(&self) {}
| -------------------- function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:126:34
|
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:126:19
--> $DIR/min_const_fn.rs:122:19
|
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| ^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:129:22
|
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:129:18
--> $DIR/min_const_fn.rs:124:18
|
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| ^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn.rs:132:23
|
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
| ^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn.rs:134:32
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn.rs:139:41
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
| ------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn.rs:139:42
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
| ------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn.rs:139:42
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
| ------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/min_const_fn.rs:144:21
|
LL | const fn no_fn_ptrs(_x: fn()) {}
| ^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/min_const_fn.rs:146:27
|
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/min_const_fn.rs:146:46
|
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
| ^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error: aborting due to 39 previous errors
error: aborting due to 24 previous errors
Some errors have detailed explanations: E0013, E0493, E0658.
For more information about an error, try `rustc --explain E0013`.
// check-pass
struct HasDyn {
field: &'static dyn std::fmt::Debug,
}
......@@ -7,9 +9,7 @@ struct HasDyn {
const fn no_inner_dyn_trait(_x: Hide) {}
const fn no_inner_dyn_trait2(x: Hide) {
x.0.field;
//~^ ERROR trait objects in const fn are unstable
}
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
//~^ ERROR trait objects in const fn are unstable
fn main() {}
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn_dyn.rs:9:5
|
LL | const fn no_inner_dyn_trait2(x: Hide) {
| ------------------------------------- function declared as const here
LL | x.0.field;
| ^^^^^^^^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
--> $DIR/min_const_fn_dyn.rs:12:66
|
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
| ----------------------------------------- ^^
| |
| function declared as const here
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
// gate-test-const_fn_fn_ptr_basics
struct HasPtr {
field: fn(),
}
struct Hide(HasPtr);
fn field() {}
const fn no_inner_dyn_trait(_x: Hide) {}
const fn no_inner_dyn_trait2(x: Hide) {
x.0.field;
//~^ ERROR function pointer
}
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) }
//~^ ERROR function pointer
fn main() {}
error[E0658]: function pointers cannot appear in constant functions
--> $DIR/min_const_fn_fn_ptr.rs:13:5
|
LL | x.0.field;
| ^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error[E0658]: function pointer casts are not allowed in constant functions
--> $DIR/min_const_fn_fn_ptr.rs:16:59
|
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
// gate-test-const_impl_trait
struct AlanTuring<T>(T);
const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { //~ `impl Trait`
AlanTuring(0)
}
const fn no_rpit() -> impl std::fmt::Debug {} //~ `impl Trait`
fn main() {}
error[E0658]: `impl Trait` is not allowed in constant functions
--> $DIR/min_const_fn_impl_trait.rs:4:24
|
LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #77463 <https://github.com/rust-lang/rust/issues/77463> for more information
= help: add `#![feature(const_impl_trait)]` to the crate attributes to enable
error[E0658]: `impl Trait` is not allowed in constant functions
--> $DIR/min_const_fn_impl_trait.rs:8:23
|
LL | const fn no_rpit() -> impl std::fmt::Debug {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #77463 <https://github.com/rust-lang/rust/issues/77463> for more information
= help: add `#![feature(const_impl_trait)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
......@@ -12,16 +12,6 @@ LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "
warning: skipping const checks
|
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/abi-mismatch.rs:9:23
|
LL | const fn call_rust_fn(my_fn: extern "Rust" fn()) {
| ^^^^^
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/abi-mismatch.rs:10:5
|
LL | my_fn();
| ^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/abi-mismatch.rs:10:5
|
......
......@@ -5,7 +5,6 @@
#![stable(feature = "core", since = "1.6.0")]
#![feature(staged_api)]
#![feature(const_fn_trait_bound)]
enum Opt<T> {
Some(T),
......
error[E0015]: cannot call non-const closure in constant functions
--> $DIR/unstable-const-fn-in-libcore.rs:23:26
--> $DIR/unstable-const-fn-in-libcore.rs:22:26
|
LL | Opt::None => f(),
| ^^^
......@@ -11,7 +11,7 @@ LL | const fn unwrap_or_else<F: FnOnce() -> T + ~const std::ops::FnOnce<()>>
| +++++++++++++++++++++++++++++
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:18:53
--> $DIR/unstable-const-fn-in-libcore.rs:17:53
|
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
| ^ constant functions cannot evaluate destructors
......@@ -20,7 +20,7 @@ LL | }
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:18:47
--> $DIR/unstable-const-fn-in-libcore.rs:17:47
|
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
| ^^^^ constant functions cannot evaluate destructors
......
// Regression test for issue #55825
// Tests that we don't emit a spurious warning in NLL mode
// check-pass
#![feature(nll)]
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } //~ ERROR const
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
fn main() { }
error[E0658]: trait objects in const fn are unstable
--> $DIR/issue-55825-const-fn.rs:6:32
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
warning: skipping const checks
|
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/caller-location-fnptr-rt-ctfe-equiv.rs:20:9
|
LL | let ptr: fn() -> L = attributed;
| ^^^
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/caller-location-fnptr-rt-ctfe-equiv.rs:21:5
|
LL | ptr()
| ^^^
help: skipping check for `const_fn_fn_ptr_basics` feature
--> $DIR/caller-location-fnptr-rt-ctfe-equiv.rs:20:26
|
LL | let ptr: fn() -> L = attributed;
| ^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/caller-location-fnptr-rt-ctfe-equiv.rs:21:5
|
LL | ptr()
| ^^^^^
error: `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine
error: aborting due to previous error; 1 warning emitted
warning: 1 warning emitted
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
pub trait MyTrait {
......
// check-pass
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
trait MyPartialEq {
......
......@@ -3,7 +3,6 @@
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
struct S;
......
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
struct S;
......
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
......
error[E0277]: can't compare `T` with `T` in const contexts
--> $DIR/call-generic-method-fail.rs:5:5
--> $DIR/call-generic-method-fail.rs:4:5
|
LL | *t == *t
| ^^^^^^^^ no implementation for `T == T`
|
note: the trait `PartialEq` is implemented for `T`, but that implementation is not `const`
--> $DIR/call-generic-method-fail.rs:5:5
--> $DIR/call-generic-method-fail.rs:4:5
|
LL | *t == *t
| ^^^^^^^^
error[E0015]: cannot call non-const operator in constant functions
--> $DIR/call-generic-method-fail.rs:5:5
--> $DIR/call-generic-method-fail.rs:4:5
|
LL | *t == *t
| ^^^^^^^^
......
// check-pass
#![feature(const_fn_trait_bound)]
struct S;
impl PartialEq for S {
......
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
struct S;
......
error[E0277]: can't compare `S` with `S` in const contexts
--> $DIR/call-generic-method-nonconst.rs:19:34
--> $DIR/call-generic-method-nonconst.rs:18:34
|
LL | pub const EQ: bool = equals_self(&S);
| ----------- ^^ no implementation for `S == S`
......@@ -8,12 +8,12 @@ LL | pub const EQ: bool = equals_self(&S);
|
= help: the trait `~const PartialEq` is not implemented for `S`
note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
--> $DIR/call-generic-method-nonconst.rs:19:34
--> $DIR/call-generic-method-nonconst.rs:18:34
|
LL | pub const EQ: bool = equals_self(&S);
| ^^
note: required by a bound in `equals_self`
--> $DIR/call-generic-method-nonconst.rs:12:25
--> $DIR/call-generic-method-nonconst.rs:11:25
|
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
| ^^^^^^^^^^^^^^^^ required by this bound in `equals_self`
......
......@@ -3,7 +3,6 @@
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
struct S;
......
// run-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
const fn answer_p1<F>(f: &F) -> u8
where
......
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)] // FIXME is this needed?
trait ConstDefaultFn: Sized {
fn b(self);
......
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
--> $DIR/const-default-method-bodies.rs:25:18
--> $DIR/const-default-method-bodies.rs:24:18
|
LL | NonConstImpl.a();
| ^^^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
--> $DIR/const-default-method-bodies.rs:25:18
--> $DIR/const-default-method-bodies.rs:24:18
|
LL | NonConstImpl.a();
| ^^^
error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
--> $DIR/const-default-method-bodies.rs:25:18
--> $DIR/const-default-method-bodies.rs:24:18
|
LL | NonConstImpl.a();
| ^^^
......
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
#![feature(const_precise_live_drops)]
const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Drop {
......
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied
--> $DIR/const-drop-fail.rs:44:5
--> $DIR/const-drop-fail.rs:43:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
......@@ -8,7 +8,7 @@ LL | NonTrivialDrop,
| ^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:35:19
--> $DIR/const-drop-fail.rs:34:19
|
LL | const fn check<T: ~const Drop>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `check`
......@@ -20,7 +20,7 @@ LL | &mut NonTrivialDrop,
| ++++
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied in `ConstImplWithDropGlue`
--> $DIR/const-drop-fail.rs:46:5
--> $DIR/const-drop-fail.rs:45:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
......@@ -29,23 +29,23 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
|
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:46:5
--> $DIR/const-drop-fail.rs:45:5
|
LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because it appears within the type `ConstImplWithDropGlue`
--> $DIR/const-drop-fail.rs:17:8
--> $DIR/const-drop-fail.rs:16:8
|
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
| ^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:35:19
--> $DIR/const-drop-fail.rs:34:19
|
LL | const fn check<T: ~const Drop>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `check`
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Drop` is not satisfied
--> $DIR/const-drop-fail.rs:48:5
--> $DIR/const-drop-fail.rs:47:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
......@@ -54,12 +54,12 @@ LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
note: required because of the requirements on the impl of `~const Drop` for `ConstDropImplWithBounds<NonTrivialDrop>`
--> $DIR/const-drop-fail.rs:29:25
--> $DIR/const-drop-fail.rs:28:25
|
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:35:19
--> $DIR/const-drop-fail.rs:34:19
|
LL | const fn check<T: ~const Drop>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `check`
......
// revisions: stock precise
#![feature(const_trait_impl)]
#![feature(const_mut_refs)]
#![feature(const_fn_trait_bound)]
#![cfg_attr(precise, feature(const_precise_live_drops))]
use std::marker::PhantomData;
......
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied
--> $DIR/const-drop-fail.rs:44:5
--> $DIR/const-drop-fail.rs:43:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
......@@ -8,7 +8,7 @@ LL | NonTrivialDrop,
| ^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:35:19
--> $DIR/const-drop-fail.rs:34:19
|
LL | const fn check<T: ~const Drop>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `check`
......@@ -20,7 +20,7 @@ LL | &mut NonTrivialDrop,
| ++++
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied in `ConstImplWithDropGlue`
--> $DIR/const-drop-fail.rs:46:5
--> $DIR/const-drop-fail.rs:45:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
......@@ -29,23 +29,23 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
|
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:46:5
--> $DIR/const-drop-fail.rs:45:5
|
LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because it appears within the type `ConstImplWithDropGlue`
--> $DIR/const-drop-fail.rs:17:8
--> $DIR/const-drop-fail.rs:16:8
|
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
| ^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:35:19
--> $DIR/const-drop-fail.rs:34:19
|
LL | const fn check<T: ~const Drop>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `check`
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Drop` is not satisfied
--> $DIR/const-drop-fail.rs:48:5
--> $DIR/const-drop-fail.rs:47:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
......@@ -54,12 +54,12 @@ LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
note: required because of the requirements on the impl of `~const Drop` for `ConstDropImplWithBounds<NonTrivialDrop>`
--> $DIR/const-drop-fail.rs:29:25
--> $DIR/const-drop-fail.rs:28:25
|
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `check`
--> $DIR/const-drop-fail.rs:35:19
--> $DIR/const-drop-fail.rs:34:19
|
LL | const fn check<T: ~const Drop>(_: T) {}
| ^^^^^^^^^^^ required by this bound in `check`
......
// run-pass
// revisions: stock precise
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
#![feature(const_mut_refs)]
#![feature(never_type)]
#![cfg_attr(precise, feature(const_precise_live_drops))]
......
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
trait Tr {}
......
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
--> $DIR/default-method-body-is-const-body-checking.rs:11:15
|
LL | foo::<()>();
| ^^ the trait `~const Tr` is not implemented for `()`
|
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
--> $DIR/default-method-body-is-const-body-checking.rs:11:15
|
LL | foo::<()>();
| ^^
note: required by a bound in `foo`
--> $DIR/default-method-body-is-const-body-checking.rs:7:28
--> $DIR/default-method-body-is-const-body-checking.rs:6:28
|
LL | const fn foo<T>() where T: ~const Tr {}
| ^^^^^^^^^ required by this bound in `foo`
......
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
pub trait Tr {
......
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
--> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
|
LL | ().a()
| ^^^ the trait `~const Tr` is not implemented for `()`
|
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
--> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
|
LL | ().a()
| ^^^
error[E0015]: cannot call non-const fn `<() as Tr>::a` in constant functions
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
--> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
|
LL | ().a()
| ^^^
......
......@@ -7,7 +7,6 @@
#![feature(staged_api)]
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
#![stable(since = "1", feature = "foo")]
trait Tr {
......
// run-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
use std::marker::PhantomData;
......
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
trait Tr {
fn req(&self);
......
error: const trait implementations may not use non-const default functions
--> $DIR/impl-with-default-fn-fail.rs:18:1
--> $DIR/impl-with-default-fn-fail.rs:17:1
|
LL | / impl const Tr for S {
LL | | fn req(&self) {}
......@@ -9,7 +9,7 @@ LL | | }
= note: `prov` not implemented
error: const trait implementations may not use non-const default functions
--> $DIR/impl-with-default-fn-fail.rs:28:1
--> $DIR/impl-with-default-fn-fail.rs:27:1
|
LL | / impl const Tr for u32 {
LL | | fn req(&self) {}
......@@ -20,7 +20,7 @@ LL | | }
= note: `prov` not implemented
error[E0046]: not all trait items implemented, missing: `req`
--> $DIR/impl-with-default-fn-fail.rs:22:1
--> $DIR/impl-with-default-fn-fail.rs:21:1
|
LL | fn req(&self);
| -------------- `req` from trait
......
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
trait Tr {
fn req(&self);
......
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
struct S;
......
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
pub trait A {
......
error[E0277]: the trait bound `T: ~const A` is not satisfied
--> $DIR/issue-88155.rs:9:5
--> $DIR/issue-88155.rs:8:5
|
LL | T::assoc()
| ^^^^^^^^^^ the trait `~const A` is not implemented for `T`
|
note: the trait `A` is implemented for `T`, but that implementation is not `const`
--> $DIR/issue-88155.rs:9:5
--> $DIR/issue-88155.rs:8:5
|
LL | T::assoc()
| ^^^^^^^^^^
error[E0015]: cannot call non-const fn `<T as A>::assoc` in constant functions
--> $DIR/issue-88155.rs:9:5
--> $DIR/issue-88155.rs:8:5
|
LL | T::assoc()
| ^^^^^^^^^^
......
......@@ -10,7 +10,6 @@
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
pub trait Tr {}
......
......@@ -2,7 +2,6 @@
//
// check-pass
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
pub trait Super {}
......
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
trait Convert<T> {
fn to(self) -> T;
......
......@@ -2,7 +2,6 @@
#![feature(staged_api)]
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
#![feature(const_t_try)]
#![feature(const_try)]
#![feature(try_trait_v2)]
......
// run-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
trait Bar {
fn bar() -> u8;
......
// check-pass
#![feature(const_trait_impl)]
#![feature(const_fn_trait_bound)]
trait Foo {
fn bar() where Self: ~const Foo;
......
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
trait Bar {}
......
error[E0277]: the trait bound `T: ~const Bar` is not satisfied
--> $DIR/trait-where-clause.rs:14:5
--> $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:14:5
--> $DIR/trait-where-clause.rs:13:5
|
LL | T::b();
| ^^^^
note: required by a bound in `Foo::b`
--> $DIR/trait-where-clause.rs:8:24
--> $DIR/trait-where-clause.rs:7:24
|
LL | fn b() where Self: ~const Bar;
| ^^^^^^^^^^ required by this bound in `Foo::b`
......@@ -20,18 +20,18 @@ 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:16:5
--> $DIR/trait-where-clause.rs:15: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.rs:16:5
--> $DIR/trait-where-clause.rs:15:5
|
LL | T::c::<T>();
| ^^^^^^^^^
note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause.rs:9:13
--> $DIR/trait-where-clause.rs:8:13
|
LL | fn c<T: ~const Bar>();
| ^^^^^^^^^^ required by this bound in `Foo::c`
......@@ -41,13 +41,13 @@ LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
| ++++++++++++
error[E0277]: the trait bound `T: Bar` is not satisfied
--> $DIR/trait-where-clause.rs:28:5
--> $DIR/trait-where-clause.rs:27:5
|
LL | T::b();
| ^^^^ the trait `Bar` is not implemented for `T`
|
note: required by a bound in `Foo::b`
--> $DIR/trait-where-clause.rs:8:24
--> $DIR/trait-where-clause.rs:7:24
|
LL | fn b() where Self: ~const Bar;
| ^^^^^^^^^^ required by this bound in `Foo::b`
......@@ -57,13 +57,13 @@ LL | fn test3<T: Foo + Bar>() {
| +++++
error[E0277]: the trait bound `T: Bar` is not satisfied
--> $DIR/trait-where-clause.rs:30:5
--> $DIR/trait-where-clause.rs:29:5
|
LL | T::c::<T>();
| ^^^^^^^^^ the trait `Bar` is not implemented for `T`
|
note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause.rs:9:13
--> $DIR/trait-where-clause.rs:8:13
|
LL | fn c<T: ~const Bar>();
| ^^^^^^^^^^ required by this bound in `Foo::c`
......
#![feature(const_impl_trait, const_fn_fn_ptr_basics, rustc_attrs)]
#![feature(rustc_attrs)]
#![feature(type_alias_impl_trait)]
type Foo = impl Fn() -> usize;
......
#![feature(const_impl_trait, generators, generator_trait, rustc_attrs)]
#![feature(generators, generator_trait, rustc_attrs)]
#![feature(type_alias_impl_trait)]
use std::ops::Generator;
......
#![feature(const_impl_trait)]
#![feature(type_alias_impl_trait)]
type Bar = impl Send;
......
error: `impl Send` cannot be used in patterns
--> $DIR/structural-match-no-leak.rs:15:9
--> $DIR/structural-match-no-leak.rs:14:9
|
LL | LEAK_FREE => (),
| ^^^^^^^^^
......
#![feature(const_impl_trait)]
#![feature(type_alias_impl_trait)]
type Foo = impl Send;
......
error: `impl Send` cannot be used in patterns
--> $DIR/structural-match.rs:16:9
--> $DIR/structural-match.rs:15:9
|
LL | VALUE => (),
| ^^^^^
......
......@@ -3,6 +3,7 @@
use clippy_utils::ty::has_drop;
use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, meets_msrv, msrvs, trait_ref_of_method};
use rustc_hir as hir;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
use rustc_lint::{LateContext, LateLintPass};
......@@ -131,6 +132,18 @@ fn check_fn(
FnKind::Closure => return,
}
// Const fns are not allowed as methods in a trait.
{
let parent = cx.tcx.hir().get_parent_item(hir_id);
if parent != CRATE_DEF_ID {
if let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent) {
if let hir::ItemKind::Trait(..) = &item.kind {
return;
}
}
}
}
let mir = cx.tcx.optimized_mir(def_id);
if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv.as_ref()) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册