diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_passes/src/intrinsicck.rs | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index 012d97ef106..96e9a40df36 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -139,6 +139,7 @@ impl ExprVisitor<'tcx> { reg: InlineAsmRegOrRegClass, expr: &hir::Expr<'tcx>, template: &[InlineAsmTemplatePiece], + is_input: bool, tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>, ) -> Option<InlineAsmType> { // Check the type against the allowed types for inline asm. @@ -150,7 +151,9 @@ impl ExprVisitor<'tcx> { _ => unreachable!(), }; let asm_ty = match *ty.kind() { - ty::Never | ty::Error(_) => return None, + // `!` is allowed for input but not for output (issue #87802) + ty::Never if is_input => return None, + ty::Error(_) => return None, ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8), ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16), ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32), @@ -350,24 +353,26 @@ impl ExprVisitor<'tcx> { for (idx, (op, _)) in asm.operands.iter().enumerate() { match *op { hir::InlineAsmOperand::In { reg, ref expr } => { - self.check_asm_operand_type(idx, reg, expr, asm.template, None); + self.check_asm_operand_type(idx, reg, expr, asm.template, true, None); } hir::InlineAsmOperand::Out { reg, late: _, ref expr } => { if let Some(expr) = expr { - self.check_asm_operand_type(idx, reg, expr, asm.template, None); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } } hir::InlineAsmOperand::InOut { reg, late: _, ref expr } => { - self.check_asm_operand_type(idx, reg, expr, asm.template, None); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => { - let in_ty = self.check_asm_operand_type(idx, reg, in_expr, asm.template, None); + let in_ty = + self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None); if let Some(out_expr) = out_expr { self.check_asm_operand_type( idx, reg, out_expr, asm.template, + false, Some((in_expr, in_ty)), ); } |
