Skip to content

Commit 76eedbd

Browse files
committed
Auto merge of #157647 - oli-obk:start-using-comptime, r=<try>
Start using comptime for reflection intrinsics and their wrapper functions try-job: aarch64-msvc-1
2 parents ab26b17 + b3c6e82 commit 76eedbd

10 files changed

Lines changed: 82 additions & 18 deletions

File tree

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,9 @@ fn should_encode_mir(
11221122
&& reachable_set.contains(&def_id)
11231123
&& (tcx.generics_of(def_id).requires_monomorphization(tcx)
11241124
|| tcx.cross_crate_inlinable(def_id)));
1125+
// Comptime fns do not have optimized MIR at all.
1126+
let opt =
1127+
opt && !matches!(tcx.constness(def_id), hir::Constness::Const { always: true });
11251128
// The function has a `const` modifier or is in a `const trait`.
11261129
let is_const_fn = tcx.is_const_fn(def_id.to_def_id());
11271130
(is_const_fn, opt)

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,14 @@ impl<'tcx> TyCtxt<'tcx> {
17891789
| DefKind::Ctor(..)
17901790
| DefKind::AnonConst
17911791
| DefKind::InlineConst => self.mir_for_ctfe(def),
1792+
DefKind::Fn | DefKind::AssocFn
1793+
if matches!(
1794+
self.constness(def),
1795+
hir::Constness::Const { always: true }
1796+
) =>
1797+
{
1798+
self.mir_for_ctfe(def)
1799+
}
17921800
// If the caller wants `mir_for_ctfe` of a function they should not be using
17931801
// `instance_mir`, so we'll assume const fn also wants the optimized version.
17941802
_ => self.optimized_mir(def),

compiler/rustc_mir_transform/src/cross_crate_inline.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_hir::attrs::InlineAttr;
22
use rustc_hir::def::DefKind;
33
use rustc_hir::def_id::LocalDefId;
4-
use rustc_hir::find_attr;
4+
use rustc_hir::{self as hir, find_attr};
55
use rustc_middle::bug;
66
use rustc_middle::mir::visit::Visitor;
77
use rustc_middle::mir::*;
@@ -43,6 +43,12 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
4343
return true;
4444
}
4545

46+
if let hir::Constness::Const { always: true } = tcx.constness(def_id) {
47+
// Comptime functions only exist during const eval and can never be passed
48+
// to codegen. The const eval MIR pipeline also doesn't inline anything at all.
49+
return false;
50+
}
51+
4652
// Obey source annotations first; this is important because it means we can use
4753
// #[inline(never)] to force code generation.
4854
match codegen_fn_attrs.inline {

compiler/rustc_mir_transform/src/deduce_param_attrs.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! after `optimized_mir`! We check for things that are *not* guaranteed to be preserved by MIR
1010
//! transforms, such as which local variables happen to be mutated.
1111
12+
use rustc_hir as hir;
1213
use rustc_hir::def_id::LocalDefId;
1314
use rustc_index::IndexVec;
1415
use rustc_middle::middle::deduced_param_attrs::{DeducedParamAttrs, UsageSummary};
@@ -205,6 +206,12 @@ pub(super) fn deduced_param_attrs<'tcx>(
205206
return &[];
206207
}
207208

209+
if let hir::Constness::Const { always: true } = tcx.constness(def_id) {
210+
// Comptime functions only exist during const eval and can never be passed
211+
// to codegen.
212+
return &[];
213+
}
214+
208215
// Grab the optimized MIR. Analyze it to determine which arguments have been mutated.
209216
let body: &Body<'tcx> = tcx.optimized_mir(def_id);
210217
// Arguments spread at ABI level are currently unsupported.

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,18 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
511511
};
512512

513513
let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::Const { always });
514-
pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None, pm::Optimizations::Allowed);
514+
// FIXME(reflection): probably need to look at this for comptime closures
515+
let passes: &[&dyn MirPass<'_>] = if matches!(tcx.def_kind(def), DefKind::Fn | DefKind::AssocFn)
516+
&& matches!(tcx.constness(def), hir::Constness::Const { always: true })
517+
{
518+
// Need to generate mentioned items, as all functions are expected to have them, but for const
519+
// fns we just look at the optimized MIR, which generates it. For comptime fns, there is no
520+
// optimized MIR.
521+
&[&ctfe_limit::CtfeLimit, &mentioned_items::MentionedItems]
522+
} else {
523+
&[&ctfe_limit::CtfeLimit]
524+
};
525+
pm::run_passes(tcx, &mut body, passes, None, pm::Optimizations::Allowed);
515526

516527
body
517528
}

library/core/src/any.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,8 @@ impl TypeId {
785785
/// ```
786786
#[unstable(feature = "type_info", issue = "146922")]
787787
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
788-
pub const fn trait_info_of<
789-
T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized + 'static,
790-
>(
788+
#[rustc_comptime]
789+
pub fn trait_info_of<T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized + 'static>(
791790
self,
792791
) -> Option<TraitImpl<T>> {
793792
// SAFETY: The vtable was obtained for `T`, so it is guaranteed to be `DynMetadata<T>`.
@@ -812,7 +811,8 @@ impl TypeId {
812811
/// ```
813812
#[unstable(feature = "type_info", issue = "146922")]
814813
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
815-
pub const fn trait_info_of_trait_type_id(
814+
#[rustc_comptime]
815+
pub fn trait_info_of_trait_type_id(
816816
self,
817817
trait_represented_by_type_id: TypeId,
818818
) -> Option<TraitImpl<*const ()>> {

library/core/src/intrinsics/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,11 +2874,12 @@ pub const unsafe fn size_of_val<T: ?Sized>(ptr: *const T) -> usize;
28742874
pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
28752875

28762876
#[rustc_intrinsic]
2877+
#[rustc_comptime]
28772878
#[unstable(feature = "core_intrinsics", issue = "none")]
28782879
/// Check if a type represented by a `TypeId` implements a trait represented by a `TypeId`.
28792880
/// It can only be called at compile time, the backends do
28802881
/// not implement it. If it implements the trait the dyn metadata gets returned for vtable access.
2881-
pub const fn type_id_vtable(
2882+
pub fn type_id_vtable(
28822883
_id: crate::any::TypeId,
28832884
_trait: crate::any::TypeId,
28842885
) -> Option<ptr::DynMetadata<*const ()>> {
@@ -2922,7 +2923,8 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
29222923
#[rustc_nounwind]
29232924
#[unstable(feature = "core_intrinsics", issue = "none")]
29242925
#[rustc_intrinsic]
2925-
pub const fn type_id<T: ?Sized>() -> crate::any::TypeId;
2926+
#[rustc_comptime]
2927+
pub fn type_id<T: ?Sized>() -> crate::any::TypeId;
29262928

29272929
/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the
29282930
/// same type. This is necessary because at const-eval time the actual discriminating
@@ -2944,7 +2946,8 @@ pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool {
29442946
/// The more user-friendly version of this intrinsic is [`core::any::TypeId::size`].
29452947
#[rustc_intrinsic]
29462948
#[unstable(feature = "core_intrinsics", issue = "none")]
2947-
pub const fn size_of_type_id(_id: crate::any::TypeId) -> Option<usize> {
2949+
#[rustc_comptime]
2950+
pub fn size_of_type_id(_id: crate::any::TypeId) -> Option<usize> {
29482951
panic!("`TypeId::size` can only be called at compile-time")
29492952
}
29502953

@@ -2953,7 +2956,8 @@ pub const fn size_of_type_id(_id: crate::any::TypeId) -> Option<usize> {
29532956
/// The more user-friendly version of this intrinsic is [`core::any::TypeId::variants`].
29542957
#[rustc_intrinsic]
29552958
#[unstable(feature = "core_intrinsics", issue = "none")]
2956-
pub const fn type_id_variants(_id: crate::any::TypeId) -> usize {
2959+
#[rustc_comptime]
2960+
pub fn type_id_variants(_id: crate::any::TypeId) -> usize {
29572961
panic!("`TypeId::variants` can only be called at compile-time")
29582962
}
29592963

@@ -2962,7 +2966,8 @@ pub const fn type_id_variants(_id: crate::any::TypeId) -> usize {
29622966
/// The more user-friendly version of this intrinsic is [`core::any::TypeId::fields`].
29632967
#[rustc_intrinsic]
29642968
#[unstable(feature = "core_intrinsics", issue = "none")]
2965-
pub const fn type_id_fields(_id: crate::any::TypeId, _variant_index: usize) -> usize {
2969+
#[rustc_comptime]
2970+
pub fn type_id_fields(_id: crate::any::TypeId, _variant_index: usize) -> usize {
29662971
panic!("`TypeId::fields` can only be called at compile-time")
29672972
}
29682973

@@ -2973,7 +2978,8 @@ pub const fn type_id_fields(_id: crate::any::TypeId, _variant_index: usize) -> u
29732978
/// [`FieldRepresentingType`]: crate::field::FieldRepresentingType
29742979
#[rustc_intrinsic]
29752980
#[unstable(feature = "core_intrinsics", issue = "none")]
2976-
pub const fn type_id_field_representing_type(
2981+
#[rustc_comptime]
2982+
pub fn type_id_field_representing_type(
29772983
_id: crate::any::TypeId,
29782984
_variant_index: usize,
29792985
_field_index: usize,
@@ -2988,7 +2994,8 @@ pub const fn type_id_field_representing_type(
29882994
/// [`FieldRepresentingType`]: crate::field::FieldRepresentingType
29892995
#[rustc_intrinsic]
29902996
#[unstable(feature = "core_intrinsics", issue = "none")]
2991-
pub const fn field_representing_type_actual_type_id(
2997+
#[rustc_comptime]
2998+
pub fn field_representing_type_actual_type_id(
29922999
_frt_type_id: crate::any::TypeId,
29933000
) -> crate::any::TypeId {
29943001
panic!("`FieldId::type_id` can only be called at compile-time")

library/core/src/mem/type_info.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@ impl TypeId {
374374
/// ```
375375
#[unstable(feature = "type_info", issue = "146922")]
376376
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
377-
pub const fn size(self) -> Option<usize> {
377+
#[rustc_comptime]
378+
pub fn size(self) -> Option<usize> {
378379
intrinsics::size_of_type_id(self)
379380
}
380381

@@ -399,7 +400,8 @@ impl TypeId {
399400
/// ```
400401
#[unstable(feature = "type_info", issue = "146922")]
401402
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
402-
pub const fn variants(self) -> usize {
403+
#[rustc_comptime]
404+
pub fn variants(self) -> usize {
403405
intrinsics::type_id_variants(self)
404406
}
405407

@@ -461,7 +463,8 @@ impl TypeId {
461463
/// ```
462464
#[unstable(feature = "type_info", issue = "146922")]
463465
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
464-
pub const fn fields(self, variant_index: usize) -> usize {
466+
#[rustc_comptime]
467+
pub fn fields(self, variant_index: usize) -> usize {
465468
intrinsics::type_id_fields(self, variant_index)
466469
}
467470

@@ -527,7 +530,8 @@ impl TypeId {
527530
/// ```
528531
#[unstable(feature = "type_info", issue = "146922")]
529532
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
530-
pub const fn field(self, variant_index: usize, field_index: usize) -> FieldId {
533+
#[rustc_comptime]
534+
pub fn field(self, variant_index: usize, field_index: usize) -> FieldId {
531535
FieldId {
532536
frt_type_id: intrinsics::type_id_field_representing_type(
533537
self,
@@ -571,7 +575,8 @@ impl FieldId {
571575
/// ```
572576
#[unstable(feature = "type_info", issue = "146922")]
573577
#[rustc_const_unstable(feature = "type_info", issue = "146922")]
574-
pub const fn type_id(self) -> TypeId {
578+
#[rustc_comptime]
579+
pub fn type_id(self) -> TypeId {
575580
intrinsics::field_representing_type_actual_type_id(self.frt_type_id)
576581
}
577582
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(type_info)]
2+
3+
trait Trait {}
4+
5+
fn main() {
6+
// Test the (lack of) usability of comptime fns in runtime code.
7+
std::any::TypeId::of::<[u8; usize::MAX]>().trait_info_of::<dyn Trait>();
8+
//~^ ERROR: comptime fns can only be called at compile time
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: comptime fns can only be called at compile time
2+
--> $DIR/reflection_methods_in_runtime_code.rs:7:5
3+
|
4+
LL | std::any::TypeId::of::<[u8; usize::MAX]>().trait_info_of::<dyn Trait>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)