Make functional record update/struct update syntax works inside closures when feature capture_disjoint_fields is enabled
This commit is contained in:
parent
180fdffa17
commit
e94cf57c3e
4 changed files with 51 additions and 5 deletions
|
@ -303,7 +303,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
|
||||||
self.base
|
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))
|
self.project(PlaceElem::Field(f, ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,7 +302,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let field_names = this.hir.all_fields(adt_def, variant_index);
|
let field_names = this.hir.all_fields(adt_def, variant_index);
|
||||||
|
|
||||||
let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
|
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
|
// MIR does not natively support FRU, so for each
|
||||||
// base-supplied field, generate an operand that
|
// base-supplied field, generate an operand that
|
||||||
|
@ -312,9 +312,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
.zip(field_types.into_iter())
|
.zip(field_types.into_iter())
|
||||||
.map(|(n, ty)| match fields_map.get(&n) {
|
.map(|(n, ty)| match fields_map.get(&n) {
|
||||||
Some(v) => v.clone(),
|
Some(v) => v.clone(),
|
||||||
None => this.consume_by_copy_or_move(
|
None => {
|
||||||
this.hir.tcx().mk_place_field(base, n, ty),
|
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()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue