@@ -41,9 +41,9 @@ impl Lower128Bit {
41
41
let ( basic_blocks, local_decls) = mir. basic_blocks_and_local_decls_mut ( ) ;
42
42
for block in basic_blocks. iter_mut ( ) {
43
43
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
47
47
} else {
48
48
continue ;
49
49
} ;
@@ -71,6 +71,9 @@ impl Lower128Bit {
71
71
_ => bug ! ( "Statement doesn't match pattern any more?" ) ,
72
72
} ;
73
73
74
+ let call_did = check_lang_item_type (
75
+ lang_item, & lvalue, & lhs, & rhs, local_decls, tcx) ;
76
+
74
77
let bb = BasicBlock :: new ( cur_len + new_blocks. len ( ) ) ;
75
78
new_blocks. push ( after_call) ;
76
79
@@ -92,33 +95,51 @@ impl Lower128Bit {
92
95
}
93
96
}
94
97
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
+
95
120
fn lower_to < ' a , ' tcx , D > ( statement : & Statement < ' tcx > , local_decls : & D , tcx : TyCtxt < ' a , ' tcx , ' tcx > )
96
- -> Option < DefId >
121
+ -> Option < LangItem >
97
122
where D : HasLocalDecls < ' tcx >
98
123
{
99
124
match statement. kind {
100
125
StatementKind :: Assign ( _, Rvalue :: BinaryOp ( bin_op, ref lhs, _) ) => {
101
126
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) ;
106
129
}
107
130
} ,
108
131
StatementKind :: Assign ( _, Rvalue :: CheckedBinaryOp ( bin_op, ref lhs, _) ) => {
109
132
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) ;
114
135
}
115
136
} ,
116
137
_ => { } ,
117
138
}
118
139
None
119
140
}
120
141
121
- fn sign_of_128bit ( ty : & Ty ) -> Option < bool > {
142
+ fn sign_of_128bit ( ty : Ty ) -> Option < bool > {
122
143
match ty. sty {
123
144
TypeVariants :: TyInt ( syntax:: ast:: IntTy :: I128 ) => Some ( true ) ,
124
145
TypeVariants :: TyUint ( syntax:: ast:: UintTy :: U128 ) => Some ( false ) ,
@@ -128,14 +149,18 @@ fn sign_of_128bit(ty: &Ty) -> Option<bool> {
128
149
129
150
fn item_for_op ( bin_op : BinOp , is_signed : bool ) -> Option < LangItem > {
130
151
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 ,
134
158
( BinOp :: Div , true ) => LangItem :: I128DivFnLangItem ,
135
159
( BinOp :: Div , false ) => LangItem :: U128DivFnLangItem ,
136
160
( BinOp :: Rem , true ) => LangItem :: I128RemFnLangItem ,
137
161
( BinOp :: Rem , false ) => LangItem :: U128RemFnLangItem ,
138
- ( BinOp :: Shl , _) => LangItem :: I128ShlFnLangItem ,
162
+ ( BinOp :: Shl , true ) => LangItem :: I128ShlFnLangItem ,
163
+ ( BinOp :: Shl , false ) => LangItem :: U128ShlFnLangItem ,
139
164
( BinOp :: Shr , true ) => LangItem :: I128ShrFnLangItem ,
140
165
( BinOp :: Shr , false ) => LangItem :: U128ShrFnLangItem ,
141
166
_ => return None ,
@@ -151,10 +176,11 @@ fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<LangItem> {
151
176
( BinOp :: Sub , false ) => LangItem :: U128SuboFnLangItem ,
152
177
( BinOp :: Mul , true ) => LangItem :: I128MuloFnLangItem ,
153
178
( BinOp :: Mul , false ) => LangItem :: U128MuloFnLangItem ,
154
- ( BinOp :: Shl , _) => LangItem :: I128ShloFnLangItem ,
179
+ ( BinOp :: Shl , true ) => LangItem :: I128ShloFnLangItem ,
180
+ ( BinOp :: Shl , false ) => LangItem :: U128ShloFnLangItem ,
155
181
( BinOp :: Shr , true ) => LangItem :: I128ShroFnLangItem ,
156
182
( BinOp :: Shr , false ) => LangItem :: U128ShroFnLangItem ,
157
- _ => return None ,
183
+ _ => bug ! ( "That should be all the checked ones?" ) ,
158
184
} ;
159
185
Some ( i)
160
186
}
0 commit comments