diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index cf2e4e8916d0a..3e8d4631464f0 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -303,7 +303,7 @@ impl<'tcx> PlaceBuilder<'tcx> { self.base } - fn field(self, f: Field, ty: Ty<'tcx>) -> Self { + crate fn field(self, f: Field, ty: Ty<'tcx>) -> Self { self.project(PlaceElem::Field(f, ty)) } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 09281799041ee..0f9d0db750cf8 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -302,7 +302,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let field_names = this.hir.all_fields(adt_def, variant_index); let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base { - let base = unpack!(block = this.as_place(block, base)); + let place_builder = unpack!(block = this.as_place_builder(block, base)); // MIR does not natively support FRU, so for each // base-supplied field, generate an operand that @@ -312,9 +312,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .zip(field_types.into_iter()) .map(|(n, ty)| match fields_map.get(&n) { Some(v) => v.clone(), - None => this.consume_by_copy_or_move( - this.hir.tcx().mk_place_field(base, n, ty), - ), + None => { + let place_builder = place_builder.clone(); + this.consume_by_copy_or_move( + place_builder + .field(n, ty) + .into_place(this.hir.tcx(), this.hir.typeck_results()), + ) + }, }) .collect() } else { diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs new file mode 100644 index 0000000000000..426eddec6ff8f --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs @@ -0,0 +1,30 @@ +// run-pass + +// Test that functional record update/struct update syntax works inside +// a closure when the feature `capture_disjoint_fields` is enabled. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 + +struct S { + a: String, + b: String, +} + +fn main() { + let a = String::new(); + let b = String::new(); + let s = S {a, b}; + + let c = || { + let s2 = S { + a: format!("New a"), + ..s + }; + println!("{} {}", s2.a, s2.b); + }; + + c(); +}