Attempt to deal with nested closures properly
This commit is contained in:
parent
d4f8729c89
commit
b6cf070eb4
|
@ -1153,7 +1153,6 @@ struct InferBorrowKind<'a, 'tcx> {
|
|||
/// Place { V1, [ProjectionKind::Field(Index=1, Variant=0)] } : CaptureKind { E2, MutableBorrow }
|
||||
/// ```
|
||||
capture_information: InferredCaptureInformation<'tcx>,
|
||||
// [FIXME] RFC2229 Change Vec to FxHashSet
|
||||
fake_reads: FxHashSet<Place<'tcx>>, // these need to be fake read.
|
||||
}
|
||||
|
||||
|
@ -1416,9 +1415,9 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
|
||||
fn fake_read(&mut self, place: PlaceWithHirId<'tcx>) {
|
||||
if let PlaceBase::Upvar(_) = place.place.base {
|
||||
self.fake_reads.insert(place.place);
|
||||
fn fake_read(&mut self, place: Place<'tcx>) {
|
||||
if let PlaceBase::Upvar(_) = place.base {
|
||||
self.fake_reads.insert(place);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
pub use self::ConsumeMode::*;
|
||||
|
||||
// Export these here so that Clippy can use them.
|
||||
pub use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId, Projection};
|
||||
pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection};
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
|
@ -54,7 +54,7 @@ pub trait Delegate<'tcx> {
|
|||
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId);
|
||||
|
||||
// [FIXME] RFC2229 This should also affect clippy ref: https://github.com/sexxi-goose/rust/pull/27
|
||||
fn fake_read(&mut self, place: PlaceWithHirId<'tcx>);
|
||||
fn fake_read(&mut self, place: Place<'tcx>);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
|
@ -558,7 +558,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
fn walk_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) {
|
||||
debug!("walk_pat(discr_place={:?}, pat={:?})", discr_place, pat);
|
||||
|
||||
self.delegate.fake_read(discr_place.clone());
|
||||
self.delegate.fake_read(discr_place.place.clone());
|
||||
|
||||
let tcx = self.tcx();
|
||||
let ExprUseVisitor { ref mc, body_owner: _, ref mut delegate } = *self;
|
||||
|
@ -620,8 +620,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
/// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing
|
||||
/// closure as the DefId.
|
||||
fn walk_captures(&mut self, closure_expr: &hir::Expr<'_>) {
|
||||
debug!("walk_captures({:?})", closure_expr);
|
||||
|
||||
// Over here we walk a closure that is nested inside the current body
|
||||
// If the current body is a closure, then we also want to report back any fake reads,
|
||||
// starting off of variables that are captured by our parent as well.
|
||||
|
@ -635,6 +633,32 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
ty::Closure(..) | ty::Generator(..)
|
||||
);
|
||||
|
||||
// [FIXME] RFC2229 Closures within closures don't work
|
||||
if let Some(fake_reads) = self.mc.typeck_results.closure_fake_reads.get(&closure_def_id) {
|
||||
for fake_read in fake_reads.iter() {
|
||||
// Use this as a reference for if we should promote the fake read
|
||||
match fake_read.base {
|
||||
PlaceBase::Upvar(upvar_id) => {
|
||||
if upvars.map_or(body_owner_is_closure, |upvars| {
|
||||
!upvars.contains_key(&upvar_id.var_path.hir_id)
|
||||
}) {
|
||||
// The nested closure might be capturing the current (enclosing) closure's local variables.
|
||||
// We check if the root variable is ever mentioned within the enclosing closure, if not
|
||||
// then for the current body (if it's a closure) these aren't captures, we will ignore them.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
bug!(
|
||||
"Do not know how to get HirId out of Rvalue and StaticItem {:?}",
|
||||
fake_read.base
|
||||
);
|
||||
}
|
||||
};
|
||||
self.delegate.fake_read(fake_read.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(min_captures) = self.mc.typeck_results.closure_min_captures.get(&closure_def_id)
|
||||
{
|
||||
for (var_hir_id, min_list) in min_captures.iter() {
|
||||
|
@ -664,12 +688,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
place.projections.clone(),
|
||||
);
|
||||
|
||||
// [FIXME] RFC2229 We want to created another loop that iterates mc.typeck_results.fake_reads()
|
||||
// [FIXME] RFC2229 Add tests for nested closures
|
||||
if body_owner_is_closure {
|
||||
self.delegate.fake_read(place_with_id.clone());
|
||||
}
|
||||
|
||||
match capture_info.capture_kind {
|
||||
ty::UpvarCapture::ByValue(_) => {
|
||||
let mode = copy_or_move(&self.mc, &place_with_id);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() {
|
||||
let _z = 9;
|
||||
let t = (String::from("Hello"), String::from("World"));
|
||||
let g = (String::from("Mr"), String::from("Goose"));
|
||||
|
||||
let a = #[rustc_capture_analysis] || {
|
||||
let (_, g2) = g;
|
||||
println!("{}", g2);
|
||||
let c = #[rustc_capture_analysis] || {
|
||||
let (_, t2) = t;
|
||||
println!("{}", t2);
|
||||
};
|
||||
|
||||
c();
|
||||
};
|
||||
|
||||
a();
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:9:13
|
||||
|
|
||||
LL | let a = #[rustc_capture_analysis] || {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:12:17
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:1: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
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:12:43
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| ___________________________________________^
|
||||
LL | | let (_, t2) = t;
|
||||
LL | | println!("{}", t2);
|
||||
LL | | };
|
||||
| |_________^
|
||||
|
|
||||
note: Capturing t[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:13:27
|
||||
|
|
||||
LL | let (_, t2) = t;
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:12:43
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| ___________________________________________^
|
||||
LL | | let (_, t2) = t;
|
||||
LL | | println!("{}", t2);
|
||||
LL | | };
|
||||
| |_________^
|
||||
|
|
||||
note: Min Capture t[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:13:27
|
||||
|
|
||||
LL | let (_, t2) = t;
|
||||
| ^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:9:39
|
||||
|
|
||||
LL | let a = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | | let (_, g2) = g;
|
||||
LL | | println!("{}", g2);
|
||||
LL | | let c = #[rustc_capture_analysis] || {
|
||||
... |
|
||||
LL | | c();
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing g[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:10:23
|
||||
|
|
||||
LL | let (_, g2) = g;
|
||||
| ^
|
||||
note: Capturing t[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:13:27
|
||||
|
|
||||
LL | let (_, t2) = t;
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:9:39
|
||||
|
|
||||
LL | let a = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | | let (_, g2) = g;
|
||||
LL | | println!("{}", g2);
|
||||
LL | | let c = #[rustc_capture_analysis] || {
|
||||
... |
|
||||
LL | | c();
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture g[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:10:23
|
||||
|
|
||||
LL | let (_, g2) = g;
|
||||
| ^
|
||||
note: Min Capture t[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure-pattern-closure-within-closure.rs:13:27
|
||||
|
|
||||
LL | let (_, t2) = t;
|
||||
| ^
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,118 @@
|
|||
//check-pass
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
#![warn(unused)]
|
||||
|
||||
struct Point {
|
||||
x: u32,
|
||||
y: u32,
|
||||
}
|
||||
|
||||
fn test1() {
|
||||
let _z = 9;
|
||||
let t = (String::from("Hello"), String::from("World"));
|
||||
|
||||
let c = || {
|
||||
let (t1, t2) = t;
|
||||
println!("{} {}", t1, t2);
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
let _z = 9;
|
||||
let t = (String::from("Hello"), String::from("World"));
|
||||
|
||||
let c = || {
|
||||
let (t1, _) = t;
|
||||
println!("{}", t1);
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
let _z = 9;
|
||||
let t = (String::from("Hello"), String::from("World"));
|
||||
|
||||
let c = || {
|
||||
let (_, t2) = t;
|
||||
println!("{}", t2);
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn test4() {
|
||||
let _z = 9;
|
||||
let t = (String::from("Hello"), String::from("World"));
|
||||
//~^ WARN unused variable: `t`
|
||||
|
||||
let c = || {
|
||||
let (_, _) = t;
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn test5() {
|
||||
let _z = 9;
|
||||
let t = (String::new(), String::new());
|
||||
let _c = || {
|
||||
let _a = match t {
|
||||
(t1, _) => t1,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
fn test6() {
|
||||
let _z = 9;
|
||||
let t = (String::new(), String::new());
|
||||
let _c = || {
|
||||
let _a = match t {
|
||||
(_, t2) => t2,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
fn test7() {
|
||||
let x = 0;
|
||||
//~^ WARN unused variable: `x`
|
||||
let tup = (1, 2);
|
||||
//~^ WARN unused variable: `tup`
|
||||
let p = Point { x: 10, y: 20 };
|
||||
|
||||
let c = || {
|
||||
let _ = x;
|
||||
let Point { x, y } = p; // 1
|
||||
//~^ WARN unused variable: `x`
|
||||
println!("{}", y);
|
||||
let (_, _) = tup; // 2
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn test8() {
|
||||
let _z = 9;
|
||||
let t = (String::from("Hello"), String::from("World"));
|
||||
|
||||
let c = || {
|
||||
let (_, t) = t;
|
||||
println!("{}", t);
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
test5();
|
||||
test6();
|
||||
test7();
|
||||
test8();
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/destructure_patterns-1.rs:2: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: unused variable: `t`
|
||||
--> $DIR/destructure_patterns-1.rs:49:9
|
||||
|
|
||||
LL | let t = (String::from("Hello"), String::from("World"));
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_t`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/destructure_patterns-1.rs:4:9
|
||||
|
|
||||
LL | #![warn(unused)]
|
||||
| ^^^^^^
|
||||
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
|
||||
|
||||
warning: unused variable: `x`
|
||||
--> $DIR/destructure_patterns-1.rs:88:21
|
||||
|
|
||||
LL | let Point { x, y } = p; // 1
|
||||
| ^ help: try ignoring the field: `x: _`
|
||||
|
||||
warning: unused variable: `x`
|
||||
--> $DIR/destructure_patterns-1.rs:80:9
|
||||
|
|
||||
LL | let x = 0;
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||
|
||||
warning: unused variable: `tup`
|
||||
--> $DIR/destructure_patterns-1.rs:82:9
|
||||
|
|
||||
LL | let tup = (1, 2);
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_tup`
|
||||
|
||||
warning: 5 warnings emitted
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct S {
|
||||
a: String,
|
||||
b: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let t = (String::new(), String::new());
|
||||
|
||||
let s = S {
|
||||
a: String::new(),
|
||||
b: String::new(),
|
||||
};
|
||||
|
||||
let c = #[rustc_capture_analysis] || {
|
||||
let (t1, t2) = t;
|
||||
};
|
||||
|
||||
|
||||
// MIR Build
|
||||
//
|
||||
// Create place for the initalizer in let which is `t`
|
||||
//
|
||||
// I'm reading Field 1 from `t`, so apply Field projections;
|
||||
//
|
||||
// new place -> t[1]
|
||||
//
|
||||
// I'm reading Field 2 from `t`, so apply Field projections;
|
||||
//
|
||||
// new place -> t[2]
|
||||
//
|
||||
// New
|
||||
// ---------
|
||||
//
|
||||
// I'm building something starting at `t`
|
||||
//
|
||||
// I read field 1 from `t`
|
||||
//
|
||||
// I need to use `t[1]`, therefore the place must be constructable
|
||||
//
|
||||
// Find the capture index for `t[1]` for this closure.
|
||||
//
|
||||
// I read field 2 from `t`
|
||||
//
|
||||
// I need to use `t[2]`, therefore the place must be constructable
|
||||
//
|
||||
// Find the capture index for `t[2]` for this closure.
|
||||
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/destructure_patterns.rs:17:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/destructure_patterns.rs:1: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
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/destructure_patterns.rs:17:39
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | | let (t1, t2) = t;
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0)] -> ByValue
|
||||
--> $DIR/destructure_patterns.rs:18:24
|
||||
|
|
||||
LL | let (t1, t2) = t;
|
||||
| ^
|
||||
note: Capturing t[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure_patterns.rs:18:24
|
||||
|
|
||||
LL | let (t1, t2) = t;
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/destructure_patterns.rs:17:39
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | | let (t1, t2) = t;
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture t[(0, 0)] -> ByValue
|
||||
--> $DIR/destructure_patterns.rs:18:24
|
||||
|
|
||||
LL | let (t1, t2) = t;
|
||||
| ^
|
||||
note: Min Capture t[(1, 0)] -> ByValue
|
||||
--> $DIR/destructure_patterns.rs:18:24
|
||||
|
|
||||
LL | let (t1, t2) = t;
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,12 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() {
|
||||
let foo = [1, 2, 3];
|
||||
let c = #[rustc_capture_analysis] || {
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| ERROR: First Pass analysis includes:
|
||||
match foo { _ => () };
|
||||
};
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/no_capture_with_wildcard_match.rs:7:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/no_capture_with_wildcard_match.rs:1: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
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/no_capture_with_wildcard_match.rs:7:39
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | match foo { _ => () };
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,23 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct S {
|
||||
a: String,
|
||||
b: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = S {
|
||||
a: String::new(),
|
||||
b: String::new(),
|
||||
};
|
||||
|
||||
let c = #[rustc_capture_analysis] || {
|
||||
let s2 = S {
|
||||
a: format!("New a"),
|
||||
..s
|
||||
};
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/struct_update_syntax.rs:15:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/struct_update_syntax.rs:1: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
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/struct_update_syntax.rs:15:39
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | | let s2 = S {
|
||||
LL | | a: format!("New a"),
|
||||
LL | | ..s
|
||||
LL | | };
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing s[(1, 0)] -> ByValue
|
||||
--> $DIR/struct_update_syntax.rs:18:15
|
||||
|
|
||||
LL | ..s
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/struct_update_syntax.rs:15:39
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
| _______________________________________^
|
||||
LL | | let s2 = S {
|
||||
LL | | a: format!("New a"),
|
||||
LL | | ..s
|
||||
LL | | };
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture s[(1, 0)] -> ByValue
|
||||
--> $DIR/struct_update_syntax.rs:18:15
|
||||
|
|
||||
LL | ..s
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue