@@ -280,3 +280,277 @@ pub enum LvalueContext {
280
280
// Consumed as part of an operand
281
281
Consume ,
282
282
}
283
+
284
+ pub trait MutVisitor < ' tcx > {
285
+ // Override these, and call `self.super_xxx` to revert back to the
286
+ // default behavior.
287
+
288
+ fn visit_mir ( & mut self , mir : & mut Mir < ' tcx > ) {
289
+ self . super_mir ( mir) ;
290
+ }
291
+
292
+ fn visit_basic_block_data ( & mut self ,
293
+ block : BasicBlock ,
294
+ data : & mut BasicBlockData < ' tcx > ) {
295
+ self . super_basic_block_data ( block, data) ;
296
+ }
297
+
298
+ fn visit_statement ( & mut self ,
299
+ block : BasicBlock ,
300
+ statement : & mut Statement < ' tcx > ) {
301
+ self . super_statement ( block, statement) ;
302
+ }
303
+
304
+ fn visit_assign ( & mut self ,
305
+ block : BasicBlock ,
306
+ lvalue : & mut Lvalue < ' tcx > ,
307
+ rvalue : & mut Rvalue < ' tcx > ) {
308
+ self . super_assign ( block, lvalue, rvalue) ;
309
+ }
310
+
311
+ fn visit_terminator ( & mut self ,
312
+ block : BasicBlock ,
313
+ terminator : & mut Terminator < ' tcx > ) {
314
+ self . super_terminator ( block, terminator) ;
315
+ }
316
+
317
+ fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > ) {
318
+ self . super_rvalue ( rvalue) ;
319
+ }
320
+
321
+ fn visit_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
322
+ self . super_operand ( operand) ;
323
+ }
324
+
325
+ fn visit_lvalue ( & mut self ,
326
+ lvalue : & mut Lvalue < ' tcx > ,
327
+ context : LvalueContext ) {
328
+ self . super_lvalue ( lvalue, context) ;
329
+ }
330
+
331
+ fn visit_branch ( & mut self , source : BasicBlock , target : BasicBlock ) {
332
+ self . super_branch ( source, target) ;
333
+ }
334
+
335
+ fn visit_constant ( & mut self , constant : & mut Constant < ' tcx > ) {
336
+ self . super_constant ( constant) ;
337
+ }
338
+
339
+ fn visit_literal ( & mut self , literal : & mut Literal < ' tcx > ) {
340
+ self . super_literal ( literal) ;
341
+ }
342
+
343
+ fn visit_def_id ( & mut self , def_id : & mut DefId ) {
344
+ self . super_def_id ( def_id) ;
345
+ }
346
+
347
+ fn visit_span ( & mut self , span : & mut Span ) {
348
+ self . super_span ( span) ;
349
+ }
350
+
351
+ // The `super_xxx` methods comprise the default behavior and are
352
+ // not meant to be overidden.
353
+
354
+ fn super_mir ( & mut self , mir : & mut Mir < ' tcx > ) {
355
+ for block in mir. all_basic_blocks ( ) {
356
+ let data = mir. basic_block_data_mut ( block) ;
357
+ self . visit_basic_block_data ( block, data) ;
358
+ }
359
+ }
360
+
361
+ fn super_basic_block_data ( & mut self ,
362
+ block : BasicBlock ,
363
+ data : & mut BasicBlockData < ' tcx > ) {
364
+ for statement in & mut data. statements {
365
+ self . visit_statement ( block, statement) ;
366
+ }
367
+ self . visit_terminator ( block, & mut data. terminator ) ;
368
+ }
369
+
370
+ fn super_statement ( & mut self ,
371
+ block : BasicBlock ,
372
+ statement : & mut Statement < ' tcx > ) {
373
+ self . visit_span ( & mut statement. span ) ;
374
+
375
+ match statement. kind {
376
+ StatementKind :: Assign ( ref mut lvalue, ref mut rvalue) => {
377
+ self . visit_assign ( block, lvalue, rvalue) ;
378
+ }
379
+ StatementKind :: Drop ( _, ref mut lvalue) => {
380
+ self . visit_lvalue ( lvalue, LvalueContext :: Drop ) ;
381
+ }
382
+ }
383
+ }
384
+
385
+ fn super_assign ( & mut self ,
386
+ _block : BasicBlock ,
387
+ lvalue : & mut Lvalue < ' tcx > ,
388
+ rvalue : & mut Rvalue < ' tcx > ) {
389
+ self . visit_lvalue ( lvalue, LvalueContext :: Store ) ;
390
+ self . visit_rvalue ( rvalue) ;
391
+ }
392
+
393
+ fn super_terminator ( & mut self ,
394
+ block : BasicBlock ,
395
+ terminator : & mut Terminator < ' tcx > ) {
396
+ match * terminator {
397
+ Terminator :: Goto { target } |
398
+ Terminator :: Panic { target } => {
399
+ self . visit_branch ( block, target) ;
400
+ }
401
+
402
+ Terminator :: If { ref mut cond, ref mut targets } => {
403
+ self . visit_operand ( cond) ;
404
+ for & target in targets. as_slice ( ) {
405
+ self . visit_branch ( block, target) ;
406
+ }
407
+ }
408
+
409
+ Terminator :: Switch { ref mut discr, adt_def : _, ref targets } => {
410
+ self . visit_lvalue ( discr, LvalueContext :: Inspect ) ;
411
+ for & target in targets {
412
+ self . visit_branch ( block, target) ;
413
+ }
414
+ }
415
+
416
+ Terminator :: SwitchInt { ref mut discr, switch_ty : _, values : _, ref targets } => {
417
+ self . visit_lvalue ( discr, LvalueContext :: Inspect ) ;
418
+ for & target in targets {
419
+ self . visit_branch ( block, target) ;
420
+ }
421
+ }
422
+
423
+ Terminator :: Diverge |
424
+ Terminator :: Return => {
425
+ }
426
+
427
+ Terminator :: Call { ref mut data, ref mut targets } => {
428
+ self . visit_lvalue ( & mut data. destination , LvalueContext :: Store ) ;
429
+ self . visit_operand ( & mut data. func ) ;
430
+ for arg in & mut data. args {
431
+ self . visit_operand ( arg) ;
432
+ }
433
+ for & target in targets. as_slice ( ) {
434
+ self . visit_branch ( block, target) ;
435
+ }
436
+ }
437
+ }
438
+ }
439
+
440
+ fn super_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > ) {
441
+ match * rvalue {
442
+ Rvalue :: Use ( ref mut operand) => {
443
+ self . visit_operand ( operand) ;
444
+ }
445
+
446
+ Rvalue :: Repeat ( ref mut value, ref mut len) => {
447
+ self . visit_operand ( value) ;
448
+ self . visit_constant ( len) ;
449
+ }
450
+
451
+ Rvalue :: Ref ( r, bk, ref mut path) => {
452
+ self . visit_lvalue ( path, LvalueContext :: Borrow {
453
+ region : r,
454
+ kind : bk
455
+ } ) ;
456
+ }
457
+
458
+ Rvalue :: Len ( ref mut path) => {
459
+ self . visit_lvalue ( path, LvalueContext :: Inspect ) ;
460
+ }
461
+
462
+ Rvalue :: Cast ( _, ref mut operand, _) => {
463
+ self . visit_operand ( operand) ;
464
+ }
465
+
466
+ Rvalue :: BinaryOp ( _, ref mut lhs, ref mut rhs) => {
467
+ self . visit_operand ( lhs) ;
468
+ self . visit_operand ( rhs) ;
469
+ }
470
+
471
+ Rvalue :: UnaryOp ( _, ref mut op) => {
472
+ self . visit_operand ( op) ;
473
+ }
474
+
475
+ Rvalue :: Box ( _) => {
476
+ }
477
+
478
+ Rvalue :: Aggregate ( ref mut kind, ref mut operands) => {
479
+ match * kind {
480
+ AggregateKind :: Closure ( ref mut def_id, _) => {
481
+ self . visit_def_id ( def_id) ;
482
+ }
483
+ _ => { /* nothing to do */ }
484
+ }
485
+
486
+ for operand in & mut operands[ ..] {
487
+ self . visit_operand ( operand) ;
488
+ }
489
+ }
490
+
491
+ Rvalue :: Slice { ref mut input, from_start, from_end } => {
492
+ self . visit_lvalue ( input, LvalueContext :: Slice {
493
+ from_start : from_start,
494
+ from_end : from_end,
495
+ } ) ;
496
+ }
497
+
498
+ Rvalue :: InlineAsm ( _) => {
499
+ }
500
+ }
501
+ }
502
+
503
+ fn super_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
504
+ match * operand {
505
+ Operand :: Consume ( ref mut lvalue) => {
506
+ self . visit_lvalue ( lvalue, LvalueContext :: Consume ) ;
507
+ }
508
+ Operand :: Constant ( ref mut constant) => {
509
+ self . visit_constant ( constant) ;
510
+ }
511
+ }
512
+ }
513
+
514
+ fn super_lvalue ( & mut self ,
515
+ lvalue : & mut Lvalue < ' tcx > ,
516
+ _context : LvalueContext ) {
517
+ match * lvalue {
518
+ Lvalue :: Var ( _) |
519
+ Lvalue :: Temp ( _) |
520
+ Lvalue :: Arg ( _) |
521
+ Lvalue :: ReturnPointer => {
522
+ }
523
+ Lvalue :: Static ( ref mut def_id) => {
524
+ self . visit_def_id ( def_id) ;
525
+ }
526
+ Lvalue :: Projection ( ref mut proj) => {
527
+ self . visit_lvalue ( & mut proj. base , LvalueContext :: Projection ) ;
528
+ }
529
+ }
530
+ }
531
+
532
+ fn super_branch ( & mut self , _source : BasicBlock , _target : BasicBlock ) {
533
+ }
534
+
535
+ fn super_constant ( & mut self , constant : & mut Constant < ' tcx > ) {
536
+ self . visit_span ( & mut constant. span ) ;
537
+ self . visit_literal ( & mut constant. literal ) ;
538
+ }
539
+
540
+ fn super_literal ( & mut self , literal : & mut Literal < ' tcx > ) {
541
+ match * literal {
542
+ Literal :: Item { ref mut def_id, .. } => {
543
+ self . visit_def_id ( def_id) ;
544
+ } ,
545
+ Literal :: Value { .. } => {
546
+ // Nothing to do
547
+ }
548
+ }
549
+ }
550
+
551
+ fn super_def_id ( & mut self , _def_id : & mut DefId ) {
552
+ }
553
+
554
+ fn super_span ( & mut self , _span : & mut Span ) {
555
+ }
556
+ }
0 commit comments