@@ -111,6 +111,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
111111 }
112112 false
113113 }
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+ }
114129
115130 fn check_asm_operand_type (
116131 & self ,
@@ -122,9 +137,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
122137 tied_input : Option < ( & hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
123138 target_features : & FxHashSet < Symbol > ,
124139 ) -> Option < InlineAsmType > {
140+ let fcx = self . fcx . unwrap_or_else ( || span_bug ! ( expr. span, "asm operand for global asm" ) ) ;
125141 // 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) ;
128144 let asm_ty_isize = match self . tcx . sess . target . pointer_width {
129145 16 => InlineAsmType :: I16 ,
130146 32 => InlineAsmType :: I32 ,
@@ -134,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
134150
135151 // Expect types to be fully resolved, no const or type variables.
136152 if ty. has_infer_types_or_consts ( ) {
137- assert ! ( self . is_tainted_by_errors( ) ) ;
153+ assert ! ( fcx . is_tainted_by_errors( ) ) ;
138154 return None ;
139155 }
140156
@@ -151,7 +167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
151167 ty:: Float ( FloatTy :: F32 ) => Some ( InlineAsmType :: F32 ) ,
152168 ty:: Float ( FloatTy :: F64 ) => Some ( InlineAsmType :: F64 ) ,
153169 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) => {
155171 Some ( asm_ty_isize)
156172 }
157173 ty:: Adt ( adt, substs) if adt. repr ( ) . simd ( ) => {
@@ -203,7 +219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
203219
204220 // Check that the type implements Copy. The only case where this can
205221 // 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 ) {
207223 let msg = "arguments for inline assembly must be copyable" ;
208224 let mut err = self . tcx . sess . struct_span_err ( expr. span , msg) ;
209225 err. note ( & format ! ( "`{ty}` does not implement the Copy trait" ) ) ;
@@ -224,8 +240,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
224240 let msg = "incompatible types for asm inout argument" ;
225241 let mut err = self . tcx . sess . struct_span_err ( vec ! [ in_expr. span, expr. span] , msg) ;
226242
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) ;
229245 err. span_label ( in_expr. span , & format ! ( "type `{in_expr_ty}`" ) ) ;
230246 err. span_label ( expr. span , & format ! ( "type `{ty}`" ) ) ;
231247 err. note (
0 commit comments