@@ -274,6 +274,38 @@ pub enum BinOp {
274
274
Offset ,
275
275
}
276
276
277
+ impl BinOp {
278
+ /// Return the type of this operation for the given input Ty.
279
+ /// This function does not perform type checking, and it currently doesn't handle SIMD.
280
+ 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( ) ) ;
283
+ match self {
284
+ BinOp :: Add
285
+ | BinOp :: AddUnchecked
286
+ | BinOp :: Sub
287
+ | BinOp :: SubUnchecked
288
+ | BinOp :: Mul
289
+ | BinOp :: MulUnchecked
290
+ | BinOp :: Div
291
+ | BinOp :: Rem
292
+ | BinOp :: BitXor
293
+ | BinOp :: BitAnd
294
+ | BinOp :: BitOr => {
295
+ assert_eq ! ( lhs_ty, rhs_ty) ;
296
+ lhs_ty
297
+ }
298
+ BinOp :: Shl | BinOp :: ShlUnchecked | BinOp :: Shr | BinOp :: ShrUnchecked | BinOp :: Offset => {
299
+ lhs_ty
300
+ }
301
+ BinOp :: Eq | BinOp :: Lt | BinOp :: Le | BinOp :: Ne | BinOp :: Ge | BinOp :: Gt => {
302
+ assert_eq ! ( lhs_ty, rhs_ty) ;
303
+ Ty :: bool_ty ( )
304
+ }
305
+ }
306
+ }
307
+ }
308
+
277
309
#[ derive( Clone , Debug , Eq , PartialEq ) ]
278
310
pub enum UnOp {
279
311
Not ,
@@ -475,6 +507,63 @@ pub enum Rvalue {
475
507
Use ( Operand ) ,
476
508
}
477
509
510
+ impl Rvalue {
511
+ pub fn ty ( & self , locals : & [ LocalDecl ] ) -> Result < Ty , Error > {
512
+ match self {
513
+ Rvalue :: Use ( operand) => operand. ty ( locals) ,
514
+ Rvalue :: Repeat ( operand, count) => {
515
+ Ok ( Ty :: new_array_with_const_len ( operand. ty ( locals) ?, count. clone ( ) ) )
516
+ }
517
+ Rvalue :: ThreadLocalRef ( did) => Ok ( did. ty ( ) ) ,
518
+ Rvalue :: Ref ( reg, bk, place) => {
519
+ let place_ty = place. ty ( locals) ?;
520
+ Ok ( Ty :: new_ref ( reg. clone ( ) , place_ty, bk. to_mutable_lossy ( ) ) )
521
+ }
522
+ Rvalue :: AddressOf ( mutability, place) => {
523
+ let place_ty = place. ty ( locals) ?;
524
+ Ok ( Ty :: new_ptr ( place_ty, * mutability) )
525
+ }
526
+ Rvalue :: Len ( ..) => Ok ( Ty :: usize_ty ( ) ) ,
527
+ Rvalue :: Cast ( .., ty) => Ok ( * ty) ,
528
+ Rvalue :: BinaryOp ( op, lhs, rhs) => {
529
+ let lhs_ty = lhs. ty ( locals) ?;
530
+ let rhs_ty = rhs. ty ( locals) ?;
531
+ Ok ( op. ty ( lhs_ty, rhs_ty) )
532
+ }
533
+ Rvalue :: CheckedBinaryOp ( op, lhs, rhs) => {
534
+ let lhs_ty = lhs. ty ( locals) ?;
535
+ let rhs_ty = rhs. ty ( locals) ?;
536
+ let ty = op. ty ( lhs_ty, rhs_ty) ;
537
+ Ok ( Ty :: new_tuple ( & [ ty, Ty :: bool_ty ( ) ] ) )
538
+ }
539
+ Rvalue :: UnaryOp ( UnOp :: Not | UnOp :: Neg , operand) => operand. ty ( locals) ,
540
+ Rvalue :: Discriminant ( place) => {
541
+ let place_ty = place. ty ( locals) ?;
542
+ place_ty
543
+ . kind ( )
544
+ . discriminant_ty ( )
545
+ . ok_or_else ( || error ! ( "Expected a `RigidTy` but found: {place_ty:?}" ) )
546
+ }
547
+ Rvalue :: NullaryOp ( NullOp :: SizeOf | NullOp :: AlignOf | NullOp :: OffsetOf ( ..) , _) => {
548
+ Ok ( Ty :: usize_ty ( ) )
549
+ }
550
+ Rvalue :: Aggregate ( ak, ops) => match * ak {
551
+ AggregateKind :: Array ( ty) => Ty :: try_new_array ( ty, ops. len ( ) as u64 ) ,
552
+ AggregateKind :: Tuple => Ok ( Ty :: new_tuple (
553
+ & ops. iter ( ) . map ( |op| op. ty ( locals) ) . collect :: < Result < Vec < _ > , _ > > ( ) ?,
554
+ ) ) ,
555
+ AggregateKind :: Adt ( def, _, ref args, _, _) => Ok ( def. ty_with_args ( args) ) ,
556
+ AggregateKind :: Closure ( def, ref args) => Ok ( Ty :: new_closure ( def, args. clone ( ) ) ) ,
557
+ AggregateKind :: Coroutine ( def, ref args, mov) => {
558
+ Ok ( Ty :: new_coroutine ( def, args. clone ( ) , mov) )
559
+ }
560
+ } ,
561
+ Rvalue :: ShallowInitBox ( _, ty) => Ok ( Ty :: new_box ( * ty) ) ,
562
+ Rvalue :: CopyForDeref ( place) => place. ty ( locals) ,
563
+ }
564
+ }
565
+ }
566
+
478
567
#[ derive( Clone , Debug , Eq , PartialEq ) ]
479
568
pub enum AggregateKind {
480
569
Array ( Ty ) ,
@@ -725,6 +814,17 @@ pub enum BorrowKind {
725
814
} ,
726
815
}
727
816
817
+ impl BorrowKind {
818
+ pub fn to_mutable_lossy ( self ) -> Mutability {
819
+ match self {
820
+ BorrowKind :: Mut { .. } => Mutability :: Mut ,
821
+ BorrowKind :: Shared => Mutability :: Not ,
822
+ // FIXME: There's no type corresponding to a shallow borrow, so use `&` as an approximation.
823
+ BorrowKind :: Fake => Mutability :: Not ,
824
+ }
825
+ }
826
+ }
827
+
728
828
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
729
829
pub enum MutBorrowKind {
730
830
Default ,
0 commit comments