Fork of daniellemaywood.uk/gleam — Wasm codegen work
1

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / src / wasm / mir / visit.rs
19 kB 745 lines
1use ecow::EcoString; 2use num_bigint::BigInt; 3 4use crate::wasm::mir::ast::{Expression, Function, Module, Var}; 5 6pub trait Visit<'mir, T> { 7 fn visit_module(&mut self, module: &'mir mut Module<T>) { 8 visit_module(self, module); 9 } 10 11 fn visit_function(&mut self, function: &'mir mut Function<T>) { 12 visit_function(self, function); 13 } 14 15 fn visit_expression(&mut self, expression: &'mir mut Expression<T>) { 16 visit_expression(self, expression); 17 } 18 19 fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression<T>>) { 20 visit_expression_block(self, expressions); 21 } 22 23 fn visit_expression_function_ref( 24 &mut self, 25 module: &mut EcoString, 26 name: &mut EcoString, 27 arity: &mut usize, 28 type_: &mut T, 29 ) { 30 visit_expression_function_ref(self, module, name, arity, type_); 31 } 32 33 fn visit_expression_var(&mut self, var: &'mir mut Var<T>) { 34 visit_expression_var(self, var); 35 } 36 37 fn visit_expression_int(&mut self, value: &'mir mut BigInt) { 38 visit_expression_int(self, value); 39 } 40 41 fn visit_expression_float(&mut self, value: &'mir mut EcoString) { 42 visit_expression_float(self, value); 43 } 44 45 fn visit_expression_bool(&mut self, value: &'mir mut bool) { 46 visit_expression_bool(self, value); 47 } 48 49 fn visit_expression_string(&mut self, value: &'mir mut EcoString) { 50 visit_expression_string(self, value); 51 } 52 53 fn visit_expression_equals( 54 &mut self, 55 lhs: &'mir mut Expression<T>, 56 rhs: &'mir mut Expression<T>, 57 ) { 58 visit_expression_equals(self, lhs, rhs); 59 } 60 61 fn visit_expression_not_equals( 62 &mut self, 63 lhs: &'mir mut Expression<T>, 64 rhs: &'mir mut Expression<T>, 65 ) { 66 visit_expression_not_equals(self, lhs, rhs); 67 } 68 69 fn visit_expression_int_gt( 70 &mut self, 71 lhs: &'mir mut Expression<T>, 72 rhs: &'mir mut Expression<T>, 73 ) { 74 visit_expression_int_gt(self, lhs, rhs); 75 } 76 77 fn visit_expression_int_gt_eq( 78 &mut self, 79 lhs: &'mir mut Expression<T>, 80 rhs: &'mir mut Expression<T>, 81 ) { 82 visit_expression_int_gt_eq(self, lhs, rhs); 83 } 84 85 fn visit_expression_int_lt( 86 &mut self, 87 lhs: &'mir mut Expression<T>, 88 rhs: &'mir mut Expression<T>, 89 ) { 90 visit_expression_int_lt(self, lhs, rhs); 91 } 92 93 fn visit_expression_int_lt_eq( 94 &mut self, 95 lhs: &'mir mut Expression<T>, 96 rhs: &'mir mut Expression<T>, 97 ) { 98 visit_expression_int_lt_eq(self, lhs, rhs); 99 } 100 101 fn visit_expression_int_add( 102 &mut self, 103 lhs: &'mir mut Expression<T>, 104 rhs: &'mir mut Expression<T>, 105 ) { 106 visit_expression_int_add(self, lhs, rhs); 107 } 108 109 fn visit_expression_int_sub( 110 &mut self, 111 lhs: &'mir mut Expression<T>, 112 rhs: &'mir mut Expression<T>, 113 ) { 114 visit_expression_int_sub(self, lhs, rhs); 115 } 116 117 fn visit_expression_int_mul( 118 &mut self, 119 lhs: &'mir mut Expression<T>, 120 rhs: &'mir mut Expression<T>, 121 ) { 122 visit_expression_int_mul(self, lhs, rhs); 123 } 124 125 fn visit_expression_int_div( 126 &mut self, 127 lhs: &'mir mut Expression<T>, 128 rhs: &'mir mut Expression<T>, 129 ) { 130 visit_expression_int_div(self, lhs, rhs); 131 } 132 133 fn visit_expression_int_rem( 134 &mut self, 135 lhs: &'mir mut Expression<T>, 136 rhs: &'mir mut Expression<T>, 137 ) { 138 visit_expression_int_rem(self, lhs, rhs); 139 } 140 141 fn visit_expression_float_gt( 142 &mut self, 143 lhs: &'mir mut Expression<T>, 144 rhs: &'mir mut Expression<T>, 145 ) { 146 visit_expression_float_gt(self, lhs, rhs); 147 } 148 149 fn visit_expression_float_gt_eq( 150 &mut self, 151 lhs: &'mir mut Expression<T>, 152 rhs: &'mir mut Expression<T>, 153 ) { 154 visit_expression_float_gt_eq(self, lhs, rhs); 155 } 156 157 fn visit_expression_float_lt( 158 &mut self, 159 lhs: &'mir mut Expression<T>, 160 rhs: &'mir mut Expression<T>, 161 ) { 162 visit_expression_float_lt(self, lhs, rhs); 163 } 164 165 fn visit_expression_float_lt_eq( 166 &mut self, 167 lhs: &'mir mut Expression<T>, 168 rhs: &'mir mut Expression<T>, 169 ) { 170 visit_expression_float_lt_eq(self, lhs, rhs); 171 } 172 173 fn visit_expression_float_add( 174 &mut self, 175 lhs: &'mir mut Expression<T>, 176 rhs: &'mir mut Expression<T>, 177 ) { 178 visit_expression_float_add(self, lhs, rhs); 179 } 180 181 fn visit_expression_float_sub( 182 &mut self, 183 lhs: &'mir mut Expression<T>, 184 rhs: &'mir mut Expression<T>, 185 ) { 186 visit_expression_float_sub(self, lhs, rhs); 187 } 188 189 fn visit_expression_float_mul( 190 &mut self, 191 lhs: &'mir mut Expression<T>, 192 rhs: &'mir mut Expression<T>, 193 ) { 194 visit_expression_float_mul(self, lhs, rhs); 195 } 196 197 fn visit_expression_float_div( 198 &mut self, 199 lhs: &'mir mut Expression<T>, 200 rhs: &'mir mut Expression<T>, 201 ) { 202 visit_expression_float_div(self, lhs, rhs); 203 } 204 205 fn visit_expression_string_concat( 206 &mut self, 207 lhs: &'mir mut Expression<T>, 208 rhs: &'mir mut Expression<T>, 209 ) { 210 visit_expression_string_concat(self, lhs, rhs); 211 } 212 213 fn visit_expression_list( 214 &mut self, 215 items: &'mir mut Vec<Expression<T>>, 216 tail: &'mir mut Option<Box<Expression<T>>>, 217 type_: &'mir mut T, 218 ) { 219 visit_expression_list(self, items, tail, type_); 220 } 221 222 fn visit_expression_tuple(&mut self, items: &'mir mut Vec<Expression<T>>, type_: &'mir mut T) { 223 visit_expression_tuple(self, items, type_); 224 } 225 226 fn visit_expression_tuple_access( 227 &mut self, 228 value: &'mir mut Expression<T>, 229 index: &'mir mut u64, 230 type_: &'mir mut T, 231 ) { 232 visit_expression_tuple_access(self, value, index, type_); 233 } 234 235 fn visit_expression_struct( 236 &mut self, 237 tag: &'mir mut u32, 238 items: &'mir mut Vec<Expression<T>>, 239 type_: &'mir mut T, 240 ) { 241 visit_expression_struct(self, tag, items, type_); 242 } 243 244 fn visit_expression_struct_tag(&mut self, value: &'mir mut Expression<T>) { 245 visit_expression_struct_tag(self, value); 246 } 247 248 fn visit_expression_struct_access( 249 &mut self, 250 value: &'mir mut Expression<T>, 251 index: &'mir mut u64, 252 type_: &'mir mut T, 253 ) { 254 visit_expression_struct_access(self, value, index, type_); 255 } 256 257 fn visit_expression_set(&mut self, name: &'mir mut Var<T>, value: &'mir mut Expression<T>) { 258 visit_expression_set(self, name, value); 259 } 260 261 fn visit_expression_if( 262 &mut self, 263 cond: &'mir mut Expression<T>, 264 then: &'mir mut Expression<T>, 265 else_: &'mir mut Expression<T>, 266 ) { 267 visit_expression_if(self, cond, then, else_); 268 } 269 270 fn visit_expression_call( 271 &mut self, 272 target: &'mir mut Expression<T>, 273 args: &'mir mut Vec<Expression<T>>, 274 type_: &'mir mut T, 275 ) { 276 visit_expression_call(self, target, args, type_); 277 } 278 279 fn visit_expression_panic(&mut self, type_: &'mir mut T) { 280 visit_expression_panic(self, type_); 281 } 282} 283 284pub fn visit_module<'mir, T, V>(v: &mut V, module: &'mir mut Module<T>) 285where 286 V: Visit<'mir, T> + ?Sized, 287{ 288 for function in &mut module.functions { 289 v.visit_function(function); 290 } 291} 292 293pub fn visit_function<'mir, T, V>(v: &mut V, function: &'mir mut Function<T>) 294where 295 V: Visit<'mir, T> + ?Sized, 296{ 297 if let Some(body) = &mut function.body { 298 v.visit_expression(body); 299 } 300} 301 302pub fn visit_expression<'mir, T, V>(v: &mut V, expression: &'mir mut Expression<T>) 303where 304 V: Visit<'mir, T> + ?Sized, 305{ 306 match expression { 307 Expression::Block(expressions) => v.visit_expression_block(expressions), 308 Expression::FunctionRef { 309 module, 310 name, 311 arity, 312 type_, 313 } => v.visit_expression_function_ref(module, name, arity, type_), 314 Expression::Var(var) => v.visit_expression_var(var), 315 Expression::Int { value } => v.visit_expression_int(value), 316 Expression::Float { value } => v.visit_expression_float(value), 317 Expression::Bool { value } => v.visit_expression_bool(value), 318 Expression::String { value } => v.visit_expression_string(value), 319 Expression::Equals { lhs, rhs } => v.visit_expression_equals(lhs, rhs), 320 Expression::NotEquals { lhs, rhs } => v.visit_expression_not_equals(lhs, rhs), 321 Expression::IntGt { lhs, rhs } => v.visit_expression_int_gt(lhs, rhs), 322 Expression::IntGtEq { lhs, rhs } => v.visit_expression_int_gt_eq(lhs, rhs), 323 Expression::IntLt { lhs, rhs } => v.visit_expression_int_lt(lhs, rhs), 324 Expression::IntLtEq { lhs, rhs } => v.visit_expression_int_lt_eq(lhs, rhs), 325 Expression::IntAdd { lhs, rhs } => v.visit_expression_int_add(lhs, rhs), 326 Expression::IntSub { lhs, rhs } => v.visit_expression_int_sub(lhs, rhs), 327 Expression::IntMul { lhs, rhs } => v.visit_expression_int_mul(lhs, rhs), 328 Expression::IntDiv { lhs, rhs } => v.visit_expression_int_div(lhs, rhs), 329 Expression::IntRem { lhs, rhs } => v.visit_expression_int_rem(lhs, rhs), 330 Expression::FloatGt { lhs, rhs } => v.visit_expression_float_gt(lhs, rhs), 331 Expression::FloatGtEq { lhs, rhs } => v.visit_expression_float_gt_eq(lhs, rhs), 332 Expression::FloatLt { lhs, rhs } => v.visit_expression_float_lt(lhs, rhs), 333 Expression::FloatLtEq { lhs, rhs } => v.visit_expression_float_lt_eq(lhs, rhs), 334 Expression::FloatAdd { lhs, rhs } => v.visit_expression_float_add(lhs, rhs), 335 Expression::FloatSub { lhs, rhs } => v.visit_expression_float_sub(lhs, rhs), 336 Expression::FloatMul { lhs, rhs } => v.visit_expression_float_mul(lhs, rhs), 337 Expression::FloatDiv { lhs, rhs } => v.visit_expression_float_div(lhs, rhs), 338 Expression::StringConcat { lhs, rhs } => v.visit_expression_string_concat(lhs, rhs), 339 Expression::List { items, tail, type_ } => v.visit_expression_list(items, tail, type_), 340 Expression::Tuple { items, type_ } => v.visit_expression_tuple(items, type_), 341 Expression::TupleAccess { 342 value, 343 index, 344 type_, 345 } => v.visit_expression_tuple_access(value, index, type_), 346 Expression::Struct { tag, items, type_ } => v.visit_expression_struct(tag, items, type_), 347 Expression::StructTag { value } => v.visit_expression_struct_tag(value), 348 Expression::StructAccess { 349 value, 350 index, 351 type_, 352 } => v.visit_expression_struct_access(value, index, type_), 353 Expression::Set { name, value } => v.visit_expression_set(name, value), 354 Expression::If { cond, then, else_ } => v.visit_expression_if(cond, then, else_), 355 Expression::Call { 356 target, 357 args, 358 type_, 359 } => v.visit_expression_call(target, args, type_), 360 Expression::Panic { type_ } => v.visit_expression_panic(type_), 361 } 362} 363 364pub fn visit_expression_block<'mir, T, V>(v: &mut V, expressions: &'mir mut Vec<Expression<T>>) 365where 366 V: Visit<'mir, T> + ?Sized, 367{ 368 for expression in expressions { 369 v.visit_expression(expression); 370 } 371} 372 373pub fn visit_expression_function_ref<'mir, T, V>( 374 _v: &mut V, 375 _module: &mut EcoString, 376 _name: &mut EcoString, 377 _arity: &mut usize, 378 _type: &mut T, 379) where 380 V: Visit<'mir, T> + ?Sized, 381{ 382} 383 384pub fn visit_expression_var<'mir, T, V>(_v: &mut V, _var: &mut Var<T>) 385where 386 V: Visit<'mir, T> + ?Sized, 387{ 388} 389 390pub fn visit_expression_int<'mir, T, V>(_v: &mut V, _value: &mut BigInt) 391where 392 V: Visit<'mir, T> + ?Sized, 393{ 394} 395 396pub fn visit_expression_float<'mir, T, V>(_v: &mut V, _value: &mut EcoString) 397where 398 V: Visit<'mir, T> + ?Sized, 399{ 400} 401 402pub fn visit_expression_bool<'mir, T, V>(_v: &mut V, _value: &mut bool) 403where 404 V: Visit<'mir, T> + ?Sized, 405{ 406} 407 408pub fn visit_expression_string<'mir, T, V>(_v: &mut V, _value: &mut EcoString) 409where 410 V: Visit<'mir, T> + ?Sized, 411{ 412} 413 414pub fn visit_expression_equals<'mir, T, V>( 415 v: &mut V, 416 lhs: &'mir mut Expression<T>, 417 rhs: &'mir mut Expression<T>, 418) where 419 V: Visit<'mir, T> + ?Sized, 420{ 421 v.visit_expression(lhs); 422 v.visit_expression(rhs); 423} 424 425pub fn visit_expression_not_equals<'mir, T, V>( 426 v: &mut V, 427 lhs: &'mir mut Expression<T>, 428 rhs: &'mir mut Expression<T>, 429) where 430 V: Visit<'mir, T> + ?Sized, 431{ 432 v.visit_expression(lhs); 433 v.visit_expression(rhs); 434} 435 436pub fn visit_expression_int_gt<'mir, T, V>( 437 v: &mut V, 438 lhs: &'mir mut Expression<T>, 439 rhs: &'mir mut Expression<T>, 440) where 441 V: Visit<'mir, T> + ?Sized, 442{ 443 v.visit_expression(lhs); 444 v.visit_expression(rhs); 445} 446 447pub fn visit_expression_int_gt_eq<'mir, T, V>( 448 v: &mut V, 449 lhs: &'mir mut Expression<T>, 450 rhs: &'mir mut Expression<T>, 451) where 452 V: Visit<'mir, T> + ?Sized, 453{ 454 v.visit_expression(lhs); 455 v.visit_expression(rhs); 456} 457 458pub fn visit_expression_int_lt<'mir, T, V>( 459 v: &mut V, 460 lhs: &'mir mut Expression<T>, 461 rhs: &'mir mut Expression<T>, 462) where 463 V: Visit<'mir, T> + ?Sized, 464{ 465 v.visit_expression(lhs); 466 v.visit_expression(rhs); 467} 468 469pub fn visit_expression_int_lt_eq<'mir, T, V>( 470 v: &mut V, 471 lhs: &'mir mut Expression<T>, 472 rhs: &'mir mut Expression<T>, 473) where 474 V: Visit<'mir, T> + ?Sized, 475{ 476 v.visit_expression(lhs); 477 v.visit_expression(rhs); 478} 479 480pub fn visit_expression_int_add<'mir, T, V>( 481 v: &mut V, 482 lhs: &'mir mut Expression<T>, 483 rhs: &'mir mut Expression<T>, 484) where 485 V: Visit<'mir, T> + ?Sized, 486{ 487 v.visit_expression(lhs); 488 v.visit_expression(rhs); 489} 490 491pub fn visit_expression_int_sub<'mir, T, V>( 492 v: &mut V, 493 lhs: &'mir mut Expression<T>, 494 rhs: &'mir mut Expression<T>, 495) where 496 V: Visit<'mir, T> + ?Sized, 497{ 498 v.visit_expression(lhs); 499 v.visit_expression(rhs); 500} 501 502pub fn visit_expression_int_mul<'mir, T, V>( 503 v: &mut V, 504 lhs: &'mir mut Expression<T>, 505 rhs: &'mir mut Expression<T>, 506) where 507 V: Visit<'mir, T> + ?Sized, 508{ 509 v.visit_expression(lhs); 510 v.visit_expression(rhs); 511} 512 513pub fn visit_expression_int_div<'mir, T, V>( 514 v: &mut V, 515 lhs: &'mir mut Expression<T>, 516 rhs: &'mir mut Expression<T>, 517) where 518 V: Visit<'mir, T> + ?Sized, 519{ 520 v.visit_expression(lhs); 521 v.visit_expression(rhs); 522} 523 524pub fn visit_expression_int_rem<'mir, T, V>( 525 v: &mut V, 526 lhs: &'mir mut Expression<T>, 527 rhs: &'mir mut Expression<T>, 528) where 529 V: Visit<'mir, T> + ?Sized, 530{ 531 v.visit_expression(lhs); 532 v.visit_expression(rhs); 533} 534 535pub fn visit_expression_float_gt<'mir, T, V>( 536 v: &mut V, 537 lhs: &'mir mut Expression<T>, 538 rhs: &'mir mut Expression<T>, 539) where 540 V: Visit<'mir, T> + ?Sized, 541{ 542 v.visit_expression(lhs); 543 v.visit_expression(rhs); 544} 545 546pub fn visit_expression_float_gt_eq<'mir, T, V>( 547 v: &mut V, 548 lhs: &'mir mut Expression<T>, 549 rhs: &'mir mut Expression<T>, 550) where 551 V: Visit<'mir, T> + ?Sized, 552{ 553 v.visit_expression(lhs); 554 v.visit_expression(rhs); 555} 556 557pub fn visit_expression_float_lt<'mir, T, V>( 558 v: &mut V, 559 lhs: &'mir mut Expression<T>, 560 rhs: &'mir mut Expression<T>, 561) where 562 V: Visit<'mir, T> + ?Sized, 563{ 564 v.visit_expression(lhs); 565 v.visit_expression(rhs); 566} 567 568pub fn visit_expression_float_lt_eq<'mir, T, V>( 569 v: &mut V, 570 lhs: &'mir mut Expression<T>, 571 rhs: &'mir mut Expression<T>, 572) where 573 V: Visit<'mir, T> + ?Sized, 574{ 575 v.visit_expression(lhs); 576 v.visit_expression(rhs); 577} 578 579pub fn visit_expression_float_add<'mir, T, V>( 580 v: &mut V, 581 lhs: &'mir mut Expression<T>, 582 rhs: &'mir mut Expression<T>, 583) where 584 V: Visit<'mir, T> + ?Sized, 585{ 586 v.visit_expression(lhs); 587 v.visit_expression(rhs); 588} 589 590pub fn visit_expression_float_sub<'mir, T, V>( 591 v: &mut V, 592 lhs: &'mir mut Expression<T>, 593 rhs: &'mir mut Expression<T>, 594) where 595 V: Visit<'mir, T> + ?Sized, 596{ 597 v.visit_expression(lhs); 598 v.visit_expression(rhs); 599} 600 601pub fn visit_expression_float_mul<'mir, T, V>( 602 v: &mut V, 603 lhs: &'mir mut Expression<T>, 604 rhs: &'mir mut Expression<T>, 605) where 606 V: Visit<'mir, T> + ?Sized, 607{ 608 v.visit_expression(lhs); 609 v.visit_expression(rhs); 610} 611 612pub fn visit_expression_float_div<'mir, T, V>( 613 v: &mut V, 614 lhs: &'mir mut Expression<T>, 615 rhs: &'mir mut Expression<T>, 616) where 617 V: Visit<'mir, T> + ?Sized, 618{ 619 v.visit_expression(lhs); 620 v.visit_expression(rhs); 621} 622 623pub fn visit_expression_string_concat<'mir, T, V>( 624 v: &mut V, 625 lhs: &'mir mut Expression<T>, 626 rhs: &'mir mut Expression<T>, 627) where 628 V: Visit<'mir, T> + ?Sized, 629{ 630 v.visit_expression(lhs); 631 v.visit_expression(rhs); 632} 633 634pub fn visit_expression_list<'mir, T, V>( 635 v: &mut V, 636 items: &'mir mut Vec<Expression<T>>, 637 tail: &'mir mut Option<Box<Expression<T>>>, 638 _type_: &'mir mut T, 639) where 640 V: Visit<'mir, T> + ?Sized, 641{ 642 for item in items { 643 v.visit_expression(item); 644 } 645 if let Some(tail) = tail { 646 v.visit_expression(tail); 647 } 648} 649 650pub fn visit_expression_tuple<'mir, T, V>( 651 v: &mut V, 652 items: &'mir mut Vec<Expression<T>>, 653 _type: &'mir mut T, 654) where 655 V: Visit<'mir, T> + ?Sized, 656{ 657 for item in items { 658 v.visit_expression(item); 659 } 660} 661 662pub fn visit_expression_tuple_access<'mir, T, V>( 663 v: &mut V, 664 value: &'mir mut Expression<T>, 665 _index: &'mir mut u64, 666 _type: &'mir mut T, 667) where 668 V: Visit<'mir, T> + ?Sized, 669{ 670 v.visit_expression(value); 671} 672 673pub fn visit_expression_struct<'mir, T, V>( 674 v: &mut V, 675 _tag: &'mir mut u32, 676 items: &'mir mut Vec<Expression<T>>, 677 _type: &'mir mut T, 678) where 679 V: Visit<'mir, T> + ?Sized, 680{ 681 for item in items { 682 v.visit_expression(item); 683 } 684} 685 686pub fn visit_expression_struct_tag<'mir, T, V>(v: &mut V, value: &'mir mut Expression<T>) 687where 688 V: Visit<'mir, T> + ?Sized, 689{ 690 v.visit_expression(value); 691} 692 693pub fn visit_expression_struct_access<'mir, T, V>( 694 v: &mut V, 695 value: &'mir mut Expression<T>, 696 _index: &'mir mut u64, 697 _type: &'mir mut T, 698) where 699 V: Visit<'mir, T> + ?Sized, 700{ 701 v.visit_expression(value); 702} 703 704pub fn visit_expression_set<'mir, T, V>( 705 v: &mut V, 706 _name: &'mir mut Var<T>, 707 value: &'mir mut Expression<T>, 708) where 709 V: Visit<'mir, T> + ?Sized, 710{ 711 v.visit_expression(value); 712} 713 714pub fn visit_expression_if<'mir, T, V>( 715 v: &mut V, 716 cond: &'mir mut Expression<T>, 717 then: &'mir mut Expression<T>, 718 else_: &'mir mut Expression<T>, 719) where 720 V: Visit<'mir, T> + ?Sized, 721{ 722 v.visit_expression(cond); 723 v.visit_expression(then); 724 v.visit_expression(else_); 725} 726 727pub fn visit_expression_call<'mir, T, V>( 728 v: &mut V, 729 target: &'mir mut Expression<T>, 730 args: &'mir mut Vec<Expression<T>>, 731 _type_: &'mir mut T, 732) where 733 V: Visit<'mir, T> + ?Sized, 734{ 735 v.visit_expression(target); 736 for arg in args { 737 v.visit_expression(arg); 738 } 739} 740 741pub fn visit_expression_panic<'mir, T, V>(_v: &mut V, _type_: &'mir mut T) 742where 743 V: Visit<'mir, T> + ?Sized, 744{ 745}