@@ -44,31 +44,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
44
44
false
45
45
}
46
46
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 > {
61
48
let asm_ty_isize = match self . tcx . sess . target . pointer_width {
62
49
16 => InlineAsmType :: I16 ,
63
50
32 => InlineAsmType :: I32 ,
64
51
64 => InlineAsmType :: I64 ,
65
52
_ => unreachable ! ( ) ,
66
53
} ;
67
54
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 ( ) {
72
56
ty:: Int ( IntTy :: I8 ) | ty:: Uint ( UintTy :: U8 ) => Some ( InlineAsmType :: I8 ) ,
73
57
ty:: Int ( IntTy :: I16 ) | ty:: Uint ( UintTy :: U16 ) => Some ( InlineAsmType :: I16 ) ,
74
58
ty:: Int ( IntTy :: I32 ) | ty:: Uint ( UintTy :: U32 ) => Some ( InlineAsmType :: I32 ) ,
@@ -99,7 +83,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
99
83
} ;
100
84
101
85
match ty. kind ( ) {
102
- ty:: Never | ty:: Error ( _) => return None ,
103
86
ty:: Int ( IntTy :: I8 ) | ty:: Uint ( UintTy :: U8 ) => Some ( InlineAsmType :: VecI8 ( size) ) ,
104
87
ty:: Int ( IntTy :: I16 ) | ty:: Uint ( UintTy :: U16 ) => {
105
88
Some ( InlineAsmType :: VecI16 ( size) )
@@ -128,6 +111,38 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
128
111
}
129
112
ty:: Infer ( _) => unreachable ! ( ) ,
130
113
_ => 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) ,
131
146
} ;
132
147
let Some ( asm_ty) = asm_ty else {
133
148
let msg = format ! ( "cannot use value of type `{ty}` for inline assembly" ) ;
0 commit comments