mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
attempt to make a minimal example work
This commit is contained in:
parent
23718a3cc2
commit
6e63f7be54
@ -41,6 +41,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
|
||||
};
|
||||
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
||||
}
|
||||
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
|
||||
_ => {
|
||||
if let Some(fn_kind) = node.fn_kind() {
|
||||
if fn_kind.constness() == hir::Constness::Const {
|
||||
|
@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust.
|
||||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(yeet_expr)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(is_some_and)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
|
@ -783,6 +783,20 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
);
|
||||
return;
|
||||
}
|
||||
Ok(Some(ImplSource::Closure(data))) => {
|
||||
if !tcx.is_const_fn_raw(data.closure_def_id) {
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
feature: None,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ok(Some(ImplSource::UserDefined(data))) => {
|
||||
let callee_name = tcx.item_name(callee);
|
||||
if let Some(&did) = tcx
|
||||
|
@ -1686,6 +1686,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
let constness = self.tcx.constness(def_id.to_def_id());
|
||||
self.tables.constness.set(def_id.to_def_id().index, constness);
|
||||
record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
|
||||
}
|
||||
|
||||
|
@ -485,7 +485,7 @@ impl<'hir> Map<'hir> {
|
||||
BodyOwnerKind::Static(mt) => ConstContext::Static(mt),
|
||||
|
||||
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None,
|
||||
BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
|
||||
BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
|
||||
ConstContext::ConstFn
|
||||
}
|
||||
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => {
|
||||
|
@ -131,7 +131,9 @@ pub enum SelectionCandidate<'tcx> {
|
||||
|
||||
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
||||
/// generated for an `||` expression.
|
||||
ClosureCandidate,
|
||||
ClosureCandidate {
|
||||
is_const: bool,
|
||||
},
|
||||
|
||||
/// Implementation of a `Generator` trait by one of the anonymous types
|
||||
/// generated for a generator.
|
||||
|
@ -2465,8 +2465,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
|
||||
matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..))
|
||||
&& self.constness(def_id) == hir::Constness::Const
|
||||
matches!(
|
||||
self.def_kind(def_id),
|
||||
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure
|
||||
) && self.constness(def_id) == hir::Constness::Const
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -254,18 +254,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
match *obligation.self_ty().skip_binder().kind() {
|
||||
ty::Closure(_, closure_substs) => {
|
||||
ty::Closure(def_id, closure_substs) => {
|
||||
let is_const = self.tcx().is_const_fn_raw(def_id);
|
||||
debug!(?kind, ?obligation, "assemble_unboxed_candidates");
|
||||
match self.infcx.closure_kind(closure_substs) {
|
||||
Some(closure_kind) => {
|
||||
debug!(?closure_kind, "assemble_unboxed_candidates");
|
||||
if closure_kind.extends(kind) {
|
||||
candidates.vec.push(ClosureCandidate);
|
||||
candidates.vec.push(ClosureCandidate {
|
||||
is_const,
|
||||
});
|
||||
}
|
||||
}
|
||||
None => {
|
||||
debug!("assemble_unboxed_candidates: closure_kind not yet known");
|
||||
candidates.vec.push(ClosureCandidate);
|
||||
candidates.vec.push(ClosureCandidate {
|
||||
is_const,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ImplSource::Object(data)
|
||||
}
|
||||
|
||||
ClosureCandidate => {
|
||||
ClosureCandidate { .. } => {
|
||||
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
||||
ImplSource::Closure(vtable_closure)
|
||||
}
|
||||
|
@ -1365,15 +1365,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// const param
|
||||
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
|
||||
// const projection
|
||||
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) => {}
|
||||
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
|
||||
// auto trait impl
|
||||
AutoImplCandidate => {}
|
||||
| AutoImplCandidate
|
||||
// generator / future, this will raise error in other places
|
||||
// or ignore error with const_async_blocks feature
|
||||
GeneratorCandidate => {}
|
||||
FutureCandidate => {}
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
// FnDef where the function is const
|
||||
FnPointerCandidate { is_const: true } => {}
|
||||
| FnPointerCandidate { is_const: true }
|
||||
| ConstDestructCandidate(_)
|
||||
| ClosureCandidate { is_const: true } => {}
|
||||
|
||||
FnPointerCandidate { is_const: false } => {
|
||||
if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
|
||||
// Trait methods are not seen as const unless the trait is implemented as const.
|
||||
@ -1382,7 +1385,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
continue
|
||||
}
|
||||
}
|
||||
ConstDestructCandidate(_) => {}
|
||||
|
||||
_ => {
|
||||
// reject all other types of candidates
|
||||
continue;
|
||||
@ -1844,7 +1847,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
(
|
||||
ParamCandidate(ref cand),
|
||||
ImplCandidate(..)
|
||||
| ClosureCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
| FnPointerCandidate { .. }
|
||||
@ -1863,7 +1866,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
(
|
||||
ImplCandidate(_)
|
||||
| ClosureCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
| FnPointerCandidate { .. }
|
||||
@ -1894,7 +1897,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
(
|
||||
ObjectCandidate(_) | ProjectionCandidate(..),
|
||||
ImplCandidate(..)
|
||||
| ClosureCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
| FnPointerCandidate { .. }
|
||||
@ -1907,7 +1910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
(
|
||||
ImplCandidate(..)
|
||||
| ClosureCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
| FnPointerCandidate { .. }
|
||||
@ -1989,7 +1992,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// Everything else is ambiguous
|
||||
(
|
||||
ImplCandidate(_)
|
||||
| ClosureCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
| FnPointerCandidate { .. }
|
||||
@ -1999,7 +2002,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| BuiltinCandidate { has_nested: true }
|
||||
| TraitAliasCandidate,
|
||||
ImplCandidate(_)
|
||||
| ClosureCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
| FnPointerCandidate { .. }
|
||||
|
10
src/test/ui/rfc-2632-const-trait-impl/const_closures/call.rs
Normal file
10
src/test/ui/rfc-2632-const-trait-impl/const_closures/call.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(const_closures, const_trait_impl)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub const _: () = {
|
||||
assert!((const || true)());
|
||||
};
|
||||
|
||||
fn main() {}
|
@ -1,3 +1,4 @@
|
||||
// gate-test-const_closures
|
||||
fn main() {
|
||||
(const || {})();
|
||||
//~^ ERROR: const closures are experimental
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: const closures are experimental
|
||||
--> $DIR/gate.rs:2:6
|
||||
--> $DIR/gate.rs:3:6
|
||||
|
|
||||
LL | (const || {})();
|
||||
| ^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user