@@ -206,56 +206,60 @@ impl MirLowerCtx<'_> {
206
206
( current, current_else)
207
207
}
208
208
Pat :: Slice { prefix, slice, suffix } => {
209
- if let TyKind :: Slice ( _) = self . infer [ pattern] . kind ( Interner ) {
210
- let pattern_len = prefix. len ( ) + suffix. len ( ) ;
211
- let place_len: Place =
212
- self . temp ( TyBuilder :: usize ( ) , current, pattern. into ( ) ) ?. into ( ) ;
213
- self . push_assignment (
214
- current,
215
- place_len. clone ( ) ,
216
- Rvalue :: Len ( ( & mut cond_place) . clone ( ) ) ,
217
- pattern. into ( ) ,
218
- ) ;
219
- let else_target = * current_else. get_or_insert_with ( || self . new_basic_block ( ) ) ;
220
- let next = self . new_basic_block ( ) ;
221
- if slice. is_none ( ) {
222
- self . set_terminator (
223
- current,
224
- TerminatorKind :: SwitchInt {
225
- discr : Operand :: Copy ( place_len) ,
226
- targets : SwitchTargets :: static_if (
227
- pattern_len as u128 ,
228
- next,
229
- else_target,
230
- ) ,
231
- } ,
232
- pattern. into ( ) ,
233
- ) ;
234
- } else {
235
- let c = Operand :: from_concrete_const (
236
- pattern_len. to_le_bytes ( ) . to_vec ( ) ,
237
- MemoryMap :: default ( ) ,
238
- TyBuilder :: usize ( ) ,
239
- ) ;
240
- let discr: Place =
241
- self . temp ( TyBuilder :: bool ( ) , current, pattern. into ( ) ) ?. into ( ) ;
209
+ if mode == MatchingMode :: Check {
210
+ // emit runtime length check for slice
211
+ if let TyKind :: Slice ( _) = self . infer [ pattern] . kind ( Interner ) {
212
+ let pattern_len = prefix. len ( ) + suffix. len ( ) ;
213
+ let place_len: Place =
214
+ self . temp ( TyBuilder :: usize ( ) , current, pattern. into ( ) ) ?. into ( ) ;
242
215
self . push_assignment (
243
216
current,
244
- discr. clone ( ) ,
245
- Rvalue :: CheckedBinaryOp ( BinOp :: Le , c, Operand :: Copy ( place_len) ) ,
246
- pattern. into ( ) ,
247
- ) ;
248
- let discr = Operand :: Copy ( discr) ;
249
- self . set_terminator (
250
- current,
251
- TerminatorKind :: SwitchInt {
252
- discr,
253
- targets : SwitchTargets :: static_if ( 1 , next, else_target) ,
254
- } ,
217
+ place_len. clone ( ) ,
218
+ Rvalue :: Len ( ( & mut cond_place) . clone ( ) ) ,
255
219
pattern. into ( ) ,
256
220
) ;
221
+ let else_target =
222
+ * current_else. get_or_insert_with ( || self . new_basic_block ( ) ) ;
223
+ let next = self . new_basic_block ( ) ;
224
+ if slice. is_none ( ) {
225
+ self . set_terminator (
226
+ current,
227
+ TerminatorKind :: SwitchInt {
228
+ discr : Operand :: Copy ( place_len) ,
229
+ targets : SwitchTargets :: static_if (
230
+ pattern_len as u128 ,
231
+ next,
232
+ else_target,
233
+ ) ,
234
+ } ,
235
+ pattern. into ( ) ,
236
+ ) ;
237
+ } else {
238
+ let c = Operand :: from_concrete_const (
239
+ pattern_len. to_le_bytes ( ) . to_vec ( ) ,
240
+ MemoryMap :: default ( ) ,
241
+ TyBuilder :: usize ( ) ,
242
+ ) ;
243
+ let discr: Place =
244
+ self . temp ( TyBuilder :: bool ( ) , current, pattern. into ( ) ) ?. into ( ) ;
245
+ self . push_assignment (
246
+ current,
247
+ discr. clone ( ) ,
248
+ Rvalue :: CheckedBinaryOp ( BinOp :: Le , c, Operand :: Copy ( place_len) ) ,
249
+ pattern. into ( ) ,
250
+ ) ;
251
+ let discr = Operand :: Copy ( discr) ;
252
+ self . set_terminator (
253
+ current,
254
+ TerminatorKind :: SwitchInt {
255
+ discr,
256
+ targets : SwitchTargets :: static_if ( 1 , next, else_target) ,
257
+ } ,
258
+ pattern. into ( ) ,
259
+ ) ;
260
+ }
261
+ current = next;
257
262
}
258
- current = next;
259
263
}
260
264
for ( i, & pat) in prefix. iter ( ) . enumerate ( ) {
261
265
let next_place = ( & mut cond_place) . project ( ProjectionElem :: ConstantIndex {
0 commit comments