Skip to content

Commit 916549e

Browse files
committed
Indroduce feature flag for RFC-2229
Signed-off-by: Aman Arora <[email protected]>
1 parent 81162b1 commit 916549e

File tree

7 files changed

+66
-16
lines changed

7 files changed

+66
-16
lines changed

compiler/rustc_feature/src/active.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ declare_features! (
610610
/// Allows unsized fn parameters.
611611
(active, unsized_fn_params, "1.49.0", Some(48055), None),
612612

613+
/// Allows capturing disjoint fields in a closure/generator (RFC 2229).
614+
(active, capture_disjoint_fields, "1.49.0", Some(53488), None),
615+
613616
// -------------------------------------------------------------------------
614617
// feature-group-end: actual feature gates
615618
// -------------------------------------------------------------------------
@@ -633,6 +636,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
633636
sym::inline_const,
634637
sym::repr128,
635638
sym::unsized_locals,
639+
sym::capture_disjoint_fields,
636640
];
637641

638642
/// Some features are not allowed to be used together at the same time, if

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
546546
// ==========================================================================
547547

548548
rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
549+
rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word)),
549550
rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
550551
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
551552
rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ symbols! {
318318
call_mut,
319319
call_once,
320320
caller_location,
321+
capture_disjoint_fields,
321322
cdylib,
322323
ceilf32,
323324
ceilf64,
@@ -907,6 +908,7 @@ symbols! {
907908
rustc_args_required_const,
908909
rustc_attrs,
909910
rustc_builtin_macro,
911+
rustc_capture_analysis,
910912
rustc_clean,
911913
rustc_const_stable,
912914
rustc_const_unstable,

compiler/rustc_typeck/src/check/upvar.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
3333
use super::FnCtxt;
3434

35-
use std::env;
36-
3735
use crate::expr_use_visitor as euv;
3836
use rustc_data_structures::fx::FxIndexMap;
3937
use rustc_hir as hir;
@@ -43,8 +41,25 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
4341
use rustc_infer::infer::UpvarRegion;
4442
use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId};
4543
use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
44+
use rustc_span::sym;
4645
use rustc_span::{Span, Symbol};
4746

47+
macro_rules! log_capture_analysis {
48+
($fcx:expr, $closure_def_id:expr, $fmt:literal) => {
49+
if $fcx.should_log_capture_analysis($closure_def_id) {
50+
print!("For closure={:?}: ", $closure_def_id);
51+
println!($fmt);
52+
}
53+
};
54+
55+
($fcx:expr, $closure_def_id:expr, $fmt:literal, $($args:expr),*) => {
56+
if $fcx.should_log_capture_analysis($closure_def_id) {
57+
print!("For closure={:?}: ", $closure_def_id);
58+
println!($fmt, $($args),*);
59+
}
60+
};
61+
}
62+
4863
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4964
pub fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) {
5065
InferBorrowKindVisitor { fcx: self }.visit_body(body);
@@ -115,8 +130,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
115130
let local_def_id = closure_def_id.expect_local();
116131

117132
let mut capture_information = FxIndexMap::<Place<'tcx>, ty::CaptureInfo<'tcx>>::default();
118-
if !new_capture_analysis() {
119-
debug!("Using old-style capture analysis");
133+
if self.tcx.features().capture_disjoint_fields {
134+
log_capture_analysis!(self, closure_def_id, "Using new-style capture analysis");
135+
} else {
136+
log_capture_analysis!(self, closure_def_id, "Using old-style capture analysis");
120137
if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
121138
for (&var_hir_id, _) in upvars.iter() {
122139
let place = self.place_for_root_variable(local_def_id, var_hir_id);
@@ -325,6 +342,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
325342
projections: Default::default(),
326343
}
327344
}
345+
346+
fn should_log_capture_analysis(&self, closure_def_id: DefId) -> bool {
347+
self.tcx.has_attr(closure_def_id, sym::rustc_capture_analysis)
348+
}
328349
}
329350

330351
struct InferBorrowKind<'a, 'tcx> {
@@ -601,10 +622,6 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
601622
let expr_id = Some(diag_expr_id);
602623
let capture_info = ty::CaptureInfo { expr_id, capture_kind };
603624

604-
if log_capture_analysis() {
605-
debug!("capture_info: {:?}", capture_info);
606-
}
607-
608625
self.capture_information.insert(place_with_id.place.clone(), capture_info);
609626
} else {
610627
debug!("Not upvar: {:?}", place_with_id);
@@ -670,11 +687,3 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
670687
fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
671688
tcx.hir().name(var_hir_id)
672689
}
673-
674-
fn new_capture_analysis() -> bool {
675-
matches!(env::var("SG_NEW"), Ok(_))
676-
}
677-
678-
fn log_capture_analysis() -> bool {
679-
matches!(env::var("SG_VERBOSE"), Ok(_))
680-
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(capture_disjoint_fields)]
2+
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
3+
#![feature(rustc_attrs)]
4+
5+
fn main() {
6+
let s = format!("s");
7+
8+
let c = #[rustc_capture_analysis] || {
9+
//~^ ERROR: attributes on expressions are experimental
10+
println!("This uses new capture analyysis to capture s={}", s);
11+
};
12+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0658]: attributes on expressions are experimental
2+
--> $DIR/feature-gate-capture_disjoint_fields.rs:8:13
3+
|
4+
LL | let c = #[rustc_capture_analysis] || {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
8+
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
9+
10+
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
11+
--> $DIR/feature-gate-capture_disjoint_fields.rs:1:12
12+
|
13+
LL | #![feature(capture_disjoint_fields)]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: `#[warn(incomplete_features)]` on by default
17+
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
18+
19+
error: aborting due to previous error; 1 warning emitted
20+
21+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): Using new-style capture analysis

0 commit comments

Comments
 (0)