@@ -44,31 +44,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
4444 false
4545 }
4646
47- fn check_asm_operand_type (
48- & self ,
49- idx : usize ,
50- reg : InlineAsmRegOrRegClass ,
51- expr : & ' tcx hir:: Expr < ' tcx > ,
52- template : & [ InlineAsmTemplatePiece ] ,
53- is_input : bool ,
54- tied_input : Option < ( & ' tcx hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
55- target_features : & FxIndexSet < Symbol > ,
56- ) -> Option < InlineAsmType > {
57- let ty = ( self . get_operand_ty ) ( expr) ;
58- if ty. has_non_region_infer ( ) {
59- bug ! ( "inference variable in asm operand ty: {:?} {:?}" , expr, ty) ;
60- }
47+ fn get_asm_ty ( & self , ty : Ty < ' tcx > ) -> Option < InlineAsmType > {
6148 let asm_ty_isize = match self . tcx . sess . target . pointer_width {
6249 16 => InlineAsmType :: I16 ,
6350 32 => InlineAsmType :: I32 ,
6451 64 => InlineAsmType :: I64 ,
6552 _ => unreachable ! ( ) ,
6653 } ;
6754
68- let asm_ty = match * ty. kind ( ) {
69- // `!` is allowed for input but not for output (issue #87802)
70- ty:: Never if is_input => return None ,
71- _ if ty. references_error ( ) => return None ,
55+ match * ty. kind ( ) {
7256 ty:: Int ( IntTy :: I8 ) | ty:: Uint ( UintTy :: U8 ) => Some ( InlineAsmType :: I8 ) ,
7357 ty:: Int ( IntTy :: I16 ) | ty:: Uint ( UintTy :: U16 ) => Some ( InlineAsmType :: I16 ) ,
7458 ty:: Int ( IntTy :: I32 ) | ty:: Uint ( UintTy :: U32 ) => Some ( InlineAsmType :: I32 ) ,
@@ -99,7 +83,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
9983 } ;
10084
10185 match ty. kind ( ) {
102- ty:: Never | ty:: Error ( _) => return None ,
10386 ty:: Int ( IntTy :: I8 ) | ty:: Uint ( UintTy :: U8 ) => Some ( InlineAsmType :: VecI8 ( size) ) ,
10487 ty:: Int ( IntTy :: I16 ) | ty:: Uint ( UintTy :: U16 ) => {
10588 Some ( InlineAsmType :: VecI16 ( size) )
@@ -128,6 +111,38 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
128111 }
129112 ty:: Infer ( _) => unreachable ! ( ) ,
130113 _ => None ,
114+ }
115+ }
116+
117+ fn check_asm_operand_type (
118+ & self ,
119+ idx : usize ,
120+ reg : InlineAsmRegOrRegClass ,
121+ expr : & ' tcx hir:: Expr < ' tcx > ,
122+ template : & [ InlineAsmTemplatePiece ] ,
123+ is_input : bool ,
124+ tied_input : Option < ( & ' tcx hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
125+ target_features : & FxIndexSet < Symbol > ,
126+ ) -> Option < InlineAsmType > {
127+ let ty = ( self . get_operand_ty ) ( expr) ;
128+ if ty. has_non_region_infer ( ) {
129+ bug ! ( "inference variable in asm operand ty: {:?} {:?}" , expr, ty) ;
130+ }
131+
132+ let asm_ty = match * ty. kind ( ) {
133+ // `!` is allowed for input but not for output (issue #87802)
134+ ty:: Never if is_input => return None ,
135+ _ if ty. references_error ( ) => return None ,
136+ ty:: Adt ( adt, args) if Some ( adt. did ( ) ) == self . tcx . lang_items ( ) . maybe_uninit ( ) => {
137+ let fields = & adt. non_enum_variant ( ) . fields ;
138+ let ty = fields[ FieldIdx :: from_u32 ( 1 ) ] . ty ( self . tcx , args) ;
139+ let ty:: Adt ( ty, args) = ty. kind ( ) else { unreachable ! ( ) } ;
140+ assert ! ( ty. is_manually_drop( ) ) ;
141+ let fields = & ty. non_enum_variant ( ) . fields ;
142+ let ty = fields[ FieldIdx :: from_u32 ( 0 ) ] . ty ( self . tcx , args) ;
143+ self . get_asm_ty ( ty)
144+ }
145+ _ => self . get_asm_ty ( ty) ,
131146 } ;
132147 let Some ( asm_ty) = asm_ty else {
133148 let msg = format ! ( "cannot use value of type `{ty}` for inline assembly" ) ;
0 commit comments