diff options
| author | Aman Arora <me@aman-arora.com> | 2020-10-11 00:14:11 -0400 |
|---|---|---|
| committer | Aman Arora <me@aman-arora.com> | 2020-11-10 20:58:28 -0500 |
| commit | 88310cc0ebf4144205743dbb3a65223deffcf8e6 (patch) | |
| tree | 44ea1014b63661687515c17cc8b74572aad787ca | |
| parent | 127a6ede1dd9622db20bee435221205b3a61d0ba (diff) | |
| download | rust-88310cc0ebf4144205743dbb3a65223deffcf8e6.tar.gz rust-88310cc0ebf4144205743dbb3a65223deffcf8e6.zip | |
Indroduce feature flag for RFC-2229
Signed-off-by: Aman Arora <me@aman-arora.com>
7 files changed, 66 insertions, 16 deletions
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 0df67b63eba..a0355079247 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -616,6 +616,9 @@ declare_features! ( /// Enables `#[cfg(panic = "...")]` config key. (active, cfg_panic, "1.49.0", Some(77443), None), + /// Allows capturing disjoint fields in a closure/generator (RFC 2229). + (active, capture_disjoint_fields, "1.49.0", Some(53488), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -639,6 +642,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::inline_const, sym::repr128, sym::unsized_locals, + sym::capture_disjoint_fields, ]; /// Some features are not allowed to be used together at the same time, if diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5c5cf609ac3..fa8edba629e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -547,6 +547,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ========================================================================== rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)), + rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word)), rustc_attr!(TEST, rustc_variance, Normal, template!(Word)), rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")), rustc_attr!(TEST, rustc_regions, Normal, template!(Word)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ad58f89d87d..3a2a3adce35 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -318,6 +318,7 @@ symbols! { call_mut, call_once, caller_location, + capture_disjoint_fields, cdylib, ceilf32, ceilf64, @@ -909,6 +910,7 @@ symbols! { rustc_args_required_const, rustc_attrs, rustc_builtin_macro, + rustc_capture_analysis, rustc_clean, rustc_const_stable, rustc_const_unstable, diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 24bb7756ef3..a28744c2ece 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -32,8 +32,6 @@ use super::FnCtxt; -use std::env; - use crate::expr_use_visitor as euv; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; @@ -43,8 +41,25 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_infer::infer::UpvarRegion; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId}; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts}; +use rustc_span::sym; use rustc_span::{Span, Symbol}; +macro_rules! log_capture_analysis { + ($fcx:expr, $closure_def_id:expr, $fmt:literal) => { + if $fcx.should_log_capture_analysis($closure_def_id) { + print!("For closure={:?}: ", $closure_def_id); + println!($fmt); + } + }; + + ($fcx:expr, $closure_def_id:expr, $fmt:literal, $($args:expr),*) => { + if $fcx.should_log_capture_analysis($closure_def_id) { + print!("For closure={:?}: ", $closure_def_id); + println!($fmt, $($args),*); + } + }; +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) { InferBorrowKindVisitor { fcx: self }.visit_body(body); @@ -115,8 +130,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let local_def_id = closure_def_id.expect_local(); let mut capture_information = FxIndexMap::<Place<'tcx>, ty::CaptureInfo<'tcx>>::default(); - if !new_capture_analysis() { - debug!("Using old-style capture analysis"); + if self.tcx.features().capture_disjoint_fields { + log_capture_analysis!(self, closure_def_id, "Using new-style capture analysis"); + } else { + log_capture_analysis!(self, closure_def_id, "Using old-style capture analysis"); if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) { for (&var_hir_id, _) in upvars.iter() { let place = self.place_for_root_variable(local_def_id, var_hir_id); @@ -325,6 +342,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { projections: Default::default(), } } + + fn should_log_capture_analysis(&self, closure_def_id: DefId) -> bool { + self.tcx.has_attr(closure_def_id, sym::rustc_capture_analysis) + } } struct InferBorrowKind<'a, 'tcx> { @@ -601,10 +622,6 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> { let expr_id = Some(diag_expr_id); let capture_info = ty::CaptureInfo { expr_id, capture_kind }; - if log_capture_analysis() { - debug!("capture_info: {:?}", capture_info); - } - self.capture_information.insert(place_with_id.place.clone(), capture_info); } else { debug!("Not upvar: {:?}", place_with_id); @@ -670,11 +687,3 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol { tcx.hir().name(var_hir_id) } - -fn new_capture_analysis() -> bool { - matches!(env::var("SG_NEW"), Ok(_)) -} - -fn log_capture_analysis() -> bool { - matches!(env::var("SG_VERBOSE"), Ok(_)) -} diff --git a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs new file mode 100644 index 00000000000..5eab718736c --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs @@ -0,0 +1,12 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING the feature `capture_disjoint_fields` is incomplete +#![feature(rustc_attrs)] + +fn main() { + let s = format!("s"); + + let c = #[rustc_capture_analysis] || { + //~^ ERROR: attributes on expressions are experimental + println!("This uses new capture analyysis to capture s={}", s); + }; +} diff --git a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr new file mode 100644 index 00000000000..4dc1f9a6ab2 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr @@ -0,0 +1,21 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/feature-gate-capture_disjoint_fields.rs:8: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/feature-gate-capture_disjoint_fields.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: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stdout b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stdout new file mode 100644 index 00000000000..c1fca9afd39 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stdout @@ -0,0 +1 @@ +For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): Using new-style capture analysis |
