@@ -111,6 +111,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
111
111
}
112
112
false
113
113
}
114
+ }
115
+
116
+ pub struct InlineAsmCtxt < ' a , ' tcx > {
117
+ tcx : TyCtxt < ' tcx > ,
118
+ fcx : Option < & ' a FnCtxt < ' a , ' tcx > > ,
119
+ }
120
+
121
+ impl < ' a , ' tcx > InlineAsmCtxt < ' a , ' tcx > {
122
+ pub fn new_global_asm ( tcx : TyCtxt < ' tcx > ) -> Self {
123
+ InlineAsmCtxt { tcx, fcx : None }
124
+ }
125
+
126
+ pub fn new_in_fn ( fcx : & ' a FnCtxt < ' a , ' tcx > ) -> Self {
127
+ InlineAsmCtxt { tcx : fcx. tcx , fcx : Some ( fcx) }
128
+ }
114
129
115
130
fn check_asm_operand_type (
116
131
& self ,
@@ -122,9 +137,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
122
137
tied_input : Option < ( & hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
123
138
target_features : & FxHashSet < Symbol > ,
124
139
) -> Option < InlineAsmType > {
140
+ let fcx = self . fcx . unwrap_or_else ( || span_bug ! ( expr. span, "asm operand for global asm" ) ) ;
125
141
// Check the type against the allowed types for inline asm.
126
- let ty = self . typeck_results . borrow ( ) . expr_ty_adjusted ( expr) ;
127
- let ty = self . resolve_vars_if_possible ( ty) ;
142
+ let ty = fcx . typeck_results . borrow ( ) . expr_ty_adjusted ( expr) ;
143
+ let ty = fcx . resolve_vars_if_possible ( ty) ;
128
144
let asm_ty_isize = match self . tcx . sess . target . pointer_width {
129
145
16 => InlineAsmType :: I16 ,
130
146
32 => InlineAsmType :: I32 ,
@@ -134,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
134
150
135
151
// Expect types to be fully resolved, no const or type variables.
136
152
if ty. has_infer_types_or_consts ( ) {
137
- assert ! ( self . is_tainted_by_errors( ) ) ;
153
+ assert ! ( fcx . is_tainted_by_errors( ) ) ;
138
154
return None ;
139
155
}
140
156
@@ -151,7 +167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
151
167
ty:: Float ( FloatTy :: F32 ) => Some ( InlineAsmType :: F32 ) ,
152
168
ty:: Float ( FloatTy :: F64 ) => Some ( InlineAsmType :: F64 ) ,
153
169
ty:: FnPtr ( _) => Some ( asm_ty_isize) ,
154
- ty:: RawPtr ( ty:: TypeAndMut { ty, mutbl : _ } ) if self . is_thin_ptr_ty ( ty) => {
170
+ ty:: RawPtr ( ty:: TypeAndMut { ty, mutbl : _ } ) if fcx . is_thin_ptr_ty ( ty) => {
155
171
Some ( asm_ty_isize)
156
172
}
157
173
ty:: Adt ( adt, substs) if adt. repr ( ) . simd ( ) => {
@@ -203,7 +219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
203
219
204
220
// Check that the type implements Copy. The only case where this can
205
221
// possibly fail is for SIMD types which don't #[derive(Copy)].
206
- if !self . infcx . type_is_copy_modulo_regions ( self . param_env , ty, DUMMY_SP ) {
222
+ if !fcx . infcx . type_is_copy_modulo_regions ( fcx . param_env , ty, DUMMY_SP ) {
207
223
let msg = "arguments for inline assembly must be copyable" ;
208
224
let mut err = self . tcx . sess . struct_span_err ( expr. span , msg) ;
209
225
err. note ( & format ! ( "`{ty}` does not implement the Copy trait" ) ) ;
@@ -224,8 +240,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
224
240
let msg = "incompatible types for asm inout argument" ;
225
241
let mut err = self . tcx . sess . struct_span_err ( vec ! [ in_expr. span, expr. span] , msg) ;
226
242
227
- let in_expr_ty = self . typeck_results . borrow ( ) . expr_ty_adjusted ( in_expr) ;
228
- let in_expr_ty = self . resolve_vars_if_possible ( in_expr_ty) ;
243
+ let in_expr_ty = fcx . typeck_results . borrow ( ) . expr_ty_adjusted ( in_expr) ;
244
+ let in_expr_ty = fcx . resolve_vars_if_possible ( in_expr_ty) ;
229
245
err. span_label ( in_expr. span , & format ! ( "type `{in_expr_ty}`" ) ) ;
230
246
err. span_label ( expr. span , & format ! ( "type `{ty}`" ) ) ;
231
247
err. note (
0 commit comments