Skip to content
/ rust Public
forked from rust-lang/rust

Commit b5432b2

Browse files
authored
Rollup merge of rust-lang#157647 - oli-obk:start-using-comptime, r=fee1-dead
Start using comptime for reflection intrinsics and their wrapper functions r? @fee1-dead follow-up to rust-lang#148820 I needed to add some more rustc code because turns out I forgot to add tests to the previous PR which actually codegen while using comptime fns. Check builds never try to create optimized MIR, so no code ever hit the assert that prevents creating optimized MIR for comptime fns.
2 parents d56483a + b3c6e82 commit b5432b2

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)