Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
}

fn apply_early_statement_effect(
&mut self,
&self,
state: &mut Self::Domain,
stmt: &mir::Statement<'tcx>,
loc: Location,
Expand All @@ -55,7 +55,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
}

fn apply_primary_statement_effect(
&mut self,
&self,
state: &mut Self::Domain,
stmt: &mir::Statement<'tcx>,
loc: Location,
Expand All @@ -66,7 +66,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
}

fn apply_early_terminator_effect(
&mut self,
&self,
state: &mut Self::Domain,
term: &mir::Terminator<'tcx>,
loc: Location,
Expand All @@ -77,7 +77,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
}

fn apply_primary_terminator_effect<'mir>(
&mut self,
&self,
state: &mut Self::Domain,
term: &'mir mir::Terminator<'tcx>,
loc: Location,
Expand All @@ -92,7 +92,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
}

fn apply_call_return_effect(
&mut self,
&self,
_state: &mut Self::Domain,
_block: BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
Expand Down Expand Up @@ -533,7 +533,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
}

fn apply_early_statement_effect(
&mut self,
&self,
state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
location: Location,
Expand All @@ -542,7 +542,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
}

fn apply_primary_statement_effect(
&mut self,
&self,
state: &mut Self::Domain,
stmt: &mir::Statement<'tcx>,
location: Location,
Expand Down Expand Up @@ -590,7 +590,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
}

fn apply_early_terminator_effect(
&mut self,
&self,
state: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
location: Location,
Expand All @@ -599,7 +599,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
}

fn apply_primary_terminator_effect<'mir>(
&mut self,
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
_location: Location,
Expand Down
26 changes: 12 additions & 14 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use rustc_mir_dataflow::move_paths::{
InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
};
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results};
use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
use rustc_span::{ErrorGuaranteed, Span, Symbol};
use smallvec::SmallVec;
Expand Down Expand Up @@ -537,13 +537,11 @@ fn borrowck_check_region_constraints<'tcx>(
mbcx.report_region_errors(nll_errors);
}

let (mut flow_analysis, flow_entry_states) =
get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
let flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
visit_results(
body,
traversal::reverse_postorder(body).map(|(bb, _)| bb),
&mut flow_analysis,
&flow_entry_states,
&flow_results,
&mut mbcx,
);

Expand Down Expand Up @@ -604,7 +602,7 @@ fn get_flow_results<'a, 'tcx>(
move_data: &'a MoveData<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
) -> (Borrowck<'a, 'tcx>, Results<BorrowckDomain>) {
) -> Results<'tcx, Borrowck<'a, 'tcx>> {
// We compute these three analyses individually, but them combine them into
// a single results so that `mbcx` can visit them all together.
let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
Expand All @@ -629,14 +627,14 @@ fn get_flow_results<'a, 'tcx>(
ever_inits: ever_inits.analysis,
};

assert_eq!(borrows.results.len(), uninits.results.len());
assert_eq!(borrows.results.len(), ever_inits.results.len());
let results: Results<_> =
itertools::izip!(borrows.results, uninits.results, ever_inits.results)
assert_eq!(borrows.entry_states.len(), uninits.entry_states.len());
assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len());
let entry_states: EntryStates<_> =
itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
.map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
.collect();

(analysis, results)
Results { analysis, entry_states }
}

pub(crate) struct BorrowckInferCtxt<'tcx> {
Expand Down Expand Up @@ -790,7 +788,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
fn visit_after_early_statement_effect(
&mut self,
_analysis: &mut Borrowck<'a, 'tcx>,
_analysis: &Borrowck<'a, 'tcx>,
state: &BorrowckDomain,
stmt: &Statement<'tcx>,
location: Location,
Expand Down Expand Up @@ -865,7 +863,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,

fn visit_after_early_terminator_effect(
&mut self,
_analysis: &mut Borrowck<'a, 'tcx>,
_analysis: &Borrowck<'a, 'tcx>,
state: &BorrowckDomain,
term: &Terminator<'tcx>,
loc: Location,
Expand Down Expand Up @@ -985,7 +983,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,

fn visit_after_primary_terminator_effect(
&mut self,
_analysis: &mut Borrowck<'a, 'tcx>,
_analysis: &Borrowck<'a, 'tcx>,
state: &BorrowckDomain,
term: &Terminator<'tcx>,
loc: Location,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/check_consts/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ where
}

fn apply_primary_statement_effect(
&mut self,
&self,
state: &mut Self::Domain,
statement: &mir::Statement<'tcx>,
location: Location,
Expand All @@ -341,7 +341,7 @@ where
}

fn apply_primary_terminator_effect<'mir>(
&mut self,
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
Expand All @@ -351,7 +351,7 @@ where
}

fn apply_call_return_effect(
&mut self,
&self,
state: &mut Self::Domain,
block: BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use rustc_ast::util::parser::ExprPrecedence;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
use rustc_hir::def_id::DefId;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, ExprKind};
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_macros::{TypeFoldable, TypeVisitable};
Expand Down Expand Up @@ -63,6 +63,7 @@ pub(crate) struct CastCheck<'tcx> {
cast_ty: Ty<'tcx>,
cast_span: Span,
span: Span,
pub body_id: LocalDefId,
}

/// The kind of pointer and associated metadata (thin, length or vtable) - we
Expand Down Expand Up @@ -244,7 +245,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
span: Span,
) -> Result<CastCheck<'tcx>, ErrorGuaranteed> {
let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span);
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span };
let check =
CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, body_id: fcx.body_id };

// For better error messages, check for some obviously unsized
// cases now. We do a more thorough check at the end, once
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::ops::Deref;
use std::{fmt, iter, mem};
use std::{fmt, iter};

use itertools::Itertools;
use rustc_data_structures::fx::FxIndexSet;
Expand Down Expand Up @@ -72,16 +72,13 @@ pub(crate) enum DivergingBlockBehavior {

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn check_casts(&mut self) {
// don't hold the borrow to deferred_cast_checks while checking to avoid borrow checker errors
// when writing to `self.param_env`.
let mut deferred_cast_checks = mem::take(&mut *self.deferred_cast_checks.borrow_mut());

let mut deferred_cast_checks = self.root_ctxt.deferred_cast_checks.borrow_mut();
debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
for cast in deferred_cast_checks.drain(..) {
let body_id = std::mem::replace(&mut self.body_id, cast.body_id);
cast.check(self);
self.body_id = body_id;
}

*self.deferred_cast_checks.borrow_mut() = deferred_cast_checks;
}

pub(in super::super) fn check_asms(&self) {
Expand Down
65 changes: 20 additions & 45 deletions compiler/rustc_mir_dataflow/src/framework/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
//! Random access inspection of the results of a dataflow analysis.

use std::borrow::Cow;
use std::cmp::Ordering;
use std::ops::{Deref, DerefMut};
use std::ops::Deref;

#[cfg(debug_assertions)]
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::mir::{self, BasicBlock, Location};

use super::{Analysis, Direction, Effect, EffectIndex, Results};

/// Some `ResultsCursor`s want to own an `Analysis`, and some want to borrow an `Analysis`, either
/// mutable or immutably. This type allows all of the above. It's similar to `Cow`, but `Cow`
/// doesn't allow mutable borrowing.
enum CowMut<'a, T> {
BorrowedMut(&'a mut T),
/// This is like `Cow`, but it lacks the `T: ToOwned` bound and doesn't support
/// `to_owned`/`into_owned`.
enum SimpleCow<'a, T> {
Borrowed(&'a T),
Owned(T),
}

impl<T> Deref for CowMut<'_, T> {
impl<T> Deref for SimpleCow<'_, T> {
type Target = T;

fn deref(&self) -> &T {
match self {
CowMut::BorrowedMut(borrowed) => borrowed,
CowMut::Owned(owned) => owned,
}
}
}

impl<T> DerefMut for CowMut<'_, T> {
fn deref_mut(&mut self) -> &mut T {
match self {
CowMut::BorrowedMut(borrowed) => borrowed,
CowMut::Owned(owned) => owned,
SimpleCow::Borrowed(borrowed) => borrowed,
SimpleCow::Owned(owned) => owned,
}
}
}
Expand All @@ -53,8 +42,7 @@ where
A: Analysis<'tcx>,
{
body: &'mir mir::Body<'tcx>,
analysis: CowMut<'mir, A>,
results: Cow<'mir, Results<A::Domain>>,
results: SimpleCow<'mir, Results<'tcx, A>>,
state: A::Domain,

pos: CursorPosition,
Expand Down Expand Up @@ -82,15 +70,10 @@ where
self.body
}

fn new(
body: &'mir mir::Body<'tcx>,
analysis: CowMut<'mir, A>,
results: Cow<'mir, Results<A::Domain>>,
) -> Self {
let bottom_value = analysis.bottom_value(body);
fn new(body: &'mir mir::Body<'tcx>, results: SimpleCow<'mir, Results<'tcx, A>>) -> Self {
let bottom_value = results.analysis.bottom_value(body);
ResultsCursor {
body,
analysis,
results,

// Initialize to the `bottom_value` and set `state_needs_reset` to tell the cursor that
Expand All @@ -106,21 +89,13 @@ where
}

/// Returns a new cursor that takes ownership of and inspects analysis results.
pub fn new_owning(
body: &'mir mir::Body<'tcx>,
analysis: A,
results: Results<A::Domain>,
) -> Self {
Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))
pub fn new_owning(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
Self::new(body, SimpleCow::Owned(results))
}

/// Returns a new cursor that borrows and inspects analysis results.
pub fn new_borrowing(
body: &'mir mir::Body<'tcx>,
analysis: &'mir mut A,
results: &'mir Results<A::Domain>,
) -> Self {
Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))
pub fn new_borrowing(body: &'mir mir::Body<'tcx>, results: &'mir Results<'tcx, A>) -> Self {
Self::new(body, SimpleCow::Borrowed(results))
}

/// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled.
Expand All @@ -132,7 +107,7 @@ where

/// Returns the `Analysis` used to generate the underlying `Results`.
pub fn analysis(&self) -> &A {
&self.analysis
&self.results.analysis
}

/// Resets the cursor to hold the entry set for the given basic block.
Expand All @@ -144,7 +119,7 @@ where
#[cfg(debug_assertions)]
assert!(self.reachable_blocks.contains(block));

self.state.clone_from(&self.results[block]);
self.state.clone_from(&self.results.entry_states[block]);
self.pos = CursorPosition::block_entry(block);
self.state_needs_reset = false;
}
Expand Down Expand Up @@ -236,7 +211,7 @@ where
let target_effect_index = effect.at_index(target.statement_index);

A::Direction::apply_effects_in_range(
&mut *self.analysis,
&self.results.analysis,
&mut self.state,
target.block,
block_data,
Expand All @@ -251,8 +226,8 @@ where
///
/// This can be used, e.g., to apply the call return effect directly to the cursor without
/// creating an extra copy of the dataflow state.
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
f(&mut self.analysis, &mut self.state);
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {
f(&self.results.analysis, &mut self.state);
self.state_needs_reset = true;
}
}
Expand Down
Loading
Loading