@@ -5,10 +5,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
5
5
use rustc_middle:: mir:: interpret:: {
6
6
read_target_uint, AllocId , ConstAllocation , ConstValue , ErrorHandled , GlobalAlloc , Scalar ,
7
7
} ;
8
- use rustc_middle:: ty:: ConstKind ;
9
8
use rustc_span:: DUMMY_SP ;
10
9
11
- use cranelift_codegen:: ir:: GlobalValueData ;
12
10
use cranelift_module:: * ;
13
11
14
12
use crate :: prelude:: * ;
@@ -41,36 +39,22 @@ impl ConstantCx {
41
39
pub ( crate ) fn check_constants ( fx : & mut FunctionCx < ' _ , ' _ , ' _ > ) -> bool {
42
40
let mut all_constants_ok = true ;
43
41
for constant in & fx. mir . required_consts {
44
- let const_ = match fx. monomorphize ( constant. literal ) {
45
- ConstantKind :: Ty ( ct) => ct,
42
+ let unevaluated = match fx. monomorphize ( constant. literal ) {
43
+ ConstantKind :: Ty ( _) => unreachable ! ( ) ,
44
+ ConstantKind :: Unevaluated ( uv, _) => uv,
46
45
ConstantKind :: Val ( ..) => continue ,
47
46
} ;
48
- match const_. kind ( ) {
49
- ConstKind :: Value ( _) => { }
50
- ConstKind :: Unevaluated ( unevaluated) => {
51
- if let Err ( err) =
52
- fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None )
53
- {
54
- all_constants_ok = false ;
55
- match err {
56
- ErrorHandled :: Reported ( _) | ErrorHandled :: Linted => {
57
- fx. tcx . sess . span_err ( constant. span , "erroneous constant encountered" ) ;
58
- }
59
- ErrorHandled :: TooGeneric => {
60
- span_bug ! (
61
- constant. span,
62
- "codegen encountered polymorphic constant: {:?}" ,
63
- err
64
- ) ;
65
- }
66
- }
47
+
48
+ if let Err ( err) = fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None ) {
49
+ all_constants_ok = false ;
50
+ match err {
51
+ ErrorHandled :: Reported ( _) | ErrorHandled :: Linted => {
52
+ fx. tcx . sess . span_err ( constant. span , "erroneous constant encountered" ) ;
53
+ }
54
+ ErrorHandled :: TooGeneric => {
55
+ span_bug ! ( constant. span, "codegen encountered polymorphic constant: {:?}" , err) ;
67
56
}
68
57
}
69
- ConstKind :: Param ( _)
70
- | ConstKind :: Infer ( _)
71
- | ConstKind :: Bound ( _, _)
72
- | ConstKind :: Placeholder ( _)
73
- | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , const_) ,
74
58
}
75
59
}
76
60
all_constants_ok
@@ -96,62 +80,47 @@ pub(crate) fn codegen_tls_ref<'tcx>(
96
80
CValue :: by_val ( tls_ptr, layout)
97
81
}
98
82
99
- fn codegen_static_ref < ' tcx > (
100
- fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
101
- def_id : DefId ,
102
- layout : TyAndLayout < ' tcx > ,
103
- ) -> CPlace < ' tcx > {
104
- let data_id = data_id_for_static ( fx. tcx , fx. module , def_id, false ) ;
105
- let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
106
- if fx. clif_comments . enabled ( ) {
107
- fx. add_comment ( local_data_id, format ! ( "{:?}" , def_id) ) ;
108
- }
109
- let global_ptr = fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id) ;
110
- assert ! ( !layout. is_unsized( ) , "unsized statics aren't supported" ) ;
111
- assert ! (
112
- matches!(
113
- fx. bcx. func. global_values[ local_data_id] ,
114
- GlobalValueData :: Symbol { tls: false , .. }
115
- ) ,
116
- "tls static referenced without Rvalue::ThreadLocalRef"
117
- ) ;
118
- CPlace :: for_ptr ( crate :: pointer:: Pointer :: new ( global_ptr) , layout)
119
- }
120
-
121
- pub ( crate ) fn codegen_constant < ' tcx > (
83
+ pub ( crate ) fn eval_mir_constant < ' tcx > (
122
84
fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
123
85
constant : & Constant < ' tcx > ,
124
- ) -> CValue < ' tcx > {
125
- let const_ = match fx. monomorphize ( constant. literal ) {
126
- ConstantKind :: Ty ( ct) => ct,
127
- ConstantKind :: Val ( val, ty) => return codegen_const_value ( fx, val, ty) ,
128
- } ;
129
- let const_val = match const_. kind ( ) {
130
- ConstKind :: Value ( valtree) => fx. tcx . valtree_to_const_val ( ( const_. ty ( ) , valtree) ) ,
131
- ConstKind :: Unevaluated ( ty:: Unevaluated { def, substs, promoted } )
86
+ ) -> ( ConstValue < ' tcx > , Ty < ' tcx > ) {
87
+ let constant_kind = fx. monomorphize ( constant. literal ) ;
88
+ let uv = match constant_kind {
89
+ ConstantKind :: Ty ( const_) => match const_. kind ( ) {
90
+ ty:: ConstKind :: Unevaluated ( uv) => uv. expand ( ) ,
91
+ ty:: ConstKind :: Value ( val) => {
92
+ return ( fx. tcx . valtree_to_const_val ( ( const_. ty ( ) , val) ) , const_. ty ( ) ) ;
93
+ }
94
+ err => span_bug ! (
95
+ constant. span,
96
+ "encountered bad ConstKind after monomorphizing: {:?}" ,
97
+ err
98
+ ) ,
99
+ } ,
100
+ ConstantKind :: Unevaluated ( mir:: UnevaluatedConst { def, .. } , _)
132
101
if fx. tcx . is_static ( def. did ) =>
133
102
{
134
- assert ! ( substs. is_empty( ) ) ;
135
- assert ! ( promoted. is_none( ) ) ;
136
-
137
- return codegen_static_ref ( fx, def. did , fx. layout_of ( const_. ty ( ) ) ) . to_cvalue ( fx) ;
138
- }
139
- ConstKind :: Unevaluated ( unevaluated) => {
140
- match fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None ) {
141
- Ok ( const_val) => const_val,
142
- Err ( _) => {
143
- span_bug ! ( constant. span, "erroneous constant not captured by required_consts" ) ;
144
- }
145
- }
103
+ span_bug ! ( constant. span, "MIR constant refers to static" ) ;
146
104
}
147
- ConstKind :: Param ( _)
148
- | ConstKind :: Infer ( _)
149
- | ConstKind :: Bound ( _, _)
150
- | ConstKind :: Placeholder ( _)
151
- | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , const_) ,
105
+ ConstantKind :: Unevaluated ( uv, _) => uv,
106
+ ConstantKind :: Val ( val, _) => return ( val, constant_kind. ty ( ) ) ,
152
107
} ;
153
108
154
- codegen_const_value ( fx, const_val, const_. ty ( ) )
109
+ (
110
+ fx. tcx . const_eval_resolve ( ty:: ParamEnv :: reveal_all ( ) , uv, None ) . unwrap_or_else ( |_err| {
111
+ span_bug ! ( constant. span, "erroneous constant not captured by required_consts" ) ;
112
+ } ) ,
113
+ constant_kind. ty ( ) ,
114
+ )
115
+ }
116
+
117
+ pub ( crate ) fn codegen_constant_operand < ' tcx > (
118
+ fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
119
+ constant : & Constant < ' tcx > ,
120
+ ) -> CValue < ' tcx > {
121
+ let ( const_val, ty) = eval_mir_constant ( fx, constant) ;
122
+
123
+ codegen_const_value ( fx, const_val, ty)
155
124
}
156
125
157
126
pub ( crate ) fn codegen_const_value < ' tcx > (
@@ -490,12 +459,14 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
490
459
operand : & Operand < ' tcx > ,
491
460
) -> Option < ConstValue < ' tcx > > {
492
461
match operand {
493
- Operand :: Constant ( const_) => match const_. literal {
494
- ConstantKind :: Ty ( const_) => fx
495
- . monomorphize ( const_)
496
- . eval_for_mir ( fx. tcx , ParamEnv :: reveal_all ( ) )
497
- . try_to_value ( fx. tcx ) ,
462
+ Operand :: Constant ( const_) => match fx. monomorphize ( const_. literal ) {
463
+ ConstantKind :: Ty ( const_) => Some (
464
+ const_. eval_for_mir ( fx. tcx , ParamEnv :: reveal_all ( ) ) . try_to_value ( fx. tcx ) . unwrap ( ) ,
465
+ ) ,
498
466
ConstantKind :: Val ( val, _) => Some ( val) ,
467
+ ConstantKind :: Unevaluated ( uv, _) => {
468
+ Some ( fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , uv, None ) . unwrap ( ) )
469
+ }
499
470
} ,
500
471
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
501
472
// inside a temporary before being passed to the intrinsic requiring the const argument.
0 commit comments