(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>)
| 429 | } |
| 430 | |
| 431 | fn process_assignment(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>) { |
| 432 | let lhs_pattern = Self::process_place(place.as_ref()); |
| 433 | let rhs_patterns = Self::process_rvalue(rvalue); |
| 434 | // TODO(boqin): check if mk_place_field work for all places. |
| 435 | // original closure impl: |
| 436 | // _x = closure => _x[0], _x[1], ... are upvars. Inside the closure, I check if a local var aliases with the upvars. |
| 437 | // current closure impl: |
| 438 | // _x = closure(def_id, args, fields) => fields[0], fields[1], ... are upvars |
| 439 | // For compatibility, I create new places: _x[0], _x[1], ... |
| 440 | // and add constraints for _x[0] = fields[0], _x[1] = fields[1], ... |
| 441 | // Note that creating new places with mk_place_field is a hack. I need to check it against large projects. |
| 442 | if let Rvalue::Aggregate(box AggregateKind::Closure(_def_id, _args), fields) = rvalue { |
| 443 | for (idx, operand) in fields.iter_enumerated() { |
| 444 | if let Some(rhs) = operand.place() { |
| 445 | let op_ty = operand.ty(&self.body.local_decls, self.tcx); |
| 446 | let lhs = self.tcx.mk_place_field(*place, idx, op_ty); |
| 447 | self.graph.add_copy(lhs.as_ref(), rhs.as_ref()); |
| 448 | } |
| 449 | } |
| 450 | } |
| 451 | for rhs_pattern in rhs_patterns.into_iter() { |
| 452 | match (&lhs_pattern, rhs_pattern) { |
| 453 | // a = &b |
| 454 | (AccessPattern::Direct(lhs), Some(AccessPattern::Ref(rhs))) => { |
| 455 | self.graph.add_address(*lhs, rhs); |
| 456 | } |
| 457 | // a = b |
| 458 | (AccessPattern::Direct(lhs), Some(AccessPattern::Direct(rhs))) => { |
| 459 | self.graph.add_copy(*lhs, rhs); |
| 460 | } |
| 461 | // a = Constant |
| 462 | (AccessPattern::Direct(lhs), Some(AccessPattern::Constant(rhs))) => { |
| 463 | self.graph.add_copy_constant(*lhs, rhs); |
| 464 | } |
| 465 | // a = *b |
| 466 | (AccessPattern::Direct(lhs), Some(AccessPattern::Indirect(rhs))) => { |
| 467 | self.graph.add_load(*lhs, rhs); |
| 468 | } |
| 469 | // *a = b |
| 470 | (AccessPattern::Indirect(lhs), Some(AccessPattern::Direct(rhs))) => { |
| 471 | self.graph.add_store(*lhs, rhs); |
| 472 | } |
| 473 | // *a = Constant |
| 474 | (AccessPattern::Indirect(lhs), Some(AccessPattern::Constant(rhs))) => { |
| 475 | self.graph.add_store_constant(*lhs, rhs); |
| 476 | } |
| 477 | _ => {} |
| 478 | } |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | fn process_place(place_ref: PlaceRef<'tcx>) -> AccessPattern<'tcx> { |
| 483 | match place_ref { |
no test coverage detected