add #[rustc_pass_by_value]
to more types
This commit is contained in:
parent
67b3e81838
commit
b8135fd5c8
@ -220,8 +220,8 @@ pub(crate) fn report_mutability_error(
|
|||||||
PlaceRef {
|
PlaceRef {
|
||||||
local,
|
local,
|
||||||
projection:
|
projection:
|
||||||
[
|
&[
|
||||||
proj_base @ ..,
|
ref proj_base @ ..,
|
||||||
ProjectionElem::Deref,
|
ProjectionElem::Deref,
|
||||||
ProjectionElem::Field(field, _),
|
ProjectionElem::Field(field, _),
|
||||||
ProjectionElem::Deref,
|
ProjectionElem::Deref,
|
||||||
@ -342,7 +342,7 @@ pub(crate) fn report_mutability_error(
|
|||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
if let ty::Closure(id, _) = the_place_err.ty(self.body, tcx).ty.kind() {
|
if let ty::Closure(id, _) = *the_place_err.ty(self.body, tcx).ty.kind() {
|
||||||
self.show_mutating_upvar(tcx, id, the_place_err, &mut err);
|
self.show_mutating_upvar(tcx, id, the_place_err, &mut err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -382,7 +382,7 @@ pub(crate) fn report_mutability_error(
|
|||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
if let ty::Ref(_, ty, Mutability::Mut) = the_place_err.ty(self.body, tcx).ty.kind()
|
if let ty::Ref(_, ty, Mutability::Mut) = the_place_err.ty(self.body, tcx).ty.kind()
|
||||||
{
|
{
|
||||||
if let ty::Closure(id, _) = ty.kind() {
|
if let ty::Closure(id, _) = *ty.kind() {
|
||||||
self.show_mutating_upvar(tcx, id, the_place_err, &mut err);
|
self.show_mutating_upvar(tcx, id, the_place_err, &mut err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,7 +687,7 @@ fn is_error_in_trait(&self, local: Local) -> (bool, Option<Span>) {
|
|||||||
fn show_mutating_upvar(
|
fn show_mutating_upvar(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
id: &hir::def_id::DefId,
|
id: hir::def_id::DefId,
|
||||||
the_place_err: PlaceRef<'tcx>,
|
the_place_err: PlaceRef<'tcx>,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
) {
|
) {
|
||||||
@ -701,7 +701,7 @@ fn show_mutating_upvar(
|
|||||||
let upvar = ty::place_to_string_for_capture(tcx, closure_kind_origin);
|
let upvar = ty::place_to_string_for_capture(tcx, closure_kind_origin);
|
||||||
let root_hir_id = upvar_id.var_path.hir_id;
|
let root_hir_id = upvar_id.var_path.hir_id;
|
||||||
// we have an origin for this closure kind starting at this root variable so it's safe to unwrap here
|
// we have an origin for this closure kind starting at this root variable so it's safe to unwrap here
|
||||||
let captured_places = tables.closure_min_captures[id].get(&root_hir_id).unwrap();
|
let captured_places = tables.closure_min_captures[&id].get(&root_hir_id).unwrap();
|
||||||
|
|
||||||
let origin_projection = closure_kind_origin
|
let origin_projection = closure_kind_origin
|
||||||
.projections
|
.projections
|
||||||
@ -1083,7 +1083,7 @@ fn is_closure_or_generator(ty: Ty<'_>) -> bool {
|
|||||||
fn get_mut_span_in_struct_field<'tcx>(
|
fn get_mut_span_in_struct_field<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
field: &mir::Field,
|
field: mir::Field,
|
||||||
) -> Option<Span> {
|
) -> Option<Span> {
|
||||||
// Expect our local to be a reference to a struct of some kind.
|
// Expect our local to be a reference to a struct of some kind.
|
||||||
if let ty::Ref(_, ty, _) = ty.kind()
|
if let ty::Ref(_, ty, _) = ty.kind()
|
||||||
|
@ -100,7 +100,7 @@ pub fn to_location(&self, index: LocationIndex) -> RichLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocationIndex {
|
impl LocationIndex {
|
||||||
fn is_start(&self) -> bool {
|
fn is_start(self) -> bool {
|
||||||
// even indices are start points; odd indices are mid points
|
// even indices are start points; odd indices are mid points
|
||||||
(self.index() % 2) == 0
|
(self.index() % 2) == 0
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ fn populate_polonius_move_facts(
|
|||||||
) {
|
) {
|
||||||
all_facts
|
all_facts
|
||||||
.path_is_var
|
.path_is_var
|
||||||
.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(v, &m)| (m, v)));
|
.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l)));
|
||||||
|
|
||||||
for (child, move_path) in move_data.move_paths.iter_enumerated() {
|
for (child, move_path) in move_data.move_paths.iter_enumerated() {
|
||||||
if let Some(parent) = move_path.parent {
|
if let Some(parent) = move_path.parent {
|
||||||
@ -135,7 +135,7 @@ fn populate_polonius_move_facts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (local, &path) in move_data.rev_lookup.iter_locals_enumerated() {
|
for (local, path) in move_data.rev_lookup.iter_locals_enumerated() {
|
||||||
if body.local_kind(local) != LocalKind::Arg {
|
if body.local_kind(local) != LocalKind::Arg {
|
||||||
// Non-arguments start out deinitialised; we simulate this with an
|
// Non-arguments start out deinitialised; we simulate this with an
|
||||||
// initial move:
|
// initial move:
|
||||||
@ -226,7 +226,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
|||||||
fr1={:?}, fr2={:?}",
|
fr1={:?}, fr2={:?}",
|
||||||
fr1, fr2
|
fr1, fr2
|
||||||
);
|
);
|
||||||
all_facts.known_placeholder_subset.push((*fr1, *fr2));
|
all_facts.known_placeholder_subset.push((fr1, fr2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -942,14 +942,14 @@ fn try_promote_type_test(
|
|||||||
|
|
||||||
debug!("try_promote_type_test: ur={:?}", ur);
|
debug!("try_promote_type_test: ur={:?}", ur);
|
||||||
|
|
||||||
let non_local_ub = self.universal_region_relations.non_local_upper_bounds(&ur);
|
let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur);
|
||||||
debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
|
debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
|
||||||
|
|
||||||
// This is slightly too conservative. To show T: '1, given `'2: '1`
|
// This is slightly too conservative. To show T: '1, given `'2: '1`
|
||||||
// and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
|
// and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
|
||||||
// avoid potential non-determinism we approximate this by requiring
|
// avoid potential non-determinism we approximate this by requiring
|
||||||
// T: '1 and T: '2.
|
// T: '1 and T: '2.
|
||||||
for &upper_bound in non_local_ub {
|
for upper_bound in non_local_ub {
|
||||||
debug_assert!(self.universal_regions.is_universal_region(upper_bound));
|
debug_assert!(self.universal_regions.is_universal_region(upper_bound));
|
||||||
debug_assert!(!self.universal_regions.is_local_free_region(upper_bound));
|
debug_assert!(!self.universal_regions.is_local_free_region(upper_bound));
|
||||||
|
|
||||||
@ -1588,12 +1588,12 @@ fn try_propagate_universal_region_error(
|
|||||||
// always will.) We'll call them `shorter_fr+` -- they're ever
|
// always will.) We'll call them `shorter_fr+` -- they're ever
|
||||||
// so slightly larger than `shorter_fr`.
|
// so slightly larger than `shorter_fr`.
|
||||||
let shorter_fr_plus =
|
let shorter_fr_plus =
|
||||||
self.universal_region_relations.non_local_upper_bounds(&shorter_fr);
|
self.universal_region_relations.non_local_upper_bounds(shorter_fr);
|
||||||
debug!(
|
debug!(
|
||||||
"try_propagate_universal_region_error: shorter_fr_plus={:?}",
|
"try_propagate_universal_region_error: shorter_fr_plus={:?}",
|
||||||
shorter_fr_plus
|
shorter_fr_plus
|
||||||
);
|
);
|
||||||
for &&fr in &shorter_fr_plus {
|
for fr in shorter_fr_plus {
|
||||||
// Push the constraint `fr-: shorter_fr+`
|
// Push the constraint `fr-: shorter_fr+`
|
||||||
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
|
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
|
||||||
subject: ClosureOutlivesSubject::Region(fr_minus),
|
subject: ClosureOutlivesSubject::Region(fr_minus),
|
||||||
|
@ -99,10 +99,9 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
crate fn postdom_upper_bound(&self, fr1: RegionVid, fr2: RegionVid) -> RegionVid {
|
crate fn postdom_upper_bound(&self, fr1: RegionVid, fr2: RegionVid) -> RegionVid {
|
||||||
assert!(self.universal_regions.is_universal_region(fr1));
|
assert!(self.universal_regions.is_universal_region(fr1));
|
||||||
assert!(self.universal_regions.is_universal_region(fr2));
|
assert!(self.universal_regions.is_universal_region(fr2));
|
||||||
*self
|
self.inverse_outlives
|
||||||
.inverse_outlives
|
.postdom_upper_bound(fr1, fr2)
|
||||||
.postdom_upper_bound(&fr1, &fr2)
|
.unwrap_or(self.universal_regions.fr_static)
|
||||||
.unwrap_or(&self.universal_regions.fr_static)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds an "upper bound" for `fr` that is not local. In other
|
/// Finds an "upper bound" for `fr` that is not local. In other
|
||||||
@ -110,7 +109,7 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
/// outlives `fr` and (b) is not local.
|
/// outlives `fr` and (b) is not local.
|
||||||
///
|
///
|
||||||
/// (*) If there are multiple competing choices, we return all of them.
|
/// (*) If there are multiple competing choices, we return all of them.
|
||||||
crate fn non_local_upper_bounds<'a>(&'a self, fr: &'a RegionVid) -> Vec<&'a RegionVid> {
|
crate fn non_local_upper_bounds<'a>(&'a self, fr: RegionVid) -> Vec<RegionVid> {
|
||||||
debug!("non_local_upper_bound(fr={:?})", fr);
|
debug!("non_local_upper_bound(fr={:?})", fr);
|
||||||
let res = self.non_local_bounds(&self.inverse_outlives, fr);
|
let res = self.non_local_bounds(&self.inverse_outlives, fr);
|
||||||
assert!(!res.is_empty(), "can't find an upper bound!?");
|
assert!(!res.is_empty(), "can't find an upper bound!?");
|
||||||
@ -120,7 +119,7 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
/// Returns the "postdominating" bound of the set of
|
/// Returns the "postdominating" bound of the set of
|
||||||
/// `non_local_upper_bounds` for the given region.
|
/// `non_local_upper_bounds` for the given region.
|
||||||
crate fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid {
|
crate fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid {
|
||||||
let upper_bounds = self.non_local_upper_bounds(&fr);
|
let upper_bounds = self.non_local_upper_bounds(fr);
|
||||||
|
|
||||||
// In case we find more than one, reduce to one for
|
// In case we find more than one, reduce to one for
|
||||||
// convenience. This is to prevent us from generating more
|
// convenience. This is to prevent us from generating more
|
||||||
@ -130,7 +129,7 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
debug!("non_local_bound: post_dom={:?}", post_dom);
|
debug!("non_local_bound: post_dom={:?}", post_dom);
|
||||||
|
|
||||||
post_dom
|
post_dom
|
||||||
.and_then(|&post_dom| {
|
.and_then(|post_dom| {
|
||||||
// If the mutual immediate postdom is not local, then
|
// If the mutual immediate postdom is not local, then
|
||||||
// there is no non-local result we can return.
|
// there is no non-local result we can return.
|
||||||
if !self.universal_regions.is_local_free_region(post_dom) {
|
if !self.universal_regions.is_local_free_region(post_dom) {
|
||||||
@ -150,7 +149,7 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
/// one. See `TransitiveRelation::postdom_upper_bound` for details.
|
/// one. See `TransitiveRelation::postdom_upper_bound` for details.
|
||||||
crate fn non_local_lower_bound(&self, fr: RegionVid) -> Option<RegionVid> {
|
crate fn non_local_lower_bound(&self, fr: RegionVid) -> Option<RegionVid> {
|
||||||
debug!("non_local_lower_bound(fr={:?})", fr);
|
debug!("non_local_lower_bound(fr={:?})", fr);
|
||||||
let lower_bounds = self.non_local_bounds(&self.outlives, &fr);
|
let lower_bounds = self.non_local_bounds(&self.outlives, fr);
|
||||||
|
|
||||||
// In case we find more than one, reduce to one for
|
// In case we find more than one, reduce to one for
|
||||||
// convenience. This is to prevent us from generating more
|
// convenience. This is to prevent us from generating more
|
||||||
@ -159,7 +158,7 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
|
|
||||||
debug!("non_local_bound: post_dom={:?}", post_dom);
|
debug!("non_local_bound: post_dom={:?}", post_dom);
|
||||||
|
|
||||||
post_dom.and_then(|&post_dom| {
|
post_dom.and_then(|post_dom| {
|
||||||
// If the mutual immediate postdom is not local, then
|
// If the mutual immediate postdom is not local, then
|
||||||
// there is no non-local result we can return.
|
// there is no non-local result we can return.
|
||||||
if !self.universal_regions.is_local_free_region(post_dom) {
|
if !self.universal_regions.is_local_free_region(post_dom) {
|
||||||
@ -176,11 +175,11 @@ fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
|||||||
fn non_local_bounds<'a>(
|
fn non_local_bounds<'a>(
|
||||||
&self,
|
&self,
|
||||||
relation: &'a TransitiveRelation<RegionVid>,
|
relation: &'a TransitiveRelation<RegionVid>,
|
||||||
fr0: &'a RegionVid,
|
fr0: RegionVid,
|
||||||
) -> Vec<&'a RegionVid> {
|
) -> Vec<RegionVid> {
|
||||||
// This method assumes that `fr0` is one of the universally
|
// This method assumes that `fr0` is one of the universally
|
||||||
// quantified region variables.
|
// quantified region variables.
|
||||||
assert!(self.universal_regions.is_universal_region(*fr0));
|
assert!(self.universal_regions.is_universal_region(fr0));
|
||||||
|
|
||||||
let mut external_parents = vec![];
|
let mut external_parents = vec![];
|
||||||
let mut queue = vec![fr0];
|
let mut queue = vec![fr0];
|
||||||
@ -188,7 +187,7 @@ fn non_local_bounds<'a>(
|
|||||||
// Keep expanding `fr` into its parents until we reach
|
// Keep expanding `fr` into its parents until we reach
|
||||||
// non-local regions.
|
// non-local regions.
|
||||||
while let Some(fr) = queue.pop() {
|
while let Some(fr) = queue.pop() {
|
||||||
if !self.universal_regions.is_local_free_region(*fr) {
|
if !self.universal_regions.is_local_free_region(fr) {
|
||||||
external_parents.push(fr);
|
external_parents.push(fr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -205,17 +204,17 @@ fn non_local_bounds<'a>(
|
|||||||
///
|
///
|
||||||
/// This will only ever be true for universally quantified regions.
|
/// This will only ever be true for universally quantified regions.
|
||||||
crate fn outlives(&self, fr1: RegionVid, fr2: RegionVid) -> bool {
|
crate fn outlives(&self, fr1: RegionVid, fr2: RegionVid) -> bool {
|
||||||
self.outlives.contains(&fr1, &fr2)
|
self.outlives.contains(fr1, fr2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector of free regions `x` such that `fr1: x` is
|
/// Returns a vector of free regions `x` such that `fr1: x` is
|
||||||
/// known to hold.
|
/// known to hold.
|
||||||
crate fn regions_outlived_by(&self, fr1: RegionVid) -> Vec<&RegionVid> {
|
crate fn regions_outlived_by(&self, fr1: RegionVid) -> Vec<RegionVid> {
|
||||||
self.outlives.reachable_from(&fr1)
|
self.outlives.reachable_from(fr1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the _non-transitive_ set of known `outlives` constraints between free regions.
|
/// Returns the _non-transitive_ set of known `outlives` constraints between free regions.
|
||||||
crate fn known_outlives(&self) -> impl Iterator<Item = (&RegionVid, &RegionVid)> {
|
crate fn known_outlives(&self) -> impl Iterator<Item = (RegionVid, RegionVid)> + '_ {
|
||||||
self.outlives.base_edges()
|
self.outlives.base_edges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1198,7 +1198,7 @@ fn relate_type_and_user_type(
|
|||||||
tcx,
|
tcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
proj,
|
proj,
|
||||||
|this, field, &()| {
|
|this, field, ()| {
|
||||||
let ty = this.field_ty(tcx, field);
|
let ty = this.field_ty(tcx, field);
|
||||||
self.normalize(ty, locations)
|
self.normalize(ty, locations)
|
||||||
},
|
},
|
||||||
|
@ -90,7 +90,7 @@ fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value {
|
|||||||
/// call. Since the function is never called, all other `CodeRegion`s can be
|
/// call. Since the function is never called, all other `CodeRegion`s can be
|
||||||
/// added as `unreachable_region`s.
|
/// added as `unreachable_region`s.
|
||||||
fn define_unused_fn(&self, def_id: DefId) {
|
fn define_unused_fn(&self, def_id: DefId) {
|
||||||
let instance = declare_unused_fn(self, &def_id);
|
let instance = declare_unused_fn(self, def_id);
|
||||||
codegen_unused_fn_and_counter(self, instance);
|
codegen_unused_fn_and_counter(self, instance);
|
||||||
add_unused_function_coverage(self, instance, def_id);
|
add_unused_function_coverage(self, instance, def_id);
|
||||||
}
|
}
|
||||||
@ -184,12 +184,12 @@ fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeReg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: &DefId) -> Instance<'tcx> {
|
fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
|
|
||||||
let instance = Instance::new(
|
let instance = Instance::new(
|
||||||
*def_id,
|
def_id,
|
||||||
InternalSubsts::for_item(tcx, *def_id, |param, _| {
|
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||||
tcx.lifetimes.re_erased.into()
|
tcx.lifetimes.re_erased.into()
|
||||||
} else {
|
} else {
|
||||||
|
@ -49,7 +49,7 @@ struct Edge {
|
|||||||
target: Index,
|
target: Index,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Eq + Hash> TransitiveRelation<T> {
|
impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.edges.is_empty()
|
self.edges.is_empty()
|
||||||
}
|
}
|
||||||
@ -58,8 +58,8 @@ pub fn elements(&self) -> impl Iterator<Item = &T> {
|
|||||||
self.elements.iter()
|
self.elements.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index(&self, a: &T) -> Option<Index> {
|
fn index(&self, a: T) -> Option<Index> {
|
||||||
self.elements.get_index_of(a).map(Index)
|
self.elements.get_index_of(&a).map(Index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_index(&mut self, a: T) -> Index {
|
fn add_index(&mut self, a: T) -> Index {
|
||||||
@ -76,12 +76,12 @@ fn add_index(&mut self, a: T) -> Index {
|
|||||||
/// `None`.
|
/// `None`.
|
||||||
pub fn maybe_map<F, U>(&self, mut f: F) -> Option<TransitiveRelation<U>>
|
pub fn maybe_map<F, U>(&self, mut f: F) -> Option<TransitiveRelation<U>>
|
||||||
where
|
where
|
||||||
F: FnMut(&T) -> Option<U>,
|
F: FnMut(T) -> Option<U>,
|
||||||
U: Clone + Debug + Eq + Hash + Clone,
|
U: Clone + Debug + Eq + Hash + Copy,
|
||||||
{
|
{
|
||||||
let mut result = TransitiveRelation::default();
|
let mut result = TransitiveRelation::default();
|
||||||
for edge in &self.edges {
|
for edge in &self.edges {
|
||||||
result.add(f(&self.elements[edge.source.0])?, f(&self.elements[edge.target.0])?);
|
result.add(f(self.elements[edge.source.0])?, f(self.elements[edge.target.0])?);
|
||||||
}
|
}
|
||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ pub fn add(&mut self, a: T, b: T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether `a < target` (transitively)
|
/// Checks whether `a < target` (transitively)
|
||||||
pub fn contains(&self, a: &T, b: &T) -> bool {
|
pub fn contains(&self, a: T, b: T) -> bool {
|
||||||
match (self.index(a), self.index(b)) {
|
match (self.index(a), self.index(b)) {
|
||||||
(Some(a), Some(b)) => self.with_closure(|closure| closure.contains(a.0, b.0)),
|
(Some(a), Some(b)) => self.with_closure(|closure| closure.contains(a.0, b.0)),
|
||||||
(None, _) | (_, None) => false,
|
(None, _) | (_, None) => false,
|
||||||
@ -113,10 +113,10 @@ pub fn contains(&self, a: &T, b: &T) -> bool {
|
|||||||
/// Really this probably ought to be `impl Iterator<Item = &T>`, but
|
/// Really this probably ought to be `impl Iterator<Item = &T>`, but
|
||||||
/// I'm too lazy to make that work, and -- given the caching
|
/// I'm too lazy to make that work, and -- given the caching
|
||||||
/// strategy -- it'd be a touch tricky anyhow.
|
/// strategy -- it'd be a touch tricky anyhow.
|
||||||
pub fn reachable_from(&self, a: &T) -> Vec<&T> {
|
pub fn reachable_from(&self, a: T) -> Vec<T> {
|
||||||
match self.index(a) {
|
match self.index(a) {
|
||||||
Some(a) => {
|
Some(a) => {
|
||||||
self.with_closure(|closure| closure.iter(a.0).map(|i| &self.elements[i]).collect())
|
self.with_closure(|closure| closure.iter(a.0).map(|i| self.elements[i]).collect())
|
||||||
}
|
}
|
||||||
None => vec![],
|
None => vec![],
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ pub fn reachable_from(&self, a: &T) -> Vec<&T> {
|
|||||||
/// a -> a1
|
/// a -> a1
|
||||||
/// b -> b1
|
/// b -> b1
|
||||||
/// ```
|
/// ```
|
||||||
pub fn postdom_upper_bound(&self, a: &T, b: &T) -> Option<&T> {
|
pub fn postdom_upper_bound(&self, a: T, b: T) -> Option<T> {
|
||||||
let mubs = self.minimal_upper_bounds(a, b);
|
let mubs = self.minimal_upper_bounds(a, b);
|
||||||
self.mutual_immediate_postdominator(mubs)
|
self.mutual_immediate_postdominator(mubs)
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ pub fn postdom_upper_bound(&self, a: &T, b: &T) -> Option<&T> {
|
|||||||
/// Viewing the relation as a graph, computes the "mutual
|
/// Viewing the relation as a graph, computes the "mutual
|
||||||
/// immediate postdominator" of a set of points (if one
|
/// immediate postdominator" of a set of points (if one
|
||||||
/// exists). See `postdom_upper_bound` for details.
|
/// exists). See `postdom_upper_bound` for details.
|
||||||
pub fn mutual_immediate_postdominator<'a>(&'a self, mut mubs: Vec<&'a T>) -> Option<&'a T> {
|
pub fn mutual_immediate_postdominator<'a>(&'a self, mut mubs: Vec<T>) -> Option<T> {
|
||||||
loop {
|
loop {
|
||||||
match mubs.len() {
|
match mubs.len() {
|
||||||
0 => return None,
|
0 => return None,
|
||||||
@ -189,7 +189,7 @@ pub fn mutual_immediate_postdominator<'a>(&'a self, mut mubs: Vec<&'a T>) -> Opt
|
|||||||
/// internal indices).
|
/// internal indices).
|
||||||
///
|
///
|
||||||
/// Note that this set can, in principle, have any size.
|
/// Note that this set can, in principle, have any size.
|
||||||
pub fn minimal_upper_bounds(&self, a: &T, b: &T) -> Vec<&T> {
|
pub fn minimal_upper_bounds(&self, a: T, b: T) -> Vec<T> {
|
||||||
let (Some(mut a), Some(mut b)) = (self.index(a), self.index(b)) else {
|
let (Some(mut a), Some(mut b)) = (self.index(a), self.index(b)) else {
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
@ -267,7 +267,7 @@ pub fn minimal_upper_bounds(&self, a: &T, b: &T) -> Vec<&T> {
|
|||||||
lub_indices
|
lub_indices
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.rev() // (4)
|
.rev() // (4)
|
||||||
.map(|i| &self.elements[i])
|
.map(|i| self.elements[i])
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ pub fn minimal_upper_bounds(&self, a: &T, b: &T) -> Vec<&T> {
|
|||||||
///
|
///
|
||||||
/// then `parents(a)` returns `[b, c]`. The `postdom_parent` function
|
/// then `parents(a)` returns `[b, c]`. The `postdom_parent` function
|
||||||
/// would further reduce this to just `f`.
|
/// would further reduce this to just `f`.
|
||||||
pub fn parents(&self, a: &T) -> Vec<&T> {
|
pub fn parents(&self, a: T) -> Vec<T> {
|
||||||
let Some(a) = self.index(a) else {
|
let Some(a) = self.index(a) else {
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
@ -314,7 +314,7 @@ pub fn parents(&self, a: &T) -> Vec<&T> {
|
|||||||
ancestors
|
ancestors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.rev() // (4)
|
.rev() // (4)
|
||||||
.map(|i| &self.elements[i])
|
.map(|i| self.elements[i])
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,10 +350,10 @@ fn compute_closure(&self) -> BitMatrix<usize, usize> {
|
|||||||
|
|
||||||
/// Lists all the base edges in the graph: the initial _non-transitive_ set of element
|
/// Lists all the base edges in the graph: the initial _non-transitive_ set of element
|
||||||
/// relations, which will be later used as the basis for the transitive closure computation.
|
/// relations, which will be later used as the basis for the transitive closure computation.
|
||||||
pub fn base_edges(&self) -> impl Iterator<Item = (&T, &T)> {
|
pub fn base_edges(&self) -> impl Iterator<Item = (T, T)> + '_ {
|
||||||
self.edges
|
self.edges
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |edge| (&self.elements[edge.source.0], &self.elements[edge.target.0]))
|
.map(move |edge| (self.elements[edge.source.0], self.elements[edge.target.0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<T: Eq + Hash> TransitiveRelation<T> {
|
impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
|
||||||
/// A "best" parent in some sense. See `parents` and
|
/// A "best" parent in some sense. See `parents` and
|
||||||
/// `postdom_upper_bound` for more details.
|
/// `postdom_upper_bound` for more details.
|
||||||
fn postdom_parent(&self, a: &T) -> Option<&T> {
|
fn postdom_parent(&self, a: T) -> Option<T> {
|
||||||
self.mutual_immediate_postdominator(self.parents(a))
|
self.mutual_immediate_postdominator(self.parents(a))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,10 +13,10 @@ fn test_one_step() {
|
|||||||
let mut relation = TransitiveRelation::default();
|
let mut relation = TransitiveRelation::default();
|
||||||
relation.add("a", "b");
|
relation.add("a", "b");
|
||||||
relation.add("a", "c");
|
relation.add("a", "c");
|
||||||
assert!(relation.contains(&"a", &"c"));
|
assert!(relation.contains("a", "c"));
|
||||||
assert!(relation.contains(&"a", &"b"));
|
assert!(relation.contains("a", "b"));
|
||||||
assert!(!relation.contains(&"b", &"a"));
|
assert!(!relation.contains("b", "a"));
|
||||||
assert!(!relation.contains(&"a", &"d"));
|
assert!(!relation.contains("a", "d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -32,17 +32,17 @@ fn test_many_steps() {
|
|||||||
|
|
||||||
relation.add("e", "g");
|
relation.add("e", "g");
|
||||||
|
|
||||||
assert!(relation.contains(&"a", &"b"));
|
assert!(relation.contains("a", "b"));
|
||||||
assert!(relation.contains(&"a", &"c"));
|
assert!(relation.contains("a", "c"));
|
||||||
assert!(relation.contains(&"a", &"d"));
|
assert!(relation.contains("a", "d"));
|
||||||
assert!(relation.contains(&"a", &"e"));
|
assert!(relation.contains("a", "e"));
|
||||||
assert!(relation.contains(&"a", &"f"));
|
assert!(relation.contains("a", "f"));
|
||||||
assert!(relation.contains(&"a", &"g"));
|
assert!(relation.contains("a", "g"));
|
||||||
|
|
||||||
assert!(relation.contains(&"b", &"g"));
|
assert!(relation.contains("b", "g"));
|
||||||
|
|
||||||
assert!(!relation.contains(&"a", &"x"));
|
assert!(!relation.contains("a", "x"));
|
||||||
assert!(!relation.contains(&"b", &"f"));
|
assert!(!relation.contains("b", "f"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -54,9 +54,9 @@ fn mubs_triangle() {
|
|||||||
let mut relation = TransitiveRelation::default();
|
let mut relation = TransitiveRelation::default();
|
||||||
relation.add("a", "tcx");
|
relation.add("a", "tcx");
|
||||||
relation.add("b", "tcx");
|
relation.add("b", "tcx");
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"tcx"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["tcx"]);
|
||||||
assert_eq!(relation.parents(&"a"), vec![&"tcx"]);
|
assert_eq!(relation.parents("a"), vec!["tcx"]);
|
||||||
assert_eq!(relation.parents(&"b"), vec![&"tcx"]);
|
assert_eq!(relation.parents("b"), vec!["tcx"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -81,10 +81,10 @@ fn mubs_best_choice1() {
|
|||||||
relation.add("3", "1");
|
relation.add("3", "1");
|
||||||
relation.add("3", "2");
|
relation.add("3", "2");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"2"]);
|
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["2"]);
|
||||||
assert_eq!(relation.parents(&"0"), vec![&"2"]);
|
assert_eq!(relation.parents("0"), vec!["2"]);
|
||||||
assert_eq!(relation.parents(&"2"), vec![&"1"]);
|
assert_eq!(relation.parents("2"), vec!["1"]);
|
||||||
assert!(relation.parents(&"1").is_empty());
|
assert!(relation.parents("1").is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -108,10 +108,10 @@ fn mubs_best_choice2() {
|
|||||||
relation.add("3", "1");
|
relation.add("3", "1");
|
||||||
relation.add("3", "2");
|
relation.add("3", "2");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1"]);
|
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["1"]);
|
||||||
assert_eq!(relation.parents(&"0"), vec![&"1"]);
|
assert_eq!(relation.parents("0"), vec!["1"]);
|
||||||
assert_eq!(relation.parents(&"1"), vec![&"2"]);
|
assert_eq!(relation.parents("1"), vec!["2"]);
|
||||||
assert!(relation.parents(&"2").is_empty());
|
assert!(relation.parents("2").is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -125,9 +125,9 @@ fn mubs_no_best_choice() {
|
|||||||
relation.add("3", "1");
|
relation.add("3", "1");
|
||||||
relation.add("3", "2");
|
relation.add("3", "2");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1", &"2"]);
|
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["1", "2"]);
|
||||||
assert_eq!(relation.parents(&"0"), vec![&"1", &"2"]);
|
assert_eq!(relation.parents("0"), vec!["1", "2"]);
|
||||||
assert_eq!(relation.parents(&"3"), vec![&"1", &"2"]);
|
assert_eq!(relation.parents("3"), vec!["1", "2"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -145,8 +145,8 @@ fn mubs_best_choice_scc() {
|
|||||||
relation.add("3", "1");
|
relation.add("3", "1");
|
||||||
relation.add("3", "2");
|
relation.add("3", "2");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1"]);
|
assert_eq!(relation.minimal_upper_bounds("0", "3"), vec!["1"]);
|
||||||
assert_eq!(relation.parents(&"0"), vec![&"1"]);
|
assert_eq!(relation.parents("0"), vec!["1"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -165,10 +165,10 @@ fn pdub_crisscross() {
|
|||||||
relation.add("a1", "x");
|
relation.add("a1", "x");
|
||||||
relation.add("b1", "x");
|
relation.add("b1", "x");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"a1", &"b1"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["a1", "b1"]);
|
||||||
assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x"));
|
assert_eq!(relation.postdom_upper_bound("a", "b"), Some("x"));
|
||||||
assert_eq!(relation.postdom_parent(&"a"), Some(&"x"));
|
assert_eq!(relation.postdom_parent("a"), Some("x"));
|
||||||
assert_eq!(relation.postdom_parent(&"b"), Some(&"x"));
|
assert_eq!(relation.postdom_parent("b"), Some("x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -195,12 +195,12 @@ fn pdub_crisscross_more() {
|
|||||||
relation.add("a3", "x");
|
relation.add("a3", "x");
|
||||||
relation.add("b2", "x");
|
relation.add("b2", "x");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"a1", &"b1"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["a1", "b1"]);
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"), vec![&"a2", &"b2"]);
|
assert_eq!(relation.minimal_upper_bounds("a1", "b1"), vec!["a2", "b2"]);
|
||||||
assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x"));
|
assert_eq!(relation.postdom_upper_bound("a", "b"), Some("x"));
|
||||||
|
|
||||||
assert_eq!(relation.postdom_parent(&"a"), Some(&"x"));
|
assert_eq!(relation.postdom_parent("a"), Some("x"));
|
||||||
assert_eq!(relation.postdom_parent(&"b"), Some(&"x"));
|
assert_eq!(relation.postdom_parent("b"), Some("x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -216,13 +216,13 @@ fn pdub_lub() {
|
|||||||
relation.add("a1", "x");
|
relation.add("a1", "x");
|
||||||
relation.add("b1", "x");
|
relation.add("b1", "x");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"x"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["x"]);
|
||||||
assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x"));
|
assert_eq!(relation.postdom_upper_bound("a", "b"), Some("x"));
|
||||||
|
|
||||||
assert_eq!(relation.postdom_parent(&"a"), Some(&"a1"));
|
assert_eq!(relation.postdom_parent("a"), Some("a1"));
|
||||||
assert_eq!(relation.postdom_parent(&"b"), Some(&"b1"));
|
assert_eq!(relation.postdom_parent("b"), Some("b1"));
|
||||||
assert_eq!(relation.postdom_parent(&"a1"), Some(&"x"));
|
assert_eq!(relation.postdom_parent("a1"), Some("x"));
|
||||||
assert_eq!(relation.postdom_parent(&"b1"), Some(&"x"));
|
assert_eq!(relation.postdom_parent("b1"), Some("x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -238,7 +238,7 @@ fn mubs_intermediate_node_on_one_side_only() {
|
|||||||
relation.add("c", "d");
|
relation.add("c", "d");
|
||||||
relation.add("b", "d");
|
relation.add("b", "d");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"d"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["d"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -259,7 +259,7 @@ fn mubs_scc_1() {
|
|||||||
relation.add("a", "d");
|
relation.add("a", "d");
|
||||||
relation.add("b", "d");
|
relation.add("b", "d");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -279,7 +279,7 @@ fn mubs_scc_2() {
|
|||||||
relation.add("b", "d");
|
relation.add("b", "d");
|
||||||
relation.add("b", "c");
|
relation.add("b", "c");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -300,7 +300,7 @@ fn mubs_scc_3() {
|
|||||||
relation.add("b", "d");
|
relation.add("b", "d");
|
||||||
relation.add("b", "e");
|
relation.add("b", "e");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -322,7 +322,7 @@ fn mubs_scc_4() {
|
|||||||
relation.add("a", "d");
|
relation.add("a", "d");
|
||||||
relation.add("b", "e");
|
relation.add("b", "e");
|
||||||
|
|
||||||
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
|
assert_eq!(relation.minimal_upper_bounds("a", "b"), vec!["c"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -357,6 +357,6 @@ fn parent() {
|
|||||||
relation.add(a, b);
|
relation.add(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
let p = relation.postdom_parent(&3);
|
let p = relation.postdom_parent(3);
|
||||||
assert_eq!(p, Some(&0));
|
assert_eq!(p, Some(0));
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
/// the code base.
|
/// the code base.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
#[derive(Encodable, Decodable)]
|
#[derive(Encodable, Decodable)]
|
||||||
|
#[rustc_pass_by_value]
|
||||||
pub struct HirId {
|
pub struct HirId {
|
||||||
pub owner: LocalDefId,
|
pub owner: LocalDefId,
|
||||||
pub local_id: ItemLocalId,
|
pub local_id: ItemLocalId,
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -86,7 +86,7 @@ pub fn sub_free_regions(
|
|||||||
|
|
||||||
/// Check whether `r_a <= r_b` is found in the relation.
|
/// Check whether `r_a <= r_b` is found in the relation.
|
||||||
fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool {
|
fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool {
|
||||||
r_a == r_b || self.relation.contains(&r_a, &r_b)
|
r_a == r_b || self.relation.contains(r_a, r_b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// True for free regions other than `'static`.
|
/// True for free regions other than `'static`.
|
||||||
@ -119,9 +119,9 @@ pub fn lub_free_regions(
|
|||||||
let result = if r_a == r_b {
|
let result = if r_a == r_b {
|
||||||
r_a
|
r_a
|
||||||
} else {
|
} else {
|
||||||
match self.relation.postdom_upper_bound(&r_a, &r_b) {
|
match self.relation.postdom_upper_bound(r_a, r_b) {
|
||||||
None => tcx.lifetimes.re_static,
|
None => tcx.lifetimes.re_static,
|
||||||
Some(r) => *r,
|
Some(r) => r,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
|
debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
|
||||||
@ -132,6 +132,6 @@ pub fn lub_free_regions(
|
|||||||
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
|
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
|
||||||
type Lifted = FreeRegionMap<'tcx>;
|
type Lifted = FreeRegionMap<'tcx>;
|
||||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {
|
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {
|
||||||
self.relation.maybe_map(|&fr| tcx.lift(fr)).map(|relation| FreeRegionMap { relation })
|
self.relation.maybe_map(|fr| tcx.lift(fr)).map(|relation| FreeRegionMap { relation })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,7 @@ fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
|||||||
#(#attrs)*
|
#(#attrs)*
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)]
|
||||||
#[rustc_layout_scalar_valid_range_end(#max)]
|
#[rustc_layout_scalar_valid_range_end(#max)]
|
||||||
|
#[rustc_pass_by_value]
|
||||||
#vis struct #name {
|
#vis struct #name {
|
||||||
private: u32,
|
private: u32,
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
@ -46,7 +46,7 @@ impl CounterValueReference {
|
|||||||
|
|
||||||
/// Returns explicitly-requested zero-based version of the counter id, used
|
/// Returns explicitly-requested zero-based version of the counter id, used
|
||||||
/// during codegen. LLVM expects zero-based indexes.
|
/// during codegen. LLVM expects zero-based indexes.
|
||||||
pub fn zero_based_index(&self) -> u32 {
|
pub fn zero_based_index(self) -> u32 {
|
||||||
let one_based_index = self.as_u32();
|
let one_based_index = self.as_u32();
|
||||||
debug_assert!(one_based_index > 0);
|
debug_assert!(one_based_index > 0);
|
||||||
one_based_index - 1
|
one_based_index - 1
|
||||||
|
@ -1292,6 +1292,8 @@ pub enum InlineAsmOperand<'tcx> {
|
|||||||
/// Type for MIR `Assert` terminator error messages.
|
/// Type for MIR `Assert` terminator error messages.
|
||||||
pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
|
pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
|
||||||
|
|
||||||
|
// FIXME: Change `Successors` to `impl Iterator<Item = BasicBlock>`.
|
||||||
|
#[allow(rustc::pass_by_value)]
|
||||||
pub type Successors<'a> =
|
pub type Successors<'a> =
|
||||||
iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
|
iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
|
||||||
pub type SuccessorsMut<'a> =
|
pub type SuccessorsMut<'a> =
|
||||||
@ -1832,7 +1834,8 @@ pub fn is_field_to(&self, f: Field) -> bool {
|
|||||||
/// and the index is a local.
|
/// and the index is a local.
|
||||||
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
||||||
|
|
||||||
// At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
|
// This type is fairly frequently used, so we shouldn't unintentionally increase
|
||||||
|
// its size.
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||||
static_assert_size!(PlaceElem<'_>, 24);
|
static_assert_size!(PlaceElem<'_>, 24);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
|
|||||||
/// not carry a `Ty` for `T`.)
|
/// not carry a `Ty` for `T`.)
|
||||||
///
|
///
|
||||||
/// Note that the resulting type has not been normalized.
|
/// Note that the resulting type has not been normalized.
|
||||||
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
|
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> {
|
||||||
let answer = match self.ty.kind() {
|
let answer = match self.ty.kind() {
|
||||||
ty::Adt(adt_def, substs) => {
|
ty::Adt(adt_def, substs) => {
|
||||||
let variant_def = match self.variant_index {
|
let variant_def = match self.variant_index {
|
||||||
@ -57,7 +57,7 @@ pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
|
|||||||
/// `PlaceElem`, where we can just use the `Ty` that is already
|
/// `PlaceElem`, where we can just use the `Ty` that is already
|
||||||
/// stored inline on field projection elems.
|
/// stored inline on field projection elems.
|
||||||
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
|
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
|
||||||
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, &ty| ty)
|
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, ty| ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
|
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
|
||||||
@ -70,11 +70,11 @@ pub fn projection_ty_core<V, T>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
elem: &ProjectionElem<V, T>,
|
elem: &ProjectionElem<V, T>,
|
||||||
mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>,
|
mut handle_field: impl FnMut(&Self, Field, T) -> Ty<'tcx>,
|
||||||
) -> PlaceTy<'tcx>
|
) -> PlaceTy<'tcx>
|
||||||
where
|
where
|
||||||
V: ::std::fmt::Debug,
|
V: ::std::fmt::Debug,
|
||||||
T: ::std::fmt::Debug,
|
T: ::std::fmt::Debug + Copy,
|
||||||
{
|
{
|
||||||
let answer = match *elem {
|
let answer = match *elem {
|
||||||
ProjectionElem::Deref => {
|
ProjectionElem::Deref => {
|
||||||
@ -105,7 +105,7 @@ pub fn projection_ty_core<V, T>(
|
|||||||
ProjectionElem::Downcast(_name, index) => {
|
ProjectionElem::Downcast(_name, index) => {
|
||||||
PlaceTy { ty: self.ty, variant_index: Some(index) }
|
PlaceTy { ty: self.ty, variant_index: Some(index) }
|
||||||
}
|
}
|
||||||
ProjectionElem::Field(ref f, ref fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
|
ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
|
||||||
};
|
};
|
||||||
debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
|
debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
|
||||||
answer
|
answer
|
||||||
|
@ -225,12 +225,14 @@ fn visit_var_debug_info(&mut self,
|
|||||||
self.super_var_debug_info(var_debug_info);
|
self.super_var_debug_info(var_debug_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::pass_by_value)]
|
||||||
fn visit_local(&mut self,
|
fn visit_local(&mut self,
|
||||||
_local: & $($mutability)? Local,
|
_local: & $($mutability)? Local,
|
||||||
_context: PlaceContext,
|
_context: PlaceContext,
|
||||||
_location: Location) {
|
_location: Location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::pass_by_value)]
|
||||||
fn visit_source_scope(&mut self,
|
fn visit_source_scope(&mut self,
|
||||||
scope: & $($mutability)? SourceScope) {
|
scope: & $($mutability)? SourceScope) {
|
||||||
self.super_source_scope(scope);
|
self.super_source_scope(scope);
|
||||||
@ -851,6 +853,7 @@ fn super_var_debug_info(&mut self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::pass_by_value)]
|
||||||
fn super_source_scope(&mut self,
|
fn super_source_scope(&mut self,
|
||||||
_scope: & $($mutability)? SourceScope) {
|
_scope: & $($mutability)? SourceScope) {
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ pub struct InitIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MoveOutIndex {
|
impl MoveOutIndex {
|
||||||
pub fn move_path_index(&self, move_data: &MoveData<'_>) -> MovePathIndex {
|
pub fn move_path_index(self, move_data: &MoveData<'_>) -> MovePathIndex {
|
||||||
move_data.moves[*self].path
|
move_data.moves[self].path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,8 +338,8 @@ pub fn find_local(&self, local: Local) -> MovePathIndex {
|
|||||||
/// `MovePathIndex`es.
|
/// `MovePathIndex`es.
|
||||||
pub fn iter_locals_enumerated(
|
pub fn iter_locals_enumerated(
|
||||||
&self,
|
&self,
|
||||||
) -> impl DoubleEndedIterator<Item = (Local, &MovePathIndex)> + ExactSizeIterator {
|
) -> impl DoubleEndedIterator<Item = (Local, MovePathIndex)> + ExactSizeIterator + '_ {
|
||||||
self.locals.iter_enumerated()
|
self.locals.iter_enumerated().map(|(l, &idx)| (l, idx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,10 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
|||||||
&AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => {
|
&AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => {
|
||||||
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
|
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
|
||||||
self.tcx.unsafety_check_result(def_id.expect_local());
|
self.tcx.unsafety_check_result(def_id.expect_local());
|
||||||
self.register_violations(violations, used_unsafe_blocks);
|
self.register_violations(
|
||||||
|
violations,
|
||||||
|
used_unsafe_blocks.iter().map(|(&h, &d)| (h, d)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -261,7 +264,7 @@ fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViola
|
|||||||
fn register_violations<'a>(
|
fn register_violations<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
|
violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
|
||||||
new_used_unsafe_blocks: impl IntoIterator<Item = (&'a HirId, &'a UsedUnsafeBlockData)>,
|
new_used_unsafe_blocks: impl IntoIterator<Item = (HirId, UsedUnsafeBlockData)>,
|
||||||
) {
|
) {
|
||||||
use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
|
use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
|
||||||
|
|
||||||
@ -318,7 +321,7 @@ fn register_violations<'a>(
|
|||||||
|
|
||||||
new_used_unsafe_blocks
|
new_used_unsafe_blocks
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.for_each(|(&hir_id, &usage_data)| update_entry(self, hir_id, usage_data));
|
.for_each(|(hir_id, usage_data)| update_entry(self, hir_id, usage_data));
|
||||||
}
|
}
|
||||||
fn check_mut_borrowing_layout_constrained_field(
|
fn check_mut_borrowing_layout_constrained_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -48,7 +48,7 @@ pub fn from_mir(mir_body: &mir::Body<'_>) -> Self {
|
|||||||
let mut bcb_successors = Vec::new();
|
let mut bcb_successors = Vec::new();
|
||||||
for successor in
|
for successor in
|
||||||
bcb_filtered_successors(&mir_body, &bcb_data.terminator(mir_body).kind)
|
bcb_filtered_successors(&mir_body, &bcb_data.terminator(mir_body).kind)
|
||||||
.filter_map(|&successor_bb| bb_to_bcb[successor_bb])
|
.filter_map(|successor_bb| bb_to_bcb[successor_bb])
|
||||||
{
|
{
|
||||||
if !seen[successor] {
|
if !seen[successor] {
|
||||||
seen[successor] = true;
|
seen[successor] = true;
|
||||||
@ -483,7 +483,7 @@ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|||||||
fn bcb_filtered_successors<'a, 'tcx>(
|
fn bcb_filtered_successors<'a, 'tcx>(
|
||||||
body: &'tcx &'a mir::Body<'tcx>,
|
body: &'tcx &'a mir::Body<'tcx>,
|
||||||
term_kind: &'tcx TerminatorKind<'tcx>,
|
term_kind: &'tcx TerminatorKind<'tcx>,
|
||||||
) -> Box<dyn Iterator<Item = &'a BasicBlock> + 'a> {
|
) -> Box<dyn Iterator<Item = BasicBlock> + 'a> {
|
||||||
let mut successors = term_kind.successors();
|
let mut successors = term_kind.successors();
|
||||||
Box::new(
|
Box::new(
|
||||||
match &term_kind {
|
match &term_kind {
|
||||||
@ -494,9 +494,8 @@ fn bcb_filtered_successors<'a, 'tcx>(
|
|||||||
// `next().into_iter()`) into the `mir::Successors` aliased type.
|
// `next().into_iter()`) into the `mir::Successors` aliased type.
|
||||||
_ => successors.next().into_iter().chain(&[]),
|
_ => successors.next().into_iter().chain(&[]),
|
||||||
}
|
}
|
||||||
.filter(move |&&successor| {
|
.copied()
|
||||||
body[successor].terminator().kind != TerminatorKind::Unreachable
|
.filter(move |&successor| body[successor].terminator().kind != TerminatorKind::Unreachable),
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +694,7 @@ pub struct ShortCircuitPreorder<
|
|||||||
F: Fn(
|
F: Fn(
|
||||||
&'tcx &'a mir::Body<'tcx>,
|
&'tcx &'a mir::Body<'tcx>,
|
||||||
&'tcx TerminatorKind<'tcx>,
|
&'tcx TerminatorKind<'tcx>,
|
||||||
) -> Box<dyn Iterator<Item = &'a BasicBlock> + 'a>,
|
) -> Box<dyn Iterator<Item = BasicBlock> + 'a>,
|
||||||
> {
|
> {
|
||||||
body: &'tcx &'a mir::Body<'tcx>,
|
body: &'tcx &'a mir::Body<'tcx>,
|
||||||
visited: BitSet<BasicBlock>,
|
visited: BitSet<BasicBlock>,
|
||||||
@ -709,7 +708,7 @@ impl<
|
|||||||
F: Fn(
|
F: Fn(
|
||||||
&'tcx &'a mir::Body<'tcx>,
|
&'tcx &'a mir::Body<'tcx>,
|
||||||
&'tcx TerminatorKind<'tcx>,
|
&'tcx TerminatorKind<'tcx>,
|
||||||
) -> Box<dyn Iterator<Item = &'a BasicBlock> + 'a>,
|
) -> Box<dyn Iterator<Item = BasicBlock> + 'a>,
|
||||||
> ShortCircuitPreorder<'a, 'tcx, F>
|
> ShortCircuitPreorder<'a, 'tcx, F>
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@ -733,7 +732,7 @@ impl<
|
|||||||
F: Fn(
|
F: Fn(
|
||||||
&'tcx &'a mir::Body<'tcx>,
|
&'tcx &'a mir::Body<'tcx>,
|
||||||
&'tcx TerminatorKind<'tcx>,
|
&'tcx TerminatorKind<'tcx>,
|
||||||
) -> Box<dyn Iterator<Item = &'a BasicBlock> + 'a>,
|
) -> Box<dyn Iterator<Item = BasicBlock> + 'a>,
|
||||||
> Iterator for ShortCircuitPreorder<'a, 'tcx, F>
|
> Iterator for ShortCircuitPreorder<'a, 'tcx, F>
|
||||||
{
|
{
|
||||||
type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
|
type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
|
||||||
|
@ -707,7 +707,7 @@ fn statement_equality(
|
|||||||
) -> StatementEquality {
|
) -> StatementEquality {
|
||||||
let helper = |rhs: &Rvalue<'tcx>,
|
let helper = |rhs: &Rvalue<'tcx>,
|
||||||
place: &Place<'tcx>,
|
place: &Place<'tcx>,
|
||||||
variant_index: &VariantIdx,
|
variant_index: VariantIdx,
|
||||||
switch_value: u128,
|
switch_value: u128,
|
||||||
side_to_choose| {
|
side_to_choose| {
|
||||||
let place_type = place.ty(self.body, self.tcx).ty;
|
let place_type = place.ty(self.body, self.tcx).ty;
|
||||||
@ -717,7 +717,7 @@ fn statement_equality(
|
|||||||
};
|
};
|
||||||
// We need to make sure that the switch value that targets the bb with
|
// We need to make sure that the switch value that targets the bb with
|
||||||
// SetDiscriminant is the same as the variant discriminant.
|
// SetDiscriminant is the same as the variant discriminant.
|
||||||
let variant_discr = adt.discriminant_for_variant(self.tcx, *variant_index).val;
|
let variant_discr = adt.discriminant_for_variant(self.tcx, variant_index).val;
|
||||||
if variant_discr != switch_value {
|
if variant_discr != switch_value {
|
||||||
trace!(
|
trace!(
|
||||||
"NO: variant discriminant {} does not equal switch value {}",
|
"NO: variant discriminant {} does not equal switch value {}",
|
||||||
@ -726,7 +726,7 @@ fn statement_equality(
|
|||||||
);
|
);
|
||||||
return StatementEquality::NotEqual;
|
return StatementEquality::NotEqual;
|
||||||
}
|
}
|
||||||
let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty();
|
let variant_is_fieldless = adt.variants[variant_index].fields.is_empty();
|
||||||
if !variant_is_fieldless {
|
if !variant_is_fieldless {
|
||||||
trace!("NO: variant {:?} was not fieldless", variant_index);
|
trace!("NO: variant {:?} was not fieldless", variant_index);
|
||||||
return StatementEquality::NotEqual;
|
return StatementEquality::NotEqual;
|
||||||
@ -753,7 +753,7 @@ fn statement_equality(
|
|||||||
// check for case A
|
// check for case A
|
||||||
(
|
(
|
||||||
StatementKind::Assign(box (_, rhs)),
|
StatementKind::Assign(box (_, rhs)),
|
||||||
StatementKind::SetDiscriminant { place, variant_index },
|
&StatementKind::SetDiscriminant { ref place, variant_index },
|
||||||
) if y_target_and_value.value.is_some() => {
|
) if y_target_and_value.value.is_some() => {
|
||||||
// choose basic block of x, as that has the assign
|
// choose basic block of x, as that has the assign
|
||||||
helper(
|
helper(
|
||||||
@ -765,8 +765,8 @@ fn statement_equality(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
StatementKind::SetDiscriminant { place, variant_index },
|
&StatementKind::SetDiscriminant { ref place, variant_index },
|
||||||
StatementKind::Assign(box (_, rhs)),
|
&StatementKind::Assign(box (_, ref rhs)),
|
||||||
) if x_target_and_value.value.is_some() => {
|
) if x_target_and_value.value.is_some() => {
|
||||||
// choose basic block of y, as that has the assign
|
// choose basic block of y, as that has the assign
|
||||||
helper(
|
helper(
|
||||||
|
@ -27,8 +27,8 @@ pub fn new(x: usize) -> CrateNum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_def_id(&self) -> DefId {
|
pub fn as_def_id(self) -> DefId {
|
||||||
DefId { krate: *self, index: CRATE_DEF_INDEX }
|
DefId { krate: self, index: CRATE_DEF_INDEX }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +222,7 @@ impl<D: Decoder> Decodable<D> for DefIndex {
|
|||||||
// On below-64 bit systems we can simply use the derived `Hash` impl
|
// On below-64 bit systems we can simply use the derived `Hash` impl
|
||||||
#[cfg_attr(not(target_pointer_width = "64"), derive(Hash))]
|
#[cfg_attr(not(target_pointer_width = "64"), derive(Hash))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[rustc_pass_by_value]
|
||||||
// We guarantee field order. Note that the order is essential here, see below why.
|
// We guarantee field order. Note that the order is essential here, see below why.
|
||||||
pub struct DefId {
|
pub struct DefId {
|
||||||
// cfg-ing the order of fields so that the `DefIndex` which is high entropy always ends up in
|
// cfg-ing the order of fields so that the `DefIndex` which is high entropy always ends up in
|
||||||
|
@ -785,7 +785,7 @@ fn perform_2229_migration_anaysis(
|
|||||||
// Add a label pointing to where a captured variable affected by drop order
|
// Add a label pointing to where a captured variable affected by drop order
|
||||||
// is dropped
|
// is dropped
|
||||||
if lint_note.reason.drop_order {
|
if lint_note.reason.drop_order {
|
||||||
let drop_location_span = drop_location_span(self.tcx, &closure_hir_id);
|
let drop_location_span = drop_location_span(self.tcx, closure_hir_id);
|
||||||
|
|
||||||
match &lint_note.captures_info {
|
match &lint_note.captures_info {
|
||||||
UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
|
UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
|
||||||
@ -1697,8 +1697,8 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Span of where the value with the provided HirId would be dropped
|
/// Returns the Span of where the value with the provided HirId would be dropped
|
||||||
fn drop_location_span<'tcx>(tcx: TyCtxt<'tcx>, hir_id: &hir::HirId) -> Span {
|
fn drop_location_span<'tcx>(tcx: TyCtxt<'tcx>, hir_id: hir::HirId) -> Span {
|
||||||
let owner_id = tcx.hir().get_enclosing_scope(*hir_id).unwrap();
|
let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap();
|
||||||
|
|
||||||
let owner_node = tcx.hir().get(owner_id);
|
let owner_node = tcx.hir().get(owner_id);
|
||||||
let owner_span = match owner_node {
|
let owner_span = match owner_node {
|
||||||
|
@ -702,10 +702,10 @@ fn walk_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) {
|
|||||||
fn walk_captures(&mut self, closure_expr: &hir::Expr<'_>) {
|
fn walk_captures(&mut self, closure_expr: &hir::Expr<'_>) {
|
||||||
fn upvar_is_local_variable<'tcx>(
|
fn upvar_is_local_variable<'tcx>(
|
||||||
upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
|
upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
|
||||||
upvar_id: &hir::HirId,
|
upvar_id: hir::HirId,
|
||||||
body_owner_is_closure: bool,
|
body_owner_is_closure: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
upvars.map(|upvars| !upvars.contains_key(upvar_id)).unwrap_or(body_owner_is_closure)
|
upvars.map(|upvars| !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("walk_captures({:?})", closure_expr);
|
debug!("walk_captures({:?})", closure_expr);
|
||||||
@ -727,7 +727,7 @@ fn upvar_is_local_variable<'tcx>(
|
|||||||
PlaceBase::Upvar(upvar_id) => {
|
PlaceBase::Upvar(upvar_id) => {
|
||||||
if upvar_is_local_variable(
|
if upvar_is_local_variable(
|
||||||
upvars,
|
upvars,
|
||||||
&upvar_id.var_path.hir_id,
|
upvar_id.var_path.hir_id,
|
||||||
body_owner_is_closure,
|
body_owner_is_closure,
|
||||||
) {
|
) {
|
||||||
// The nested closure might be fake reading the current (enclosing) closure's local variables.
|
// The nested closure might be fake reading the current (enclosing) closure's local variables.
|
||||||
|
@ -543,10 +543,10 @@ fn into_map(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let borrowers = self.possible_borrower.reachable_from(&row);
|
let borrowers = self.possible_borrower.reachable_from(row);
|
||||||
if !borrowers.is_empty() {
|
if !borrowers.is_empty() {
|
||||||
let mut bs = HybridBitSet::new_empty(self.body.local_decls.len());
|
let mut bs = HybridBitSet::new_empty(self.body.local_decls.len());
|
||||||
for &c in borrowers {
|
for c in borrowers {
|
||||||
if c != mir::Local::from_usize(0) {
|
if c != mir::Local::from_usize(0) {
|
||||||
bs.insert(c);
|
bs.insert(c);
|
||||||
}
|
}
|
||||||
@ -663,10 +663,10 @@ fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap<mir::Local, HybridBitSet<
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let borrowers = self.possible_origin.reachable_from(&row);
|
let borrowers = self.possible_origin.reachable_from(row);
|
||||||
if !borrowers.is_empty() {
|
if !borrowers.is_empty() {
|
||||||
let mut bs = HybridBitSet::new_empty(self.body.local_decls.len());
|
let mut bs = HybridBitSet::new_empty(self.body.local_decls.len());
|
||||||
for &c in borrowers {
|
for c in borrowers {
|
||||||
if c != mir::Local::from_usize(0) {
|
if c != mir::Local::from_usize(0) {
|
||||||
bs.insert(c);
|
bs.insert(c);
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,8 @@ fn find_primitive(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
|||||||
fn find_crate(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
fn find_crate(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
||||||
tcx.crates(())
|
tcx.crates(())
|
||||||
.iter()
|
.iter()
|
||||||
.find(|&&num| tcx.crate_name(num).as_str() == name)
|
.copied()
|
||||||
|
.find(|&num| tcx.crate_name(num).as_str() == name)
|
||||||
.map(CrateNum::as_def_id)
|
.map(CrateNum::as_def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user