Simplifications in match lowering by Nadrieril · Pull Request #126835 · rust-lang/rust (original) (raw)

let mut next = Some(&candidate);

while let Some(candidate_ref) = next.take() {

for binding in &candidate_ref.extra_data.bindings {

// `try_to_place` may fail if it is unable to resolve the given `PlaceBuilder` inside a

// closure. In this case, we don't want to include a scrutinee place.

// `scrutinee_place_builder` will fail for destructured assignments. This is because a

// closure only captures the precise places that it will read and as a result a closure

// may not capture the entire tuple/struct and rather have individual places that will

// be read in the final MIR.

// Example:

// ```

// let foo = (0, 1);

// let c = || {

// let (v1, v2) = foo;

// };

// ```

if let Some(place) = initializer.try_to_place(self) {

visit_bindings(&[&mut candidate], |binding: &Binding<'_>| {

let local = self.var_local_id(binding.var_id, OutsideGuard);

// `try_to_place` may fail if it is unable to resolve the given

// `PlaceBuilder` inside a closure. In this case, we don't want to include

// a scrutinee place. `scrutinee_place_builder` will fail for destructured

// assignments. This is because a closure only captures the precise places

// that it will read and as a result a closure may not capture the entire

// tuple/struct and rather have individual places that will be read in the

// final MIR.

// Example:

// ```

// let foo = (0, 1);

// let c = || {

// let (v1, v2) = foo;

// };

// ```

if let Some(place) = initializer.try_to_place(self) {

let LocalInfo::User(BindingForm::Var(VarBindingForm {

opt_match_place: Some((ref mut match_place, _)),

..

})) = **self.local_decls[local].local_info.as_mut().assert_crate_local()

else {

bug!("Let binding to non-user variable.")

};

if let LocalInfo::User(BindingForm::Var(VarBindingForm {

opt_match_place: Some((ref mut match_place, _)),

..

})) = **self.local_decls[local].local_info.as_mut().assert_crate_local()

{

*match_place = Some(place);

}

}

// All of the subcandidates should bind the same locals, so we

// only visit the first one.

next = candidate_ref.subcandidates.get(0)

} else {

bug!("Let binding to non-user variable.")

};

});