@@ -41,9 +41,9 @@ impl Lower128Bit {
4141 let ( basic_blocks, local_decls) = mir. basic_blocks_and_local_decls_mut ( ) ;
4242 for block in basic_blocks. iter_mut ( ) {
4343 for i in ( 0 ..block. statements . len ( ) ) . rev ( ) {
44- let call_did =
45- if let Some ( call_did ) = lower_to ( & block. statements [ i] , local_decls, tcx) {
46- call_did
44+ let lang_item =
45+ if let Some ( lang_item ) = lower_to ( & block. statements [ i] , local_decls, tcx) {
46+ lang_item
4747 } else {
4848 continue ;
4949 } ;
@@ -71,6 +71,9 @@ impl Lower128Bit {
7171 _ => bug ! ( "Statement doesn't match pattern any more?" ) ,
7272 } ;
7373
74+ let call_did = check_lang_item_type (
75+ lang_item, & lvalue, & lhs, & rhs, local_decls, tcx) ;
76+
7477 let bb = BasicBlock :: new ( cur_len + new_blocks. len ( ) ) ;
7578 new_blocks. push ( after_call) ;
7679
@@ -92,33 +95,51 @@ impl Lower128Bit {
9295 }
9396}
9497
98+ fn check_lang_item_type < ' a , ' tcx , D > (
99+ lang_item : LangItem ,
100+ lvalue : & Lvalue < ' tcx > ,
101+ lhs : & Operand < ' tcx > ,
102+ rhs : & Operand < ' tcx > ,
103+ local_decls : & D ,
104+ tcx : TyCtxt < ' a , ' tcx , ' tcx > )
105+ -> DefId
106+ where D : HasLocalDecls < ' tcx >
107+ {
108+ let did = tcx. require_lang_item ( lang_item) ;
109+ let poly_sig = tcx. fn_sig ( did) ;
110+ let sig = tcx. no_late_bound_regions ( & poly_sig) . unwrap ( ) ;
111+ let lhs_ty = lhs. ty ( local_decls, tcx) ;
112+ let rhs_ty = rhs. ty ( local_decls, tcx) ;
113+ let lvalue_ty = lvalue. ty ( local_decls, tcx) . to_ty ( tcx) ;
114+ let expected = [ lhs_ty, rhs_ty, lvalue_ty] ;
115+ assert_eq ! ( sig. inputs_and_output[ ..] , expected,
116+ "lang item {}" , tcx. def_symbol_name( did) ) ;
117+ did
118+ }
119+
95120fn lower_to < ' a , ' tcx , D > ( statement : & Statement < ' tcx > , local_decls : & D , tcx : TyCtxt < ' a , ' tcx , ' tcx > )
96- -> Option < DefId >
121+ -> Option < LangItem >
97122 where D : HasLocalDecls < ' tcx >
98123{
99124 match statement. kind {
100125 StatementKind :: Assign ( _, Rvalue :: BinaryOp ( bin_op, ref lhs, _) ) => {
101126 let ty = lhs. ty ( local_decls, tcx) ;
102- if let Some ( is_signed) = sign_of_128bit ( & ty) {
103- if let Some ( item) = item_for_op ( bin_op, is_signed) {
104- return Some ( tcx. require_lang_item ( item) )
105- }
127+ if let Some ( is_signed) = sign_of_128bit ( ty) {
128+ return item_for_op ( bin_op, is_signed) ;
106129 }
107130 } ,
108131 StatementKind :: Assign ( _, Rvalue :: CheckedBinaryOp ( bin_op, ref lhs, _) ) => {
109132 let ty = lhs. ty ( local_decls, tcx) ;
110- if let Some ( is_signed) = sign_of_128bit ( & ty) {
111- if let Some ( item) = item_for_checked_op ( bin_op, is_signed) {
112- return Some ( tcx. require_lang_item ( item) )
113- }
133+ if let Some ( is_signed) = sign_of_128bit ( ty) {
134+ return item_for_checked_op ( bin_op, is_signed) ;
114135 }
115136 } ,
116137 _ => { } ,
117138 }
118139 None
119140}
120141
121- fn sign_of_128bit ( ty : & Ty ) -> Option < bool > {
142+ fn sign_of_128bit ( ty : Ty ) -> Option < bool > {
122143 match ty. sty {
123144 TypeVariants :: TyInt ( syntax:: ast:: IntTy :: I128 ) => Some ( true ) ,
124145 TypeVariants :: TyUint ( syntax:: ast:: UintTy :: U128 ) => Some ( false ) ,
@@ -128,14 +149,18 @@ fn sign_of_128bit(ty: &Ty) -> Option<bool> {
128149
129150fn item_for_op ( bin_op : BinOp , is_signed : bool ) -> Option < LangItem > {
130151 let i = match ( bin_op, is_signed) {
131- ( BinOp :: Add , _) => LangItem :: I128AddFnLangItem ,
132- ( BinOp :: Sub , _) => LangItem :: I128SubFnLangItem ,
133- ( BinOp :: Mul , _) => LangItem :: I128MulFnLangItem ,
152+ ( BinOp :: Add , true ) => LangItem :: I128AddFnLangItem ,
153+ ( BinOp :: Add , false ) => LangItem :: U128AddFnLangItem ,
154+ ( BinOp :: Sub , true ) => LangItem :: I128SubFnLangItem ,
155+ ( BinOp :: Sub , false ) => LangItem :: U128SubFnLangItem ,
156+ ( BinOp :: Mul , true ) => LangItem :: I128MulFnLangItem ,
157+ ( BinOp :: Mul , false ) => LangItem :: U128MulFnLangItem ,
134158 ( BinOp :: Div , true ) => LangItem :: I128DivFnLangItem ,
135159 ( BinOp :: Div , false ) => LangItem :: U128DivFnLangItem ,
136160 ( BinOp :: Rem , true ) => LangItem :: I128RemFnLangItem ,
137161 ( BinOp :: Rem , false ) => LangItem :: U128RemFnLangItem ,
138- ( BinOp :: Shl , _) => LangItem :: I128ShlFnLangItem ,
162+ ( BinOp :: Shl , true ) => LangItem :: I128ShlFnLangItem ,
163+ ( BinOp :: Shl , false ) => LangItem :: U128ShlFnLangItem ,
139164 ( BinOp :: Shr , true ) => LangItem :: I128ShrFnLangItem ,
140165 ( BinOp :: Shr , false ) => LangItem :: U128ShrFnLangItem ,
141166 _ => return None ,
@@ -151,10 +176,11 @@ fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<LangItem> {
151176 ( BinOp :: Sub , false ) => LangItem :: U128SuboFnLangItem ,
152177 ( BinOp :: Mul , true ) => LangItem :: I128MuloFnLangItem ,
153178 ( BinOp :: Mul , false ) => LangItem :: U128MuloFnLangItem ,
154- ( BinOp :: Shl , _) => LangItem :: I128ShloFnLangItem ,
179+ ( BinOp :: Shl , true ) => LangItem :: I128ShloFnLangItem ,
180+ ( BinOp :: Shl , false ) => LangItem :: U128ShloFnLangItem ,
155181 ( BinOp :: Shr , true ) => LangItem :: I128ShroFnLangItem ,
156182 ( BinOp :: Shr , false ) => LangItem :: U128ShroFnLangItem ,
157- _ => return None ,
183+ _ => bug ! ( "That should be all the checked ones?" ) ,
158184 } ;
159185 Some ( i)
160186}
0 commit comments