Skip to content

Commit b90abe6

Browse files
committed
constify const Fn*: Destruct
1 parent 620e36a commit b90abe6

File tree

7 files changed

+92
-10
lines changed

7 files changed

+92
-10
lines changed

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -797,12 +797,16 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
797797
| ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_))
798798
| ty::Error(_) => Ok(vec![]),
799799

800-
// Coroutines and closures could implement `[const] Drop`,
800+
// Closures are [const] Destruct when all of their upvars (captures) are [const] Destruct.
801+
ty::Closure(_, args) => {
802+
let closure_args = args.as_closure();
803+
Ok(vec![ty::TraitRef::new(cx, destruct_def_id, [closure_args.tupled_upvars_ty()])])
804+
}
805+
// Coroutines could implement `[const] Drop`,
801806
// but they don't really need to right now.
802-
ty::Closure(_, _)
803-
| ty::CoroutineClosure(_, _)
804-
| ty::Coroutine(_, _)
805-
| ty::CoroutineWitness(_, _) => Err(NoSolution),
807+
ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) | ty::CoroutineWitness(_, _) => {
808+
Err(NoSolution)
809+
}
806810

807811
// FIXME(unsafe_binders): Unsafe binders could implement `[const] Drop`
808812
// if their inner type implements it.

compiler/rustc_trait_selection/src/traits/effects.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,17 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
472472
| ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_))
473473
| ty::Error(_) => thin_vec![],
474474

475-
// Coroutines and closures could implement `[const] Drop`,
475+
// Closures are [const] Destruct when all of their upvars (captures) are [const] Destruct.
476+
ty::Closure(_, args) => {
477+
let closure_args = args.as_closure();
478+
thin_vec![ty::TraitRef::new(tcx, destruct_def_id, [closure_args.tupled_upvars_ty()])]
479+
}
480+
481+
// Coroutines could implement `[const] Drop`,
476482
// but they don't really need to right now.
477-
ty::Closure(_, _)
478-
| ty::CoroutineClosure(_, _)
479-
| ty::Coroutine(_, _)
480-
| ty::CoroutineWitness(_, _) => return Err(EvaluationFailure::NoSolution),
483+
ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) | ty::CoroutineWitness(_, _) => {
484+
return Err(EvaluationFailure::NoSolution);
485+
}
481486

482487
// FIXME(unsafe_binders): Unsafe binders could implement `[const] Drop`
483488
// if their inner type implements it.

library/coretests/tests/array.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,3 +741,18 @@ fn const_array_ops() {
741741
struct Zst;
742742
assert_eq!([(); 10].try_map(|()| Some(Zst)), Some([const { Zst }; 10]));
743743
}
744+
745+
#[test]
746+
const fn extra_const_array_ops() {
747+
let x: [u8; 4] =
748+
{ std::array::from_fn(const |i| i + 4).map(const |x| x * 2).map(const |x| x as _) };
749+
let y = 4;
750+
struct Z(u16);
751+
impl const Drop for Z {
752+
fn drop(&mut self) {}
753+
}
754+
let w = Z(2);
755+
let _x: [u8; 4] = {
756+
std::array::from_fn(const |_| x[0] + y).map(const |x| x * (w.0 as u8)).map(const |x| x as _)
757+
};
758+
}

library/coretests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#![feature(const_bool)]
1818
#![feature(const_cell_traits)]
1919
#![feature(const_clone)]
20+
#![feature(const_closures)]
2021
#![feature(const_cmp)]
2122
#![feature(const_convert)]
2223
#![feature(const_default)]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0277]: the trait bound `Vec<u8>: const Destruct` is not satisfied
2+
--> $DIR/const-closure-with-indestructible-indestructible.rs:10:16
3+
|
4+
LL | i_need(const || {
5+
| _________------_^
6+
| | |
7+
| | required by a bound introduced by this call
8+
LL | |
9+
LL | | let y = v;
10+
LL | | })
11+
| |_________^
12+
|
13+
note: required by a bound in `i_need`
14+
--> $DIR/const-closure-with-indestructible-indestructible.rs:5:20
15+
|
16+
LL | const fn i_need<F: [const] std::marker::Destruct>(x: F) {}
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `i_need`
18+
19+
error: aborting due to 1 previous error
20+
21+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0277]: the trait bound `Vec<u8>: const Destruct` is not satisfied
2+
--> $DIR/const-closure-with-indestructible-indestructible.rs:10:16
3+
|
4+
LL | i_need(const || {
5+
| _________------_^
6+
| | |
7+
| | required by a bound introduced by this call
8+
LL | |
9+
LL | | let y = v;
10+
LL | | })
11+
| |_________^
12+
|
13+
note: required by a bound in `i_need`
14+
--> $DIR/const-closure-with-indestructible-indestructible.rs:5:20
15+
|
16+
LL | const fn i_need<F: [const] std::marker::Destruct>(x: F) {}
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `i_need`
18+
19+
error: aborting due to 1 previous error
20+
21+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@revisions: next old
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
#![feature(const_trait_impl, const_closures, const_destruct)]
5+
const fn i_need<F: [const] std::marker::Destruct>(x: F) {}
6+
7+
fn main() {
8+
const {
9+
let v = Vec::<u8>::new();
10+
i_need(const || {
11+
//~^ ERROR the trait bound
12+
let y = v;
13+
})
14+
};
15+
}

0 commit comments

Comments
 (0)