@@ -6,19 +6,18 @@ use std::assert_matches::assert_matches;
66
77use rustc_abi:: Size ;
88use rustc_apfloat:: ieee:: { Double , Half , Quad , Single } ;
9- use rustc_hir:: def_id:: DefId ;
109use rustc_middle:: mir:: { self , BinOp , ConstValue , NonDivergingIntrinsic } ;
1110use rustc_middle:: ty:: layout:: { TyAndLayout , ValidityRequirement } ;
12- use rustc_middle:: ty:: { GenericArgsRef , Ty , TyCtxt } ;
11+ use rustc_middle:: ty:: { Ty , TyCtxt } ;
1312use rustc_middle:: { bug, ty} ;
1413use rustc_span:: { Symbol , sym} ;
1514use tracing:: trace;
1615
1716use super :: memory:: MemoryKind ;
1817use super :: util:: ensure_monomorphic_enough;
1918use super :: {
20- Allocation , CheckInAllocMsg , ConstAllocation , GlobalId , ImmTy , InterpCx , InterpResult , Machine ,
21- OpTy , PlaceTy , Pointer , PointerArithmetic , Provenance , Scalar , err_inval, err_ub_custom,
19+ Allocation , CheckInAllocMsg , ConstAllocation , ImmTy , InterpCx , InterpResult , Machine , OpTy ,
20+ PlaceTy , Pointer , PointerArithmetic , Provenance , Scalar , err_inval, err_ub_custom,
2221 err_unsup_format, interp_ok, throw_inval, throw_ub_custom, throw_ub_format,
2322} ;
2423use crate :: fluent_generated as fluent;
@@ -30,73 +29,6 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAll
3029 tcx. mk_const_alloc ( alloc)
3130}
3231
33- /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
34- /// inside an `InterpCx` and instead have their value computed directly from rustc internal info.
35- pub ( crate ) fn eval_nullary_intrinsic < ' tcx > (
36- tcx : TyCtxt < ' tcx > ,
37- typing_env : ty:: TypingEnv < ' tcx > ,
38- def_id : DefId ,
39- args : GenericArgsRef < ' tcx > ,
40- ) -> InterpResult < ' tcx , ConstValue < ' tcx > > {
41- let tp_ty = args. type_at ( 0 ) ;
42- let name = tcx. item_name ( def_id) ;
43- interp_ok ( match name {
44- sym:: type_name => {
45- ensure_monomorphic_enough ( tcx, tp_ty) ?;
46- let alloc = alloc_type_name ( tcx, tp_ty) ;
47- ConstValue :: Slice { data : alloc, meta : alloc. inner ( ) . size ( ) . bytes ( ) }
48- }
49- sym:: needs_drop => {
50- ensure_monomorphic_enough ( tcx, tp_ty) ?;
51- ConstValue :: from_bool ( tp_ty. needs_drop ( tcx, typing_env) )
52- }
53- sym:: type_id => {
54- ensure_monomorphic_enough ( tcx, tp_ty) ?;
55- ConstValue :: from_u128 ( tcx. type_id_hash ( tp_ty) . as_u128 ( ) )
56- }
57- sym:: variant_count => match match tp_ty. kind ( ) {
58- // Pattern types have the same number of variants as their base type.
59- // Even if we restrict e.g. which variants are valid, the variants are essentially just uninhabited.
60- // And `Result<(), !>` still has two variants according to `variant_count`.
61- ty:: Pat ( base, _) => * base,
62- _ => tp_ty,
63- }
64- . kind ( )
65- {
66- // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
67- ty:: Adt ( adt, _) => ConstValue :: from_target_usize ( adt. variants ( ) . len ( ) as u64 , & tcx) ,
68- ty:: Alias ( ..) | ty:: Param ( _) | ty:: Placeholder ( _) | ty:: Infer ( _) => {
69- throw_inval ! ( TooGeneric )
70- }
71- ty:: Pat ( ..) => unreachable ! ( ) ,
72- ty:: Bound ( _, _) => bug ! ( "bound ty during ctfe" ) ,
73- ty:: Bool
74- | ty:: Char
75- | ty:: Int ( _)
76- | ty:: Uint ( _)
77- | ty:: Float ( _)
78- | ty:: Foreign ( _)
79- | ty:: Str
80- | ty:: Array ( _, _)
81- | ty:: Slice ( _)
82- | ty:: RawPtr ( _, _)
83- | ty:: Ref ( _, _, _)
84- | ty:: FnDef ( _, _)
85- | ty:: FnPtr ( ..)
86- | ty:: Dynamic ( _, _, _)
87- | ty:: Closure ( _, _)
88- | ty:: CoroutineClosure ( _, _)
89- | ty:: Coroutine ( _, _)
90- | ty:: CoroutineWitness ( ..)
91- | ty:: UnsafeBinder ( _)
92- | ty:: Never
93- | ty:: Tuple ( _)
94- | ty:: Error ( _) => ConstValue :: from_target_usize ( 0u64 , & tcx) ,
95- } ,
96- other => bug ! ( "`{}` is not a zero arg intrinsic" , other) ,
97- } )
98- }
99-
10032impl < ' tcx , M : Machine < ' tcx > > InterpCx < ' tcx , M > {
10133 /// Returns `true` if emulation happened.
10234 /// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
@@ -110,8 +42,77 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
11042 ) -> InterpResult < ' tcx , bool > {
11143 let instance_args = instance. args ;
11244 let intrinsic_name = self . tcx . item_name ( instance. def_id ( ) ) ;
45+ let tcx = self . tcx . tcx ;
11346
11447 match intrinsic_name {
48+ sym:: type_name => {
49+ let tp_ty = instance. args . type_at ( 0 ) ;
50+ ensure_monomorphic_enough ( tcx, tp_ty) ?;
51+ let alloc = alloc_type_name ( tcx, tp_ty) ;
52+ let val = ConstValue :: Slice { data : alloc, meta : alloc. inner ( ) . size ( ) . bytes ( ) } ;
53+ let val = self . const_val_to_op ( val, dest. layout . ty , Some ( dest. layout ) ) ?;
54+ self . copy_op ( & val, dest) ?;
55+ }
56+ sym:: needs_drop => {
57+ let tp_ty = instance. args . type_at ( 0 ) ;
58+ ensure_monomorphic_enough ( tcx, tp_ty) ?;
59+ let val = ConstValue :: from_bool ( tp_ty. needs_drop ( tcx, self . typing_env ) ) ;
60+ let val = self . const_val_to_op ( val, tcx. types . bool , Some ( dest. layout ) ) ?;
61+ self . copy_op ( & val, dest) ?;
62+ }
63+ sym:: type_id => {
64+ let tp_ty = instance. args . type_at ( 0 ) ;
65+ ensure_monomorphic_enough ( tcx, tp_ty) ?;
66+ let val = ConstValue :: from_u128 ( tcx. type_id_hash ( tp_ty) . as_u128 ( ) ) ;
67+ let val = self . const_val_to_op ( val, dest. layout . ty , Some ( dest. layout ) ) ?;
68+ self . copy_op ( & val, dest) ?;
69+ }
70+ sym:: variant_count => {
71+ let tp_ty = instance. args . type_at ( 0 ) ;
72+ let ty = match tp_ty. kind ( ) {
73+ // Pattern types have the same number of variants as their base type.
74+ // Even if we restrict e.g. which variants are valid, the variants are essentially just uninhabited.
75+ // And `Result<(), !>` still has two variants according to `variant_count`.
76+ ty:: Pat ( base, _) => * base,
77+ _ => tp_ty,
78+ } ;
79+ let val = match ty. kind ( ) {
80+ // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
81+ ty:: Adt ( adt, _) => {
82+ ConstValue :: from_target_usize ( adt. variants ( ) . len ( ) as u64 , & tcx)
83+ }
84+ ty:: Alias ( ..) | ty:: Param ( _) | ty:: Placeholder ( _) | ty:: Infer ( _) => {
85+ throw_inval ! ( TooGeneric )
86+ }
87+ ty:: Pat ( ..) => unreachable ! ( ) ,
88+ ty:: Bound ( _, _) => bug ! ( "bound ty during ctfe" ) ,
89+ ty:: Bool
90+ | ty:: Char
91+ | ty:: Int ( _)
92+ | ty:: Uint ( _)
93+ | ty:: Float ( _)
94+ | ty:: Foreign ( _)
95+ | ty:: Str
96+ | ty:: Array ( _, _)
97+ | ty:: Slice ( _)
98+ | ty:: RawPtr ( _, _)
99+ | ty:: Ref ( _, _, _)
100+ | ty:: FnDef ( _, _)
101+ | ty:: FnPtr ( ..)
102+ | ty:: Dynamic ( _, _, _)
103+ | ty:: Closure ( _, _)
104+ | ty:: CoroutineClosure ( _, _)
105+ | ty:: Coroutine ( _, _)
106+ | ty:: CoroutineWitness ( ..)
107+ | ty:: UnsafeBinder ( _)
108+ | ty:: Never
109+ | ty:: Tuple ( _)
110+ | ty:: Error ( _) => ConstValue :: from_target_usize ( 0u64 , & tcx) ,
111+ } ;
112+ let val = self . const_val_to_op ( val, dest. layout . ty , Some ( dest. layout ) ) ?;
113+ self . copy_op ( & val, dest) ?;
114+ }
115+
115116 sym:: caller_location => {
116117 let span = self . find_closest_untracked_caller_location ( ) ;
117118 let val = self . tcx . span_as_caller_location ( span) ;
@@ -137,21 +138,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
137138 self . write_scalar ( Scalar :: from_target_usize ( result, self ) , dest) ?;
138139 }
139140
140- sym:: needs_drop | sym:: type_id | sym:: type_name | sym:: variant_count => {
141- let gid = GlobalId { instance, promoted : None } ;
142- let ty = self
143- . tcx
144- . fn_sig ( instance. def_id ( ) )
145- . instantiate ( self . tcx . tcx , instance. args )
146- . output ( )
147- . no_bound_vars ( )
148- . unwrap ( ) ;
149- let val = self
150- . ctfe_query ( |tcx| tcx. const_eval_global_id ( self . typing_env , gid, tcx. span ) ) ?;
151- let val = self . const_val_to_op ( val, ty, Some ( dest. layout ) ) ?;
152- self . copy_op ( & val, dest) ?;
153- }
154-
155141 sym:: fadd_algebraic
156142 | sym:: fsub_algebraic
157143 | sym:: fmul_algebraic
0 commit comments