Skip to content

Commit 2f790af

Browse files
committed
Fix BinOp ty assertion and fn_sig for closures
Also added a few more util methods to TyKind to check for specific types.
1 parent 8a37655 commit 2f790af

File tree

4 files changed

+167
-12
lines changed

4 files changed

+167
-12
lines changed

compiler/rustc_smir/src/rustc_smir/context.rs

Lines changed: 12 additions & 0 deletions
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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 12 additions & 10 deletions
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,10 @@ 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());
281+
let lhs_kind = lhs_ty.kind();
282+
let rhs_kind = rhs_ty.kind();
283+
assert!(lhs_kind.is_primitive() || lhs_kind.is_any_ptr());
284+
assert!(rhs_kind.is_primitive() || rhs_kind.is_any_ptr());
283285
match self {
284286
BinOp::Add
285287
| BinOp::AddUnchecked
@@ -306,7 +308,7 @@ impl BinOp {
306308
}
307309
}
308310

309-
#[derive(Clone, Debug, Eq, PartialEq)]
311+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
310312
pub enum UnOp {
311313
Not,
312314
Neg,
@@ -319,7 +321,7 @@ pub enum CoroutineKind {
319321
Gen(CoroutineSource),
320322
}
321323

322-
#[derive(Clone, Debug, Eq, PartialEq)]
324+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
323325
pub enum CoroutineSource {
324326
Block,
325327
Closure,
@@ -343,15 +345,15 @@ pub enum FakeReadCause {
343345
}
344346

345347
/// Describes what kind of retag is to be performed
346-
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
348+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
347349
pub enum RetagKind {
348350
FnEntry,
349351
TwoPhase,
350352
Raw,
351353
Default,
352354
}
353355

354-
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
356+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
355357
pub enum Variance {
356358
Covariant,
357359
Invariant,
@@ -862,7 +864,7 @@ pub enum Safety {
862864
Normal,
863865
}
864866

865-
#[derive(Clone, Debug, Eq, PartialEq)]
867+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
866868
pub enum PointerCoercion {
867869
/// Go from a fn-item type to a fn-pointer type.
868870
ReifyFnPointer,
@@ -889,7 +891,7 @@ pub enum PointerCoercion {
889891
Unsize,
890892
}
891893

892-
#[derive(Clone, Debug, Eq, PartialEq)]
894+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
893895
pub enum CastKind {
894896
PointerExposeAddress,
895897
PointerFromExposedAddress,

compiler/stable_mir/src/ty.rs

Lines changed: 137 additions & 2 deletions
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,102 @@ impl TyKind {
259283
)
260284
}
261285

286+
/// A scalar type is one that denotes an atomic datum, with no sub-components.
287+
/// (A RawPtr is scalar because it represents a non-managed pointer, so its
288+
/// contents are abstract to rustc.)
289+
#[inline]
290+
pub fn is_scalar(&self) -> bool {
291+
matches!(
292+
self,
293+
TyKind::RigidTy(RigidTy::Bool)
294+
| TyKind::RigidTy(RigidTy::Char)
295+
| TyKind::RigidTy(RigidTy::Int(_))
296+
| TyKind::RigidTy(RigidTy::Float(_))
297+
| TyKind::RigidTy(RigidTy::Uint(_))
298+
| TyKind::RigidTy(RigidTy::FnDef(..))
299+
| TyKind::RigidTy(RigidTy::FnPtr(_))
300+
| TyKind::RigidTy(RigidTy::RawPtr(..))
301+
)
302+
}
303+
304+
#[inline]
305+
pub fn is_float(&self) -> bool {
306+
matches!(self, TyKind::RigidTy(RigidTy::Float(_)))
307+
}
308+
309+
#[inline]
310+
pub fn is_integral(&self) -> bool {
311+
matches!(self, TyKind::RigidTy(RigidTy::Int(_) | RigidTy::Uint(_)))
312+
}
313+
314+
#[inline]
315+
pub fn is_numeric(&self) -> bool {
316+
self.is_integral() || self.is_float()
317+
}
318+
319+
#[inline]
320+
pub fn is_signed(&self) -> bool {
321+
matches!(self, TyKind::RigidTy(RigidTy::Int(_)))
322+
}
323+
324+
#[inline]
325+
pub fn is_str(&self) -> bool {
326+
*self == TyKind::RigidTy(RigidTy::Str)
327+
}
328+
329+
#[inline]
330+
pub fn is_slice(&self) -> bool {
331+
matches!(self, TyKind::RigidTy(RigidTy::Slice(_)))
332+
}
333+
334+
#[inline]
335+
pub fn is_array(&self) -> bool {
336+
matches!(self, TyKind::RigidTy(RigidTy::Array(..)))
337+
}
338+
339+
#[inline]
340+
pub fn is_mutable_ptr(&self) -> bool {
341+
matches!(
342+
self,
343+
TyKind::RigidTy(RigidTy::RawPtr(_, Mutability::Mut))
344+
| TyKind::RigidTy(RigidTy::Ref(_, _, Mutability::Mut))
345+
)
346+
}
347+
348+
#[inline]
349+
pub fn is_raw_ptr(&self) -> bool {
350+
matches!(self, TyKind::RigidTy(RigidTy::RawPtr(..)))
351+
}
352+
353+
/// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
354+
#[inline]
355+
pub fn is_any_ptr(&self) -> bool {
356+
self.is_ref() || self.is_raw_ptr() || self.is_fn_ptr()
357+
}
358+
359+
#[inline]
360+
pub fn is_coroutine(&self) -> bool {
361+
matches!(self, TyKind::RigidTy(RigidTy::Coroutine(..)))
362+
}
363+
364+
#[inline]
365+
pub fn is_closure(&self) -> bool {
366+
matches!(self, TyKind::RigidTy(RigidTy::Closure(..)))
367+
}
368+
369+
#[inline]
370+
pub fn is_box(&self) -> bool {
371+
match self {
372+
TyKind::RigidTy(RigidTy::Adt(def, _)) => def.is_box(),
373+
_ => false,
374+
}
375+
}
376+
377+
#[inline]
378+
pub fn is_simd(&self) -> bool {
379+
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_simd())
380+
}
381+
262382
pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
263383
if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
264384
if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
@@ -300,12 +420,12 @@ impl TyKind {
300420
}
301421
}
302422

303-
/// Get the function signature for function like types (Fn, FnPtr, Closure, Coroutine)
304-
/// FIXME(closure)
423+
/// Get the function signature for function like types (Fn, FnPtr, and Closure)
305424
pub fn fn_sig(&self) -> Option<PolyFnSig> {
306425
match self {
307426
TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
308427
TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
428+
TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
309429
_ => None,
310430
}
311431
}
@@ -481,6 +601,10 @@ impl AdtDef {
481601
with(|cx| cx.adt_is_box(*self))
482602
}
483603

604+
pub fn is_simd(&self) -> bool {
605+
with(|cx| cx.adt_is_simd(*self))
606+
}
607+
484608
/// The number of variants in this ADT.
485609
pub fn num_variants(&self) -> usize {
486610
with(|cx| cx.adt_variants_len(*self))
@@ -738,13 +862,24 @@ pub enum Abi {
738862
RiscvInterruptS,
739863
}
740864

865+
/// A Binder<T> represents a possibly generic type and its bound vars.
741866
#[derive(Clone, Debug, Eq, PartialEq)]
742867
pub struct Binder<T> {
743868
pub value: T,
744869
pub bound_vars: Vec<BoundVariableKind>,
745870
}
746871

747872
impl<T> Binder<T> {
873+
/// Create a new binder with the given bound vars.
874+
pub fn new(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
875+
Binder { value, bound_vars }
876+
}
877+
878+
/// Create a new binder with no bounded variable.
879+
pub fn dummy(value: T) -> Self {
880+
Binder { value, bound_vars: vec![] }
881+
}
882+
748883
pub fn skip_binder(self) -> T {
749884
self.value
750885
}

0 commit comments

Comments
 (0)