add #[rustc_pass_by_value] to more types

This commit is contained in:
lcnr 2022-03-08 15:39:52 +01:00
parent 67b3e81838
commit b8135fd5c8
27 changed files with 165 additions and 152 deletions

View File

@ -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()

View File

@ -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
} }

View File

@ -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));
} }
} }
} }

View File

@ -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),

View File

@ -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()
} }
} }

View File

@ -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)
}, },

View File

@ -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 {

View File

@ -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]))
} }
} }

View File

@ -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));
} }

View File

@ -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,

View File

@ -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]

View File

@ -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 })
} }
} }

View File

@ -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,
} }

View File

@ -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)]

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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) {
} }

View File

@ -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))
} }
} }

View File

@ -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,

View File

@ -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>);

View File

@ -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(

View File

@ -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

View File

@ -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 {

View File

@ -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.

View File

@ -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);
} }

View File

@ -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)
} }