Skip to content

Commit

Permalink
Make functional record update/struct update syntax works inside closu…
Browse files Browse the repository at this point in the history
…res when feature capture_disjoint_fields is enabled
  • Loading branch information
null-sleep committed Jan 23, 2021
1 parent 180fdff commit e94cf57
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 5 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/expr/as_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down
30 changes: 30 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/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();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/fru_syntax.rs:6:12
|
LL | #![feature(capture_disjoint_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information

warning: 1 warning emitted

0 comments on commit e94cf57

Please sign in to comment.