@@ -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