Replace closures_captures and upvar_capture with closure_min_captures
make changes to liveness to use closure_min_captures use different span borrow check uses new structures rename to CapturedPlace stop using upvar_capture in regionck remove the bridge cleanup from rebase + remove the upvar_capture reference from mutability_errors.rs remove line from livenes test make our unused var checking more consistent update tests adding more warnings to the tests move is_ancestor_or_same_capture to rustc_middle/ty update names to reflect the closures add FIXME check that all captures are immutable borrows before returning add surrounding if statement like the original move var out of the loop and rename Co-authored-by: Logan Mosier <logmosier@gmail.com> Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
This commit is contained in:
parent
1705a7d64b
commit
52dba13e41
14 changed files with 477 additions and 243 deletions
|
@ -168,6 +168,56 @@ impl CapturedPlace<'tcx> {
|
|||
base => bug!("Expected upvar, found={:?}", base),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `LocalDefId` of the closure that captureed this Place
|
||||
pub fn get_closure_local_def_id(&self) -> LocalDefId {
|
||||
match self.place.base {
|
||||
HirPlaceBase::Upvar(upvar_id) => upvar_id.closure_expr_id,
|
||||
base => bug!("expected upvar, found={:?}", base),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return span pointing to use that resulted in selecting the current capture kind
|
||||
pub fn get_capture_kind_span(&self, tcx: TyCtxt<'tcx>) -> Span {
|
||||
if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
|
||||
tcx.hir().span(capture_kind_expr_id)
|
||||
} else if let Some(path_expr_id) = self.info.path_expr_id {
|
||||
tcx.hir().span(path_expr_id)
|
||||
} else {
|
||||
// Fallback on upvars mentioned if neither path or capture expr id is captured
|
||||
|
||||
// Safe to unwrap since we know this place is captured by the closure, therefore the closure must have upvars.
|
||||
tcx.upvars_mentioned(self.get_closure_local_def_id()).unwrap()
|
||||
[&self.get_root_variable()]
|
||||
.span
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if the `proj_possible_ancestor` represents an ancestor path
|
||||
/// to `proj_capture` or `proj_possible_ancestor` is same as `proj_capture`,
|
||||
/// assuming they both start off of the same root variable.
|
||||
///
|
||||
/// **Note:** It's the caller's responsibility to ensure that both lists of projections
|
||||
/// start off of the same root variable.
|
||||
///
|
||||
/// Eg: 1. `foo.x` which is represented using `projections=[Field(x)]` is an ancestor of
|
||||
/// `foo.x.y` which is represented using `projections=[Field(x), Field(y)]`.
|
||||
/// Note both `foo.x` and `foo.x.y` start off of the same root variable `foo`.
|
||||
/// 2. Since we only look at the projections here function will return `bar.x` as an a valid
|
||||
/// ancestor of `foo.x.y`. It's the caller's responsibility to ensure that both projections
|
||||
/// list are being applied to the same root variable.
|
||||
pub fn is_ancestor_or_same_capture(
|
||||
proj_possible_ancestor: &[HirProjectionKind],
|
||||
proj_capture: &[HirProjectionKind],
|
||||
) -> bool {
|
||||
// We want to make sure `is_ancestor_or_same_capture("x.0.0", "x.0")` to return false.
|
||||
// Therefore we can't just check if all projections are same in the zipped iterator below.
|
||||
if proj_possible_ancestor.len() > proj_capture.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
proj_possible_ancestor.iter().zip(proj_capture).all(|(a, b)| a == b)
|
||||
}
|
||||
|
||||
/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
|
||||
|
|
|
@ -30,9 +30,7 @@ use rustc_attr as attr;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
hash_stable_hashmap, HashStable, StableHasher, StableVec,
|
||||
};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableVec};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
|
||||
use rustc_errors::ErrorReported;
|
||||
|
@ -386,9 +384,6 @@ pub struct TypeckResults<'tcx> {
|
|||
/// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
|
||||
pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
|
||||
|
||||
/// Borrows
|
||||
pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
|
||||
|
||||
/// Records the reasons that we picked the kind of each closure;
|
||||
/// not all closures are present in the map.
|
||||
closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
|
||||
|
@ -424,12 +419,6 @@ pub struct TypeckResults<'tcx> {
|
|||
/// by this function.
|
||||
pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
|
||||
|
||||
/// Given the closure ID this map provides the list of UpvarIDs used by it.
|
||||
/// The upvarID contains the HIR node ID and it also contains the full path
|
||||
/// leading to the member of the struct or tuple that is used instead of the
|
||||
/// entire variable.
|
||||
pub closure_captures: ty::UpvarListMap,
|
||||
|
||||
/// Tracks the minimum captures required for a closure;
|
||||
/// see `MinCaptureInformationMap` for more details.
|
||||
pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
|
||||
|
@ -482,7 +471,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
adjustments: Default::default(),
|
||||
pat_binding_modes: Default::default(),
|
||||
pat_adjustments: Default::default(),
|
||||
upvar_capture_map: Default::default(),
|
||||
closure_kind_origins: Default::default(),
|
||||
liberated_fn_sigs: Default::default(),
|
||||
fru_field_types: Default::default(),
|
||||
|
@ -490,7 +478,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
used_trait_imports: Lrc::new(Default::default()),
|
||||
tainted_by_errors: None,
|
||||
concrete_opaque_types: Default::default(),
|
||||
closure_captures: Default::default(),
|
||||
closure_min_captures: Default::default(),
|
||||
closure_fake_reads: Default::default(),
|
||||
generator_interior_types: ty::Binder::dummy(Default::default()),
|
||||
|
@ -675,10 +662,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
.flatten()
|
||||
}
|
||||
|
||||
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
|
||||
self.upvar_capture_map[&upvar_id]
|
||||
}
|
||||
|
||||
pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
|
||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
|
||||
}
|
||||
|
@ -722,7 +705,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
let ty::TypeckResults {
|
||||
hir_owner,
|
||||
hir_owner: _,
|
||||
ref type_dependent_defs,
|
||||
ref field_indices,
|
||||
ref user_provided_types,
|
||||
|
@ -732,17 +715,13 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
|
|||
ref adjustments,
|
||||
ref pat_binding_modes,
|
||||
ref pat_adjustments,
|
||||
ref upvar_capture_map,
|
||||
ref closure_kind_origins,
|
||||
ref liberated_fn_sigs,
|
||||
ref fru_field_types,
|
||||
|
||||
ref coercion_casts,
|
||||
|
||||
ref used_trait_imports,
|
||||
tainted_by_errors,
|
||||
ref concrete_opaque_types,
|
||||
ref closure_captures,
|
||||
ref closure_min_captures,
|
||||
ref closure_fake_reads,
|
||||
ref generator_interior_types,
|
||||
|
@ -759,17 +738,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
|
|||
adjustments.hash_stable(hcx, hasher);
|
||||
pat_binding_modes.hash_stable(hcx, hasher);
|
||||
pat_adjustments.hash_stable(hcx, hasher);
|
||||
hash_stable_hashmap(hcx, hasher, upvar_capture_map, |up_var_id, hcx| {
|
||||
let ty::UpvarId { var_path, closure_expr_id } = *up_var_id;
|
||||
|
||||
assert_eq!(var_path.hir_id.owner, hir_owner);
|
||||
|
||||
(
|
||||
hcx.local_def_path_hash(var_path.hir_id.owner),
|
||||
var_path.hir_id.local_id,
|
||||
hcx.local_def_path_hash(closure_expr_id),
|
||||
)
|
||||
});
|
||||
|
||||
closure_kind_origins.hash_stable(hcx, hasher);
|
||||
liberated_fn_sigs.hash_stable(hcx, hasher);
|
||||
|
@ -778,7 +746,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
|
|||
used_trait_imports.hash_stable(hcx, hasher);
|
||||
tainted_by_errors.hash_stable(hcx, hasher);
|
||||
concrete_opaque_types.hash_stable(hcx, hasher);
|
||||
closure_captures.hash_stable(hcx, hasher);
|
||||
closure_min_captures.hash_stable(hcx, hasher);
|
||||
closure_fake_reads.hash_stable(hcx, hasher);
|
||||
generator_interior_types.hash_stable(hcx, hasher);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue