Edition 2021 enables disjoint capture
This commit is contained in:
parent
4573a4a879
commit
f265997b82
@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// We now fake capture information for all variables that are mentioned within the closure
|
||||
// We do this after handling migrations so that min_captures computes before
|
||||
if !self.tcx.features().capture_disjoint_fields {
|
||||
if !enable_precise_capture(self.tcx, span) {
|
||||
let mut capture_information: InferredCaptureInformation<'tcx> = Default::default();
|
||||
|
||||
if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
|
||||
@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// If we have an origin, store it.
|
||||
if let Some(origin) = delegate.current_origin.clone() {
|
||||
let origin = if self.tcx.features().capture_disjoint_fields {
|
||||
let origin = if enable_precise_capture(self.tcx, span) {
|
||||
(origin.0, restrict_capture_precision(origin.1))
|
||||
} else {
|
||||
(origin.0, Place { projections: vec![], ..origin.1 })
|
||||
@ -1924,3 +1924,13 @@ fn determine_place_ancestry_relation(
|
||||
PlaceAncestryRelation::Divergent
|
||||
}
|
||||
}
|
||||
|
||||
/// Precise capture is enabled if the feature gate `capture_disjoint_fields` is enabled or if
|
||||
/// user is using Rust Edition 2021 or higher.
|
||||
///
|
||||
/// `span` is the span of the closure.
|
||||
fn enable_precise_capture(tcx: TyCtxt<'_>, span: Span) -> bool {
|
||||
// We use span here to ensure that if the closure was generated by a macro with a different
|
||||
// edition.
|
||||
tcx.features().capture_disjoint_fields || span.rust_2021()
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
// edition:2021
|
||||
// run-pass
|
||||
|
||||
// Test that edition 2021 enables disjoint capture by default.
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 10, y: 10 };
|
||||
|
||||
let c = || {
|
||||
println!("{}", p.x);
|
||||
};
|
||||
|
||||
// `c` should only capture `p.x`, therefore mutating `p.y` is allowed.
|
||||
let py = &mut p.y;
|
||||
|
||||
c();
|
||||
*py = 20;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user