Skip to content

Commit 6e63f7b

Browse files
committed
attempt to make a minimal example work
1 parent 23718a3 commit 6e63f7b

File tree

13 files changed

+62
-21
lines changed

13 files changed

+62
-21
lines changed

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
4141
};
4242
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
4343
}
44+
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
4445
_ => {
4546
if let Some(fn_kind) = node.fn_kind() {
4647
if fn_kind.constness() == hir::Constness::Const {

compiler/rustc_const_eval/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust.
2020
#![feature(trusted_step)]
2121
#![feature(try_blocks)]
2222
#![feature(yeet_expr)]
23+
#![feature(if_let_guard)]
2324
#![feature(is_some_and)]
2425
#![recursion_limit = "256"]
2526

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+14
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,20 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
783783
);
784784
return;
785785
}
786+
Ok(Some(ImplSource::Closure(data))) => {
787+
if !tcx.is_const_fn_raw(data.closure_def_id) {
788+
self.check_op(ops::FnCallNonConst {
789+
caller,
790+
callee,
791+
substs,
792+
span: *fn_span,
793+
from_hir_call: *from_hir_call,
794+
feature: None,
795+
});
796+
797+
return;
798+
}
799+
}
786800
Ok(Some(ImplSource::UserDefined(data))) => {
787801
let callee_name = tcx.item_name(callee);
788802
if let Some(&did) = tcx

compiler/rustc_metadata/src/rmeta/encoder.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16861686
}
16871687

16881688
ty::Closure(_, substs) => {
1689+
let constness = self.tcx.constness(def_id.to_def_id());
1690+
self.tables.constness.set(def_id.to_def_id().index, constness);
16891691
record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
16901692
}
16911693

compiler/rustc_middle/src/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ impl<'hir> Map<'hir> {
485485
BodyOwnerKind::Static(mt) => ConstContext::Static(mt),
486486

487487
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None,
488-
BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
488+
BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
489489
ConstContext::ConstFn
490490
}
491491
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => {

compiler/rustc_middle/src/traits/select.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ pub enum SelectionCandidate<'tcx> {
131131

132132
/// Implementation of a `Fn`-family trait by one of the anonymous types
133133
/// generated for an `||` expression.
134-
ClosureCandidate,
134+
ClosureCandidate {
135+
is_const: bool,
136+
},
135137

136138
/// Implementation of a `Generator` trait by one of the anonymous types
137139
/// generated for a generator.

compiler/rustc_middle/src/ty/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -2465,8 +2465,10 @@ impl<'tcx> TyCtxt<'tcx> {
24652465

24662466
#[inline]
24672467
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
2468-
matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..))
2469-
&& self.constness(def_id) == hir::Constness::Const
2468+
matches!(
2469+
self.def_kind(def_id),
2470+
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure
2471+
) && self.constness(def_id) == hir::Constness::Const
24702472
}
24712473

24722474
#[inline]

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -254,18 +254,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
254254
// touch bound regions, they just capture the in-scope
255255
// type/region parameters
256256
match *obligation.self_ty().skip_binder().kind() {
257-
ty::Closure(_, closure_substs) => {
257+
ty::Closure(def_id, closure_substs) => {
258+
let is_const = self.tcx().is_const_fn_raw(def_id);
258259
debug!(?kind, ?obligation, "assemble_unboxed_candidates");
259260
match self.infcx.closure_kind(closure_substs) {
260261
Some(closure_kind) => {
261262
debug!(?closure_kind, "assemble_unboxed_candidates");
262263
if closure_kind.extends(kind) {
263-
candidates.vec.push(ClosureCandidate);
264+
candidates.vec.push(ClosureCandidate {
265+
is_const,
266+
});
264267
}
265268
}
266269
None => {
267270
debug!("assemble_unboxed_candidates: closure_kind not yet known");
268-
candidates.vec.push(ClosureCandidate);
271+
candidates.vec.push(ClosureCandidate {
272+
is_const,
273+
});
269274
}
270275
}
271276
}

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
8484
ImplSource::Object(data)
8585
}
8686

87-
ClosureCandidate => {
87+
ClosureCandidate { .. } => {
8888
let vtable_closure = self.confirm_closure_candidate(obligation)?;
8989
ImplSource::Closure(vtable_closure)
9090
}

compiler/rustc_trait_selection/src/traits/select/mod.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -1365,15 +1365,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13651365
// const param
13661366
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
13671367
// const projection
1368-
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) => {}
1368+
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
13691369
// auto trait impl
1370-
AutoImplCandidate => {}
1370+
| AutoImplCandidate
13711371
// generator / future, this will raise error in other places
13721372
// or ignore error with const_async_blocks feature
1373-
GeneratorCandidate => {}
1374-
FutureCandidate => {}
1373+
| GeneratorCandidate
1374+
| FutureCandidate
13751375
// FnDef where the function is const
1376-
FnPointerCandidate { is_const: true } => {}
1376+
| FnPointerCandidate { is_const: true }
1377+
| ConstDestructCandidate(_)
1378+
| ClosureCandidate { is_const: true } => {}
1379+
13771380
FnPointerCandidate { is_const: false } => {
13781381
if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
13791382
// Trait methods are not seen as const unless the trait is implemented as const.
@@ -1382,7 +1385,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13821385
continue
13831386
}
13841387
}
1385-
ConstDestructCandidate(_) => {}
1388+
13861389
_ => {
13871390
// reject all other types of candidates
13881391
continue;
@@ -1844,7 +1847,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18441847
(
18451848
ParamCandidate(ref cand),
18461849
ImplCandidate(..)
1847-
| ClosureCandidate
1850+
| ClosureCandidate { .. }
18481851
| GeneratorCandidate
18491852
| FutureCandidate
18501853
| FnPointerCandidate { .. }
@@ -1863,7 +1866,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18631866
}
18641867
(
18651868
ImplCandidate(_)
1866-
| ClosureCandidate
1869+
| ClosureCandidate { .. }
18671870
| GeneratorCandidate
18681871
| FutureCandidate
18691872
| FnPointerCandidate { .. }
@@ -1894,7 +1897,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18941897
(
18951898
ObjectCandidate(_) | ProjectionCandidate(..),
18961899
ImplCandidate(..)
1897-
| ClosureCandidate
1900+
| ClosureCandidate { .. }
18981901
| GeneratorCandidate
18991902
| FutureCandidate
19001903
| FnPointerCandidate { .. }
@@ -1907,7 +1910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19071910

19081911
(
19091912
ImplCandidate(..)
1910-
| ClosureCandidate
1913+
| ClosureCandidate { .. }
19111914
| GeneratorCandidate
19121915
| FutureCandidate
19131916
| FnPointerCandidate { .. }
@@ -1989,7 +1992,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19891992
// Everything else is ambiguous
19901993
(
19911994
ImplCandidate(_)
1992-
| ClosureCandidate
1995+
| ClosureCandidate { .. }
19931996
| GeneratorCandidate
19941997
| FutureCandidate
19951998
| FnPointerCandidate { .. }
@@ -1999,7 +2002,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19992002
| BuiltinCandidate { has_nested: true }
20002003
| TraitAliasCandidate,
20012004
ImplCandidate(_)
2002-
| ClosureCandidate
2005+
| ClosureCandidate { .. }
20032006
| GeneratorCandidate
20042007
| FutureCandidate
20052008
| FnPointerCandidate { .. }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
3+
#![feature(const_closures, const_trait_impl)]
4+
#![allow(incomplete_features)]
5+
6+
pub const _: () = {
7+
assert!((const || true)());
8+
};
9+
10+
fn main() {}

src/test/ui/rfc-2632-const-trait-impl/const_closures/gate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// gate-test-const_closures
12
fn main() {
23
(const || {})();
34
//~^ ERROR: const closures are experimental

src/test/ui/rfc-2632-const-trait-impl/const_closures/gate.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0658]: const closures are experimental
2-
--> $DIR/gate.rs:2:6
2+
--> $DIR/gate.rs:3:6
33
|
44
LL | (const || {})();
55
| ^^^^^^^^^^^

0 commit comments

Comments
 (0)