Skip to content

Commit d67e80f

Browse files
authored
Rollup merge of rust-lang#118846 - celinval:smir-ty-methods, r=compiler-errors
Fix BinOp `ty()` assertion and `fn_sig()` for closures `BinOp::ty()` was asserting that the argument types were primitives. However, the primitive check doesn't include pointers, which can be used in a `BinaryOperation`. Thus extend the arguments to include them. Since I had to add methods to check for pointers in TyKind, I just went ahead and added a bunch more utility checks that can be handy for our users and fixed the `fn_sig()` method to also include closures. `@compiler-errors` just wanted to confirm that today no `BinaryOperation` accept SIMD types. Is that correct? r? `@compiler-errors`
2 parents cdc4fc9 + 638b08e commit d67e80f

File tree

4 files changed

+156
-13
lines changed

4 files changed

+156
-13
lines changed

compiler/rustc_smir/src/rustc_smir/context.rs

+12
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,25 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
213213
def.internal(&mut *tables).is_box()
214214
}
215215

216+
fn adt_is_simd(&self, def: AdtDef) -> bool {
217+
let mut tables = self.0.borrow_mut();
218+
def.internal(&mut *tables).repr().simd()
219+
}
220+
216221
fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
217222
let mut tables = self.0.borrow_mut();
218223
let def_id = def.0.internal(&mut *tables);
219224
let sig = tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables));
220225
sig.stable(&mut *tables)
221226
}
222227

228+
fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig {
229+
let mut tables = self.0.borrow_mut();
230+
let args_ref = args.internal(&mut *tables);
231+
let sig = args_ref.as_closure().sig();
232+
sig.stable(&mut *tables)
233+
}
234+
223235
fn adt_variants_len(&self, def: AdtDef) -> usize {
224236
let mut tables = self.0.borrow_mut();
225237
def.internal(&mut *tables).variants().len()

compiler/stable_mir/src/compiler_interface.rs

+6
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,15 @@ pub trait Context {
6969
/// Returns if the ADT is a box.
7070
fn adt_is_box(&self, def: AdtDef) -> bool;
7171

72+
/// Returns whether this ADT is simd.
73+
fn adt_is_simd(&self, def: AdtDef) -> bool;
74+
7275
/// Retrieve the function signature for the given generic arguments.
7376
fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig;
7477

78+
/// Retrieve the closure signature for the given generic arguments.
79+
fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig;
80+
7581
/// The number of variants in this ADT.
7682
fn adt_variants_len(&self, def: AdtDef) -> usize;
7783

compiler/stable_mir/src/mir/body.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ pub struct InlineAsmOperand {
228228
pub raw_rpr: String,
229229
}
230230

231-
#[derive(Clone, Debug, Eq, PartialEq)]
231+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
232232
pub enum UnwindAction {
233233
Continue,
234234
Unreachable,
@@ -248,7 +248,7 @@ pub enum AssertMessage {
248248
MisalignedPointerDereference { required: Operand, found: Operand },
249249
}
250250

251-
#[derive(Clone, Debug, Eq, PartialEq)]
251+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
252252
pub enum BinOp {
253253
Add,
254254
AddUnchecked,
@@ -278,8 +278,6 @@ impl BinOp {
278278
/// Return the type of this operation for the given input Ty.
279279
/// This function does not perform type checking, and it currently doesn't handle SIMD.
280280
pub fn ty(&self, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
281-
assert!(lhs_ty.kind().is_primitive());
282-
assert!(rhs_ty.kind().is_primitive());
283281
match self {
284282
BinOp::Add
285283
| BinOp::AddUnchecked
@@ -293,20 +291,30 @@ impl BinOp {
293291
| BinOp::BitAnd
294292
| BinOp::BitOr => {
295293
assert_eq!(lhs_ty, rhs_ty);
294+
assert!(lhs_ty.kind().is_primitive());
296295
lhs_ty
297296
}
298-
BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked | BinOp::Offset => {
297+
BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => {
298+
assert!(lhs_ty.kind().is_primitive());
299+
assert!(rhs_ty.kind().is_primitive());
300+
lhs_ty
301+
}
302+
BinOp::Offset => {
303+
assert!(lhs_ty.kind().is_raw_ptr());
304+
assert!(rhs_ty.kind().is_integral());
299305
lhs_ty
300306
}
301307
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
302308
assert_eq!(lhs_ty, rhs_ty);
309+
let lhs_kind = lhs_ty.kind();
310+
assert!(lhs_kind.is_primitive() || lhs_kind.is_raw_ptr() || lhs_kind.is_fn_ptr());
303311
Ty::bool_ty()
304312
}
305313
}
306314
}
307315
}
308316

309-
#[derive(Clone, Debug, Eq, PartialEq)]
317+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
310318
pub enum UnOp {
311319
Not,
312320
Neg,
@@ -319,7 +327,7 @@ pub enum CoroutineKind {
319327
Gen(CoroutineSource),
320328
}
321329

322-
#[derive(Clone, Debug, Eq, PartialEq)]
330+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
323331
pub enum CoroutineSource {
324332
Block,
325333
Closure,
@@ -343,15 +351,15 @@ pub enum FakeReadCause {
343351
}
344352

345353
/// Describes what kind of retag is to be performed
346-
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
354+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
347355
pub enum RetagKind {
348356
FnEntry,
349357
TwoPhase,
350358
Raw,
351359
Default,
352360
}
353361

354-
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
362+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
355363
pub enum Variance {
356364
Covariant,
357365
Invariant,
@@ -862,7 +870,7 @@ pub enum Safety {
862870
Normal,
863871
}
864872

865-
#[derive(Clone, Debug, Eq, PartialEq)]
873+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
866874
pub enum PointerCoercion {
867875
/// Go from a fn-item type to a fn-pointer type.
868876
ReifyFnPointer,
@@ -889,7 +897,7 @@ pub enum PointerCoercion {
889897
Unsize,
890898
}
891899

892-
#[derive(Clone, Debug, Eq, PartialEq)]
900+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
893901
pub enum CastKind {
894902
PointerExposeAddress,
895903
PointerFromExposedAddress,

compiler/stable_mir/src/ty.rs

+119-2
Original file line numberDiff line numberDiff line change
@@ -214,38 +214,62 @@ impl TyKind {
214214
if let TyKind::RigidTy(inner) = self { Some(inner) } else { None }
215215
}
216216

217+
#[inline]
217218
pub fn is_unit(&self) -> bool {
218219
matches!(self, TyKind::RigidTy(RigidTy::Tuple(data)) if data.is_empty())
219220
}
220221

222+
#[inline]
221223
pub fn is_bool(&self) -> bool {
222224
matches!(self, TyKind::RigidTy(RigidTy::Bool))
223225
}
224226

227+
#[inline]
228+
pub fn is_char(&self) -> bool {
229+
matches!(self, TyKind::RigidTy(RigidTy::Char))
230+
}
231+
232+
#[inline]
225233
pub fn is_trait(&self) -> bool {
226234
matches!(self, TyKind::RigidTy(RigidTy::Dynamic(_, _, DynKind::Dyn)))
227235
}
228236

237+
#[inline]
229238
pub fn is_enum(&self) -> bool {
230239
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Enum)
231240
}
232241

242+
#[inline]
233243
pub fn is_struct(&self) -> bool {
234244
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Struct)
235245
}
236246

247+
#[inline]
237248
pub fn is_union(&self) -> bool {
238249
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Union)
239250
}
240251

252+
#[inline]
253+
pub fn is_adt(&self) -> bool {
254+
matches!(self, TyKind::RigidTy(RigidTy::Adt(..)))
255+
}
256+
257+
#[inline]
258+
pub fn is_ref(&self) -> bool {
259+
matches!(self, TyKind::RigidTy(RigidTy::Ref(..)))
260+
}
261+
262+
#[inline]
241263
pub fn is_fn(&self) -> bool {
242264
matches!(self, TyKind::RigidTy(RigidTy::FnDef(..)))
243265
}
244266

267+
#[inline]
245268
pub fn is_fn_ptr(&self) -> bool {
246269
matches!(self, TyKind::RigidTy(RigidTy::FnPtr(..)))
247270
}
248271

272+
#[inline]
249273
pub fn is_primitive(&self) -> bool {
250274
matches!(
251275
self,
@@ -259,6 +283,84 @@ impl TyKind {
259283
)
260284
}
261285

286+
#[inline]
287+
pub fn is_float(&self) -> bool {
288+
matches!(self, TyKind::RigidTy(RigidTy::Float(_)))
289+
}
290+
291+
#[inline]
292+
pub fn is_integral(&self) -> bool {
293+
matches!(self, TyKind::RigidTy(RigidTy::Int(_) | RigidTy::Uint(_)))
294+
}
295+
296+
#[inline]
297+
pub fn is_numeric(&self) -> bool {
298+
self.is_integral() || self.is_float()
299+
}
300+
301+
#[inline]
302+
pub fn is_signed(&self) -> bool {
303+
matches!(self, TyKind::RigidTy(RigidTy::Int(_)))
304+
}
305+
306+
#[inline]
307+
pub fn is_str(&self) -> bool {
308+
*self == TyKind::RigidTy(RigidTy::Str)
309+
}
310+
311+
#[inline]
312+
pub fn is_slice(&self) -> bool {
313+
matches!(self, TyKind::RigidTy(RigidTy::Slice(_)))
314+
}
315+
316+
#[inline]
317+
pub fn is_array(&self) -> bool {
318+
matches!(self, TyKind::RigidTy(RigidTy::Array(..)))
319+
}
320+
321+
#[inline]
322+
pub fn is_mutable_ptr(&self) -> bool {
323+
matches!(
324+
self,
325+
TyKind::RigidTy(RigidTy::RawPtr(_, Mutability::Mut))
326+
| TyKind::RigidTy(RigidTy::Ref(_, _, Mutability::Mut))
327+
)
328+
}
329+
330+
#[inline]
331+
pub fn is_raw_ptr(&self) -> bool {
332+
matches!(self, TyKind::RigidTy(RigidTy::RawPtr(..)))
333+
}
334+
335+
/// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
336+
#[inline]
337+
pub fn is_any_ptr(&self) -> bool {
338+
self.is_ref() || self.is_raw_ptr() || self.is_fn_ptr()
339+
}
340+
341+
#[inline]
342+
pub fn is_coroutine(&self) -> bool {
343+
matches!(self, TyKind::RigidTy(RigidTy::Coroutine(..)))
344+
}
345+
346+
#[inline]
347+
pub fn is_closure(&self) -> bool {
348+
matches!(self, TyKind::RigidTy(RigidTy::Closure(..)))
349+
}
350+
351+
#[inline]
352+
pub fn is_box(&self) -> bool {
353+
match self {
354+
TyKind::RigidTy(RigidTy::Adt(def, _)) => def.is_box(),
355+
_ => false,
356+
}
357+
}
358+
359+
#[inline]
360+
pub fn is_simd(&self) -> bool {
361+
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_simd())
362+
}
363+
262364
pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
263365
if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
264366
if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
@@ -300,12 +402,12 @@ impl TyKind {
300402
}
301403
}
302404

303-
/// Get the function signature for function like types (Fn, FnPtr, Closure, Coroutine)
304-
/// FIXME(closure)
405+
/// Get the function signature for function like types (Fn, FnPtr, and Closure)
305406
pub fn fn_sig(&self) -> Option<PolyFnSig> {
306407
match self {
307408
TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
308409
TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
410+
TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
309411
_ => None,
310412
}
311413
}
@@ -481,6 +583,10 @@ impl AdtDef {
481583
with(|cx| cx.adt_is_box(*self))
482584
}
483585

586+
pub fn is_simd(&self) -> bool {
587+
with(|cx| cx.adt_is_simd(*self))
588+
}
589+
484590
/// The number of variants in this ADT.
485591
pub fn num_variants(&self) -> usize {
486592
with(|cx| cx.adt_variants_len(*self))
@@ -738,13 +844,24 @@ pub enum Abi {
738844
RiscvInterruptS,
739845
}
740846

847+
/// A binder represents a possibly generic type and its bound vars.
741848
#[derive(Clone, Debug, Eq, PartialEq)]
742849
pub struct Binder<T> {
743850
pub value: T,
744851
pub bound_vars: Vec<BoundVariableKind>,
745852
}
746853

747854
impl<T> Binder<T> {
855+
/// Create a new binder with the given bound vars.
856+
pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
857+
Binder { value, bound_vars }
858+
}
859+
860+
/// Create a new binder with no bounded variable.
861+
pub fn dummy(value: T) -> Self {
862+
Binder { value, bound_vars: vec![] }
863+
}
864+
748865
pub fn skip_binder(self) -> T {
749866
self.value
750867
}

0 commit comments

Comments
 (0)