@@ -139,6 +139,7 @@ impl ExprVisitor<'tcx> {
139
139
reg : InlineAsmRegOrRegClass ,
140
140
expr : & hir:: Expr < ' tcx > ,
141
141
template : & [ InlineAsmTemplatePiece ] ,
142
+ is_input : bool ,
142
143
tied_input : Option < ( & hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
143
144
) -> Option < InlineAsmType > {
144
145
// Check the type against the allowed types for inline asm.
@@ -150,7 +151,9 @@ impl ExprVisitor<'tcx> {
150
151
_ => unreachable ! ( ) ,
151
152
} ;
152
153
let asm_ty = match * ty. kind ( ) {
153
- ty:: Never | ty:: Error ( _) => return None ,
154
+ // `!` is allowed for input but not for output (issue #87802)
155
+ ty:: Never if is_input => return None ,
156
+ ty:: Error ( _) => return None ,
154
157
ty:: Int ( IntTy :: I8 ) | ty:: Uint ( UintTy :: U8 ) => Some ( InlineAsmType :: I8 ) ,
155
158
ty:: Int ( IntTy :: I16 ) | ty:: Uint ( UintTy :: U16 ) => Some ( InlineAsmType :: I16 ) ,
156
159
ty:: Int ( IntTy :: I32 ) | ty:: Uint ( UintTy :: U32 ) => Some ( InlineAsmType :: I32 ) ,
@@ -350,24 +353,26 @@ impl ExprVisitor<'tcx> {
350
353
for ( idx, ( op, _) ) in asm. operands . iter ( ) . enumerate ( ) {
351
354
match * op {
352
355
hir:: InlineAsmOperand :: In { reg, ref expr } => {
353
- self . check_asm_operand_type ( idx, reg, expr, asm. template , None ) ;
356
+ self . check_asm_operand_type ( idx, reg, expr, asm. template , true , None ) ;
354
357
}
355
358
hir:: InlineAsmOperand :: Out { reg, late : _, ref expr } => {
356
359
if let Some ( expr) = expr {
357
- self . check_asm_operand_type ( idx, reg, expr, asm. template , None ) ;
360
+ self . check_asm_operand_type ( idx, reg, expr, asm. template , false , None ) ;
358
361
}
359
362
}
360
363
hir:: InlineAsmOperand :: InOut { reg, late : _, ref expr } => {
361
- self . check_asm_operand_type ( idx, reg, expr, asm. template , None ) ;
364
+ self . check_asm_operand_type ( idx, reg, expr, asm. template , false , None ) ;
362
365
}
363
366
hir:: InlineAsmOperand :: SplitInOut { reg, late : _, ref in_expr, ref out_expr } => {
364
- let in_ty = self . check_asm_operand_type ( idx, reg, in_expr, asm. template , None ) ;
367
+ let in_ty =
368
+ self . check_asm_operand_type ( idx, reg, in_expr, asm. template , true , None ) ;
365
369
if let Some ( out_expr) = out_expr {
366
370
self . check_asm_operand_type (
367
371
idx,
368
372
reg,
369
373
out_expr,
370
374
asm. template ,
375
+ false ,
371
376
Some ( ( in_expr, in_ty) ) ,
372
377
) ;
373
378
}
0 commit comments