1
Fork 0

Make const_eval_select a rustc_intrinsic

This commit is contained in:
Oli Scherer 2024-03-05 17:39:04 +00:00
parent 196ff446d2
commit 7f9830b16c
5 changed files with 95 additions and 71 deletions

View file

@ -579,7 +579,7 @@ pub fn check_intrinsic_type(
sym::is_val_statically_known => (1, 1, vec![param(0)], tcx.types.bool), sym::is_val_statically_known => (1, 1, vec![param(0)], tcx.types.bool),
sym::const_eval_select => (4, 0, vec![param(0), param(1), param(2)], param(3)), sym::const_eval_select => (4, 1, vec![param(0), param(1), param(2)], param(3)),
sym::vtable_size | sym::vtable_align => { sym::vtable_size | sym::vtable_align => {
(0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize) (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)

View file

@ -1704,12 +1704,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
{ {
for &local_def_id in tcx.mir_keys(()) { for &local_def_id in tcx.mir_keys(()) {
if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) {
if tcx.intrinsic(local_def_id).map_or(true, |i| !i.must_be_overridden) {
record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <-
self.tcx.deduced_param_attrs(local_def_id.to_def_id())); self.tcx.deduced_param_attrs(local_def_id.to_def_id()));
} }
} }
} }
} }
}
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn encode_stability(&mut self, def_id: DefId) { fn encode_stability(&mut self, def_id: DefId) {

View file

@ -1365,8 +1365,10 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
if associated_body(Node::ImplItem(item)).is_some() { if associated_body(Node::ImplItem(item)).is_some() {
if !self.tcx.has_attr(item.owner_id.def_id, sym::rustc_intrinsic_must_be_overridden) {
self.body_owners.push(item.owner_id.def_id); self.body_owners.push(item.owner_id.def_id);
} }
}
self.impl_items.push(item.impl_item_id()); self.impl_items.push(item.impl_item_id());
intravisit::walk_impl_item(self, item) intravisit::walk_impl_item(self, item)

View file

@ -2508,6 +2508,19 @@ extern "rust-intrinsic" {
#[rustc_nounwind] #[rustc_nounwind]
pub fn vtable_align(ptr: *const ()) -> usize; pub fn vtable_align(ptr: *const ()) -> usize;
#[cfg(bootstrap)]
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
pub fn const_eval_select<ARG: Tuple, F, G, RET>(
arg: ARG,
called_in_const: F,
called_at_rt: G,
) -> RET
where
G: FnOnce<ARG, Output = RET>,
F: FnOnce<ARG, Output = RET>;
}
/// Selects which function to call depending on the context. /// Selects which function to call depending on the context.
/// ///
/// If this function is evaluated at compile-time, then a call to this /// If this function is evaluated at compile-time, then a call to this
@ -2565,15 +2578,20 @@ extern "rust-intrinsic" {
/// Currently such an assertion would always succeed; until Rust decides /// Currently such an assertion would always succeed; until Rust decides
/// otherwise, that principle should not be violated. /// otherwise, that principle should not be violated.
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")] #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] #[unstable(feature = "core_intrinsics", issue = "none")]
pub fn const_eval_select<ARG: Tuple, F, G, RET>( #[cfg(not(bootstrap))]
arg: ARG, #[rustc_intrinsic]
called_in_const: F, #[rustc_intrinsic_must_be_overridden]
called_at_rt: G, pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
_arg: ARG,
_called_in_const: F,
_called_at_rt: G,
) -> RET ) -> RET
where where
G: FnOnce<ARG, Output = RET>, G: FnOnce<ARG, Output = RET>,
F: FnOnce<ARG, Output = RET>; F: FnOnce<ARG, Output = RET>,
{
unreachable!()
} }
/// Returns whether the argument's value is statically known at /// Returns whether the argument's value is statically known at

View file

@ -509,17 +509,19 @@ trait StructuralPartialEq {}
const fn drop<T: ~const Destruct>(_: T) {} const fn drop<T: ~const Destruct>(_: T) {}
extern "rust-intrinsic" {
#[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")] #[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")]
#[rustc_safe_intrinsic] #[rustc_intrinsic_must_be_overridden]
fn const_eval_select<ARG: Tuple, F, G, RET>( #[rustc_intrinsic]
const fn const_eval_select<ARG: Tuple, F, G, RET>(
arg: ARG, arg: ARG,
called_in_const: F, called_in_const: F,
called_at_rt: G, called_at_rt: G,
) -> RET ) -> RET
where where
F: const FnOnce<ARG, Output = RET>, F: const FnOnce<ARG, Output = RET>,
G: FnOnce<ARG, Output = RET>; G: FnOnce<ARG, Output = RET>,
{
loop {}
} }
fn test_const_eval_select() { fn test_const_eval_select() {