@@ -214,38 +214,62 @@ impl TyKind {
214
214
if let TyKind::RigidTy(inner) = self { Some(inner) } else { None }
215
215
}
216
216
217
+ #[inline]
217
218
pub fn is_unit(&self) -> bool {
218
219
matches!(self, TyKind::RigidTy(RigidTy::Tuple(data)) if data.is_empty())
219
220
}
220
221
222
+ #[inline]
221
223
pub fn is_bool(&self) -> bool {
222
224
matches!(self, TyKind::RigidTy(RigidTy::Bool))
223
225
}
224
226
227
+ #[inline]
228
+ pub fn is_char(&self) -> bool {
229
+ matches!(self, TyKind::RigidTy(RigidTy::Char))
230
+ }
231
+
232
+ #[inline]
225
233
pub fn is_trait(&self) -> bool {
226
234
matches!(self, TyKind::RigidTy(RigidTy::Dynamic(_, _, DynKind::Dyn)))
227
235
}
228
236
237
+ #[inline]
229
238
pub fn is_enum(&self) -> bool {
230
239
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Enum)
231
240
}
232
241
242
+ #[inline]
233
243
pub fn is_struct(&self) -> bool {
234
244
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Struct)
235
245
}
236
246
247
+ #[inline]
237
248
pub fn is_union(&self) -> bool {
238
249
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Union)
239
250
}
240
251
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]
241
263
pub fn is_fn(&self) -> bool {
242
264
matches!(self, TyKind::RigidTy(RigidTy::FnDef(..)))
243
265
}
244
266
267
+ #[inline]
245
268
pub fn is_fn_ptr(&self) -> bool {
246
269
matches!(self, TyKind::RigidTy(RigidTy::FnPtr(..)))
247
270
}
248
271
272
+ #[inline]
249
273
pub fn is_primitive(&self) -> bool {
250
274
matches!(
251
275
self,
@@ -259,6 +283,102 @@ impl TyKind {
259
283
)
260
284
}
261
285
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
+
262
382
pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
263
383
if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
264
384
if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
@@ -300,12 +420,12 @@ impl TyKind {
300
420
}
301
421
}
302
422
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)
305
424
pub fn fn_sig(&self) -> Option<PolyFnSig> {
306
425
match self {
307
426
TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
308
427
TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
428
+ TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
309
429
_ => None,
310
430
}
311
431
}
@@ -481,6 +601,10 @@ impl AdtDef {
481
601
with(|cx| cx.adt_is_box(*self))
482
602
}
483
603
604
+ pub fn is_simd(&self) -> bool {
605
+ with(|cx| cx.adt_is_simd(*self))
606
+ }
607
+
484
608
/// The number of variants in this ADT.
485
609
pub fn num_variants(&self) -> usize {
486
610
with(|cx| cx.adt_variants_len(*self))
@@ -738,13 +862,24 @@ pub enum Abi {
738
862
RiscvInterruptS,
739
863
}
740
864
865
+ /// A Binder<T> represents a possibly generic type and its bound vars.
741
866
#[derive(Clone, Debug, Eq, PartialEq)]
742
867
pub struct Binder<T> {
743
868
pub value: T,
744
869
pub bound_vars: Vec<BoundVariableKind>,
745
870
}
746
871
747
872
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
+
748
883
pub fn skip_binder(self) -> T {
749
884
self.value
750
885
}
0 commit comments