@@ -9,7 +9,6 @@ use rustc_session::lint;
99use rustc_span:: { Span , Symbol , DUMMY_SP } ;
1010use rustc_target:: abi:: { Pointer , VariantIdx } ;
1111use rustc_target:: asm:: { InlineAsmReg , InlineAsmRegClass , InlineAsmRegOrRegClass , InlineAsmType } ;
12- use rustc_trait_selection:: infer:: InferCtxtExt ;
1312
1413use super :: FnCtxt ;
1514
@@ -98,62 +97,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9897 }
9998 err. emit ( ) ;
10099 }
100+ }
101+
102+ pub struct InlineAsmCtxt < ' a , ' tcx > {
103+ tcx : TyCtxt < ' tcx > ,
104+ param_env : ty:: ParamEnv < ' tcx > ,
105+ get_operand_ty : Box < dyn Fn ( & ' tcx hir:: Expr < ' tcx > ) -> Ty < ' tcx > + ' a > ,
106+ }
107+
108+ impl < ' a , ' tcx > InlineAsmCtxt < ' a , ' tcx > {
109+ pub fn new_global_asm ( tcx : TyCtxt < ' tcx > ) -> Self {
110+ InlineAsmCtxt {
111+ tcx,
112+ param_env : ty:: ParamEnv :: empty ( ) ,
113+ get_operand_ty : Box :: new ( |e| bug ! ( "asm operand in global asm: {e:?}" ) ) ,
114+ }
115+ }
116+
117+ pub fn new_in_fn (
118+ tcx : TyCtxt < ' tcx > ,
119+ param_env : ty:: ParamEnv < ' tcx > ,
120+ get_operand_ty : impl Fn ( & ' tcx hir:: Expr < ' tcx > ) -> Ty < ' tcx > + ' a ,
121+ ) -> Self {
122+ InlineAsmCtxt { tcx, param_env, get_operand_ty : Box :: new ( get_operand_ty) }
123+ }
101124
102125 // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
103126 fn is_thin_ptr_ty ( & self , ty : Ty < ' tcx > ) -> bool {
104127 // Type still may have region variables, but `Sized` does not depend
105128 // on those, so just erase them before querying.
106- if self . tcx . erase_regions ( ty ) . is_sized ( self . tcx . at ( DUMMY_SP ) , self . param_env ) {
129+ if ty . is_sized ( self . tcx . at ( DUMMY_SP ) , self . param_env ) {
107130 return true ;
108131 }
109132 if let ty:: Foreign ( ..) = ty. kind ( ) {
110133 return true ;
111134 }
112135 false
113136 }
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- }
129137
130138 fn check_asm_operand_type (
131139 & self ,
132140 idx : usize ,
133141 reg : InlineAsmRegOrRegClass ,
134- expr : & hir:: Expr < ' tcx > ,
142+ expr : & ' tcx hir:: Expr < ' tcx > ,
135143 template : & [ InlineAsmTemplatePiece ] ,
136144 is_input : bool ,
137- tied_input : Option < ( & hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
145+ tied_input : Option < ( & ' tcx hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
138146 target_features : & FxHashSet < Symbol > ,
139147 ) -> Option < InlineAsmType > {
140- let fcx = self . fcx . unwrap_or_else ( || span_bug ! ( expr. span , "asm operand for global asm" ) ) ;
141- // Check the type against the allowed types for inline asm.
142- let ty = fcx . typeck_results . borrow ( ) . expr_ty_adjusted ( expr) ;
143- let ty = fcx . resolve_vars_if_possible ( ty ) ;
148+ let ty = ( self . get_operand_ty ) ( expr) ;
149+ if ty . has_infer_types_or_consts ( ) {
150+ bug ! ( "inference variable in asm operand ty: {:?} {:?}" , expr, ty ) ;
151+ }
144152 let asm_ty_isize = match self . tcx . sess . target . pointer_width {
145153 16 => InlineAsmType :: I16 ,
146154 32 => InlineAsmType :: I32 ,
147155 64 => InlineAsmType :: I64 ,
148156 _ => unreachable ! ( ) ,
149157 } ;
150158
151- // Expect types to be fully resolved, no const or type variables.
152- if ty. has_infer_types_or_consts ( ) {
153- assert ! ( fcx. is_tainted_by_errors( ) ) ;
154- return None ;
155- }
156-
157159 let asm_ty = match * ty. kind ( ) {
158160 // `!` is allowed for input but not for output (issue #87802)
159161 ty:: Never if is_input => return None ,
@@ -167,7 +169,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
167169 ty:: Float ( FloatTy :: F32 ) => Some ( InlineAsmType :: F32 ) ,
168170 ty:: Float ( FloatTy :: F64 ) => Some ( InlineAsmType :: F64 ) ,
169171 ty:: FnPtr ( _) => Some ( asm_ty_isize) ,
170- ty:: RawPtr ( ty:: TypeAndMut { ty, mutbl : _ } ) if fcx . is_thin_ptr_ty ( ty) => {
172+ ty:: RawPtr ( ty:: TypeAndMut { ty, mutbl : _ } ) if self . is_thin_ptr_ty ( ty) => {
171173 Some ( asm_ty_isize)
172174 }
173175 ty:: Adt ( adt, substs) if adt. repr ( ) . simd ( ) => {
@@ -219,7 +221,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
219221
220222 // Check that the type implements Copy. The only case where this can
221223 // possibly fail is for SIMD types which don't #[derive(Copy)].
222- if !fcx . infcx . type_is_copy_modulo_regions ( fcx . param_env , ty , DUMMY_SP ) {
224+ if !ty . is_copy_modulo_regions ( self . tcx . at ( expr . span ) , self . param_env ) {
223225 let msg = "arguments for inline assembly must be copyable" ;
224226 let mut err = self . tcx . sess . struct_span_err ( expr. span , msg) ;
225227 err. note ( & format ! ( "`{ty}` does not implement the Copy trait" ) ) ;
@@ -240,8 +242,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
240242 let msg = "incompatible types for asm inout argument" ;
241243 let mut err = self . tcx . sess . struct_span_err ( vec ! [ in_expr. span, expr. span] , msg) ;
242244
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) ;
245+ let in_expr_ty = ( self . get_operand_ty ) ( in_expr) ;
245246 err. span_label ( in_expr. span , & format ! ( "type `{in_expr_ty}`" ) ) ;
246247 err. span_label ( expr. span , & format ! ( "type `{ty}`" ) ) ;
247248 err. note (
0 commit comments