Skip to content

Commit

Permalink
Indroduce feature flag for RFC-2229
Browse files Browse the repository at this point in the history
Signed-off-by: Aman Arora <me@aman-arora.com>
  • Loading branch information
arora-aman committed Oct 17, 2020
1 parent 16bef5c commit 08b85c8
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 16 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,9 @@ declare_features! (
/// Allows `#[instruction_set(_)]` attribute
(active, isa_attribute, "1.48.0", Some(74727), 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
// -------------------------------------------------------------------------
Expand All @@ -618,6 +621,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_trait_bound_opt_out,
sym::lazy_normalization_consts,
sym::specialization,
sym::capture_disjoint_fields,
];

/// Some features are not allowed to be used together at the same time, if
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,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)),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ symbols! {
call_mut,
call_once,
caller_location,
capture_disjoint_fields,
cdylib,
ceilf32,
ceilf64,
Expand Down Expand Up @@ -895,6 +896,7 @@ symbols! {
rustc_args_required_const,
rustc_attrs,
rustc_builtin_macro,
rustc_capture_analysis,
rustc_clean,
rustc_const_stable,
rustc_const_unstable,
Expand Down
41 changes: 25 additions & 16 deletions compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -592,10 +613,6 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {

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);
Expand Down Expand Up @@ -646,11 +663,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(_))
}
Original file line number Diff line number Diff line change
@@ -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);
};
}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): Using new-style capture analysis

0 comments on commit 08b85c8

Please sign in to comment.