1
Fork 0

Auto merge of #130165 - matthiaskrgr:rollup-fsnmz3t, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #129929 (`rustc_mir_transform` cleanups, round 2)
 - #130022 (Dataflow/borrowck lifetime cleanups)
 - #130064 (fix ICE in CMSE type validation)
 - #130067 (Remove redundant check in `symlink_hard_link` test)
 - #130131 (Print a helpful message if any tests were skipped for being up-to-date)
 - #130137 (Fix ICE caused by missing span in a region error)
 - #130153 (use verbose flag as a default value for `rust.verbose-tests`)
 - #130154 (Stabilize `char::MIN`)
 - #130158 (Update books)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-09-09 18:53:06 +00:00
commit c2f74c3f92
105 changed files with 662 additions and 598 deletions

View file

@ -8,7 +8,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> { pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> {
self.infcx.dcx() self.infcx.dcx()
} }

View file

@ -15,24 +15,24 @@ use tracing::debug;
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext}; use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
/// The results of the dataflow analyses used by the borrow checker. /// The results of the dataflow analyses used by the borrow checker.
pub(crate) struct BorrowckResults<'a, 'mir, 'tcx> { pub(crate) struct BorrowckResults<'a, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>, pub(crate) borrows: Results<'tcx, Borrows<'a, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>, pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'tcx>>,
} }
/// The transient state of the dataflow analyses used by the borrow checker. /// The transient state of the dataflow analyses used by the borrow checker.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct BorrowckFlowState<'a, 'mir, 'tcx> { pub(crate) struct BorrowckFlowState<'a, 'tcx> {
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain, pub(crate) borrows: <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain, pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain, pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
} }
impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> { impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
// All three analyses are forward, but we have to use just one here. // All three analyses are forward, but we have to use just one here.
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction; type Direction = <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>; type FlowState = BorrowckFlowState<'a, 'tcx>;
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState { fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
BorrowckFlowState { BorrowckFlowState {
@ -106,10 +106,9 @@ rustc_index::newtype_index! {
/// `BorrowIndex`, and maps each such index to a `BorrowData` /// `BorrowIndex`, and maps each such index to a `BorrowData`
/// describing the borrow. These indexes are used for representing the /// describing the borrow. These indexes are used for representing the
/// borrows in compact bitvectors. /// borrows in compact bitvectors.
pub struct Borrows<'a, 'mir, 'tcx> { pub struct Borrows<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>, borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
} }
@ -389,10 +388,10 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
} }
} }
impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> { impl<'a, 'tcx> Borrows<'a, 'tcx> {
pub fn new( pub fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>, regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
) -> Self { ) -> Self {
@ -494,7 +493,7 @@ impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> {
} }
} }
impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> { impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
type Domain = BitSet<BorrowIndex>; type Domain = BitSet<BorrowIndex>;
const NAME: &'static str = "borrows"; const NAME: &'static str = "borrows";
@ -517,7 +516,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> {
/// region stops containing the CFG points reachable from the issuing location. /// region stops containing the CFG points reachable from the issuing location.
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
/// `a.b.c` when `a` is overwritten. /// `a.b.c` when `a` is overwritten.
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> { impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
type Idx = BorrowIndex; type Idx = BorrowIndex;
fn domain_size(&self, _: &mir::Body<'tcx>) -> usize { fn domain_size(&self, _: &mir::Body<'tcx>) -> usize {
@ -617,8 +616,8 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> {
} }
} }
impl DebugWithContext<Borrows<'_, '_, '_>> for BorrowIndex { impl DebugWithContext<Borrows<'_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", ctxt.location(*self)) write!(f, "{:?}", ctxt.location(*self))
} }
} }

View file

@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> {
pub(crate) fn report_error( pub(crate) fn report_error(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
placeholder: ty::PlaceholderRegion, placeholder: ty::PlaceholderRegion,
error_element: RegionElement, error_element: RegionElement,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> {
fn nice_error<'infcx>( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> {
#[instrument(level = "debug", skip(self, mbcx))] #[instrument(level = "debug", skip(self, mbcx))]
fn report_error( fn report_error(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
placeholder: ty::PlaceholderRegion, placeholder: ty::PlaceholderRegion,
error_element: RegionElement, error_element: RegionElement,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
fn nice_error<'infcx>( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
@ -277,7 +277,7 @@ where
fn nice_error<'infcx>( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
@ -324,7 +324,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
fn nice_error<'infcx>( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
@ -357,7 +357,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
fn nice_error<'infcx>( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
_cause: ObligationCause<'tcx>, _cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,

View file

@ -69,7 +69,7 @@ enum StorageDeadOrDrop<'tcx> {
Destructor(Ty<'tcx>), Destructor(Ty<'tcx>),
} }
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn report_use_of_moved_or_uninitialized( pub(crate) fn report_use_of_moved_or_uninitialized(
&mut self, &mut self,
location: Location, location: Location,
@ -4358,11 +4358,7 @@ enum AnnotatedBorrowFnSignature<'tcx> {
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
/// Annotate the provided diagnostic with information about borrow from the fn signature that /// Annotate the provided diagnostic with information about borrow from the fn signature that
/// helps explain. /// helps explain.
pub(crate) fn emit( pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, '_, 'tcx>, diag: &mut Diag<'_>) -> String {
&self,
cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>,
diag: &mut Diag<'_>,
) -> String {
match self { match self {
&AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
diag.span_label( diag.span_label(

View file

@ -390,7 +390,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
} }
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
fn free_region_constraint_info( fn free_region_constraint_info(
&self, &self,
borrow_region: RegionVid, borrow_region: RegionVid,

View file

@ -68,7 +68,7 @@ pub(super) struct DescribePlaceOpt {
pub(super) struct IncludingTupleField(pub(super) bool); pub(super) struct IncludingTupleField(pub(super) bool);
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
/// is moved after being invoked. /// is moved after being invoked.
/// ///
@ -772,7 +772,7 @@ struct CapturedMessageOpt {
maybe_reinitialized_locations_is_empty: bool, maybe_reinitialized_locations_is_empty: bool,
} }
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
/// Finds the spans associated to a move or copy of move_place at location. /// Finds the spans associated to a move or copy of move_place at location.
pub(super) fn move_spans( pub(super) fn move_spans(
&self, &self,

View file

@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> {
}, },
} }
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn report_move_errors(&mut self) { pub(crate) fn report_move_errors(&mut self) {
let grouped_errors = self.group_move_errors(); let grouped_errors = self.group_move_errors();
for error in grouped_errors { for error in grouped_errors {

View file

@ -32,7 +32,7 @@ pub(crate) enum AccessKind {
Mutate, Mutate,
} }
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn report_mutability_error( pub(crate) fn report_mutability_error(
&mut self, &mut self,
access_place: Place<'tcx>, access_place: Place<'tcx>,

View file

@ -76,7 +76,7 @@ impl OutlivesSuggestionBuilder {
/// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`. /// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`.
fn region_vid_to_name( fn region_vid_to_name(
&self, &self,
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, mbcx: &MirBorrowckCtxt<'_, '_, '_>,
region: RegionVid, region: RegionVid,
) -> Option<RegionName> { ) -> Option<RegionName> {
mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable) mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable)
@ -85,7 +85,7 @@ impl OutlivesSuggestionBuilder {
/// Compiles a list of all suggestions to be printed in the final big suggestion. /// Compiles a list of all suggestions to be printed in the final big suggestion.
fn compile_all_suggestions( fn compile_all_suggestions(
&self, &self,
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, mbcx: &MirBorrowckCtxt<'_, '_, '_>,
) -> SmallVec<[SuggestedConstraint; 2]> { ) -> SmallVec<[SuggestedConstraint; 2]> {
let mut suggested = SmallVec::new(); let mut suggested = SmallVec::new();
@ -161,7 +161,7 @@ impl OutlivesSuggestionBuilder {
/// Emit an intermediate note on the given `Diag` if the involved regions are suggestable. /// Emit an intermediate note on the given `Diag` if the involved regions are suggestable.
pub(crate) fn intermediate_suggestion( pub(crate) fn intermediate_suggestion(
&mut self, &mut self,
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, mbcx: &MirBorrowckCtxt<'_, '_, '_>,
errci: &ErrorConstraintInfo<'_>, errci: &ErrorConstraintInfo<'_>,
diag: &mut Diag<'_>, diag: &mut Diag<'_>,
) { ) {
@ -180,7 +180,7 @@ impl OutlivesSuggestionBuilder {
/// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
/// suggestion including all collected constraints. /// suggestion including all collected constraints.
pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_, '_>) { pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_>) {
// No constraints to add? Done. // No constraints to add? Done.
if self.constraints_to_add.is_empty() { if self.constraints_to_add.is_empty() {
debug!("No constraints to suggest."); debug!("No constraints to suggest.");

View file

@ -156,7 +156,7 @@ pub(crate) struct ErrorConstraintInfo<'tcx> {
pub(super) span: Span, pub(super) span: Span,
} }
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
/// Converts a region inference variable into a `ty::Region` that /// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound, /// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is /// then we use the name that we have on record for it. If `r` is

View file

@ -200,7 +200,7 @@ impl rustc_errors::IntoDiagArg for RegionName {
} }
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId { pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId {
self.body.source.def_id().expect_local() self.body.source.def_id().expect_local()
} }

View file

@ -304,11 +304,11 @@ fn do_mir_borrowck<'tcx>(
promoted_mbcx.report_move_errors(); promoted_mbcx.report_move_errors();
diags = promoted_mbcx.diags; diags = promoted_mbcx.diags;
struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> { struct MoveVisitor<'a, 'b, 'infcx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>, ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
} }
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> { impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> {
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
if let Operand::Move(place) = operand { if let Operand::Move(place) = operand {
self.ctxt.check_movable_place(location, *place); self.ctxt.check_movable_place(location, *place);
@ -522,10 +522,10 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
} }
} }
struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> { struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
infcx: &'infcx BorrowckInferCtxt<'tcx>, infcx: &'infcx BorrowckInferCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
/// Map from MIR `Location` to `LocationIndex`; created /// Map from MIR `Location` to `LocationIndex`; created
@ -599,16 +599,16 @@ struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> {
// 2. loans made in overlapping scopes do not conflict // 2. loans made in overlapping scopes do not conflict
// 3. assignments do not affect things loaned out as immutable // 3. assignments do not affect things loaned out as immutable
// 4. moves do not affect things loaned out in any way // 4. moves do not affect things loaned out in any way
impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
for MirBorrowckCtxt<'a, 'mir, '_, 'tcx> for MirBorrowckCtxt<'a, '_, 'tcx>
{ {
type FlowState = Flows<'a, 'mir, 'tcx>; type FlowState = Flows<'a, 'tcx>;
fn visit_statement_before_primary_effect( fn visit_statement_before_primary_effect(
&mut self, &mut self,
_results: &mut R, _results: &mut R,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
stmt: &'mir Statement<'tcx>, stmt: &'a Statement<'tcx>,
location: Location, location: Location,
) { ) {
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state); debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state);
@ -677,8 +677,8 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_before_primary_effect( fn visit_terminator_before_primary_effect(
&mut self, &mut self,
_results: &mut R, _results: &mut R,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
term: &'mir Terminator<'tcx>, term: &'a Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state); debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state);
@ -794,8 +794,8 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_after_primary_effect( fn visit_terminator_after_primary_effect(
&mut self, &mut self,
_results: &mut R, _results: &mut R,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
term: &'mir Terminator<'tcx>, term: &'a Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
let span = term.source_info.span; let span = term.source_info.span;
@ -972,8 +972,8 @@ impl InitializationRequiringAction {
} }
} }
impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
fn body(&self) -> &'mir Body<'tcx> { fn body(&self) -> &'a Body<'tcx> {
self.body self.body
} }
@ -989,7 +989,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite), kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
let (sd, rw) = kind; let (sd, rw) = kind;
@ -1039,7 +1039,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
sd: AccessDepth, sd: AccessDepth,
rw: ReadOrWrite, rw: ReadOrWrite,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) -> bool { ) -> bool {
let mut error_reported = false; let mut error_reported = false;
let borrow_set = Rc::clone(&self.borrow_set); let borrow_set = Rc::clone(&self.borrow_set);
@ -1180,7 +1180,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
kind: AccessDepth, kind: AccessDepth,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
// Write of P[i] or *P requires P init'd. // Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state); self.check_if_assigned_path_is_moved(location, place_span, flow_state);
@ -1197,8 +1197,8 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn consume_rvalue( fn consume_rvalue(
&mut self, &mut self,
location: Location, location: Location,
(rvalue, span): (&'mir Rvalue<'tcx>, Span), (rvalue, span): (&'a Rvalue<'tcx>, Span),
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
match rvalue { match rvalue {
&Rvalue::Ref(_ /*rgn*/, bk, place) => { &Rvalue::Ref(_ /*rgn*/, bk, place) => {
@ -1455,8 +1455,8 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn consume_operand( fn consume_operand(
&mut self, &mut self,
location: Location, location: Location,
(operand, span): (&'mir Operand<'tcx>, Span), (operand, span): (&'a Operand<'tcx>, Span),
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
match *operand { match *operand {
Operand::Copy(place) => { Operand::Copy(place) => {
@ -1576,12 +1576,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
} }
} }
fn check_activations( fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'a, 'tcx>) {
&mut self,
location: Location,
span: Span,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// Two-phase borrow support: For each activation that is newly // Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with // generated at this statement, check if it interferes with
// another borrow. // another borrow.
@ -1744,7 +1739,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span), place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
let maybe_uninits = &flow_state.uninits; let maybe_uninits = &flow_state.uninits;
@ -1849,7 +1844,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span), place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
let maybe_uninits = &flow_state.uninits; let maybe_uninits = &flow_state.uninits;
@ -1948,7 +1943,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
debug!("check_if_assigned_path_is_moved place: {:?}", place); debug!("check_if_assigned_path_is_moved place: {:?}", place);
@ -2009,12 +2004,12 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
} }
} }
fn check_parent_of_field<'mir, 'tcx>( fn check_parent_of_field<'a, 'tcx>(
this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>, this: &mut MirBorrowckCtxt<'a, '_, 'tcx>,
location: Location, location: Location,
base: PlaceRef<'tcx>, base: PlaceRef<'tcx>,
span: Span, span: Span,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) { ) {
// rust-lang/rust#21232: Until Rust allows reads from the // rust-lang/rust#21232: Until Rust allows reads from the
// initialized parts of partially initialized structs, we // initialized parts of partially initialized structs, we
@ -2105,7 +2100,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
kind: ReadOrWrite, kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
location: Location, location: Location,
) -> bool { ) -> bool {
debug!( debug!(
@ -2221,7 +2216,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn is_local_ever_initialized( fn is_local_ever_initialized(
&self, &self,
local: Local, local: Local,
flow_state: &Flows<'_, 'mir, 'tcx>, flow_state: &Flows<'a, 'tcx>,
) -> Option<InitIndex> { ) -> Option<InitIndex> {
let mpi = self.move_data.rev_lookup.find_local(local)?; let mpi = self.move_data.rev_lookup.find_local(local)?;
let ii = &self.move_data.init_path_map[mpi]; let ii = &self.move_data.init_path_map[mpi];
@ -2229,7 +2224,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
} }
/// Adds the place into the used mutable variables set /// Adds the place into the used mutable variables set
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>) { fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'a, 'tcx>) {
match root_place { match root_place {
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
// If the local may have been initialized, and it is now currently being // If the local may have been initialized, and it is now currently being
@ -2484,7 +2479,7 @@ mod diags {
} }
} }
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
self.diags.buffer_error(diag); self.diags.buffer_error(diag);
} }

View file

@ -75,14 +75,14 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
/// Computes the (non-lexical) regions from the input MIR. /// Computes the (non-lexical) regions from the input MIR.
/// ///
/// This may result in errors being reported. /// This may result in errors being reported.
pub(crate) fn compute_regions<'cx, 'tcx>( pub(crate) fn compute_regions<'a, 'tcx>(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>,
universal_regions: UniversalRegions<'tcx>, universal_regions: UniversalRegions<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
promoted: &IndexSlice<Promoted, Body<'tcx>>, promoted: &IndexSlice<Promoted, Body<'tcx>>,
location_table: &LocationTable, location_table: &LocationTable,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'_, 'cx, 'tcx>>, flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
upvars: &[&ty::CapturedPlace<'tcx>], upvars: &[&ty::CapturedPlace<'tcx>],
@ -301,13 +301,13 @@ pub(super) fn dump_nll_mir<'tcx>(
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
pub(super) fn dump_annotation<'tcx, 'cx>( pub(super) fn dump_annotation<'tcx, 'infcx>(
infcx: &'cx BorrowckInferCtxt<'tcx>, infcx: &'infcx BorrowckInferCtxt<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>, regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>, closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>, opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
diags: &mut crate::diags::BorrowckDiags<'cx, 'tcx>, diags: &mut crate::diags::BorrowckDiags<'infcx, 'tcx>,
) { ) {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); let base_def_id = tcx.typeck_root_def_id(body.source.def_id());

View file

@ -34,7 +34,7 @@ pub(super) enum PrefixSet {
Shallow, Shallow,
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
/// Returns an iterator over the prefixes of `place` /// Returns an iterator over the prefixes of `place`
/// (inclusive) from longest to smallest, potentially /// (inclusive) from longest to smallest, potentially
/// terminating the iteration early based on `kind`. /// terminating the iteration early based on `kind`.

View file

@ -30,11 +30,11 @@ mod trace;
/// ///
/// N.B., this computation requires normalization; therefore, it must be /// N.B., this computation requires normalization; therefore, it must be
/// performed before /// performed before
pub(super) fn generate<'mir, 'tcx>( pub(super) fn generate<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>, elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
) { ) {
debug!("liveness::generate"); debug!("liveness::generate");

View file

@ -37,11 +37,11 @@ use crate::type_check::{NormalizeLocation, TypeChecker};
/// DROP-LIVE set are to the liveness sets for regions found in the /// DROP-LIVE set are to the liveness sets for regions found in the
/// `dropck_outlives` result of the variable's type (in particular, /// `dropck_outlives` result of the variable's type (in particular,
/// this respects `#[may_dangle]` annotations). /// this respects `#[may_dangle]` annotations).
pub(super) fn trace<'mir, 'tcx>( pub(super) fn trace<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>, elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
relevant_live_locals: Vec<Local>, relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>, boring_locals: Vec<Local>,
@ -99,29 +99,29 @@ pub(super) fn trace<'mir, 'tcx>(
} }
/// Contextual state for the type-liveness coroutine. /// Contextual state for the type-liveness coroutine.
struct LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx> { struct LivenessContext<'a, 'typeck, 'b, 'tcx> {
/// Current type-checker, giving us our inference context etc. /// Current type-checker, giving us our inference context etc.
typeck: &'me mut TypeChecker<'typeck, 'tcx>, typeck: &'a mut TypeChecker<'typeck, 'tcx>,
/// Defines the `PointIndex` mapping /// Defines the `PointIndex` mapping
elements: &'me DenseLocationMap, elements: &'a DenseLocationMap,
/// MIR we are analyzing. /// MIR we are analyzing.
body: &'me Body<'tcx>, body: &'a Body<'tcx>,
/// Mapping to/from the various indices used for initialization tracking. /// Mapping to/from the various indices used for initialization tracking.
move_data: &'me MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
/// Cache for the results of `dropck_outlives` query. /// Cache for the results of `dropck_outlives` query.
drop_data: FxIndexMap<Ty<'tcx>, DropData<'tcx>>, drop_data: FxIndexMap<Ty<'tcx>, DropData<'tcx>>,
/// Results of dataflow tracking which variables (and paths) have been /// Results of dataflow tracking which variables (and paths) have been
/// initialized. /// initialized.
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'a, 'flow, 'tcx>>, flow_inits: &'a mut ResultsCursor<'b, 'tcx, MaybeInitializedPlaces<'b, 'tcx>>,
/// Index indicating where each variable is assigned, used, or /// Index indicating where each variable is assigned, used, or
/// dropped. /// dropped.
local_use_map: &'me LocalUseMap, local_use_map: &'a LocalUseMap,
} }
struct DropData<'tcx> { struct DropData<'tcx> {
@ -129,8 +129,8 @@ struct DropData<'tcx> {
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>, region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
} }
struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> { struct LivenessResults<'a, 'typeck, 'b, 'tcx> {
cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>, cx: LivenessContext<'a, 'typeck, 'b, 'tcx>,
/// Set of points that define the current local. /// Set of points that define the current local.
defs: BitSet<PointIndex>, defs: BitSet<PointIndex>,
@ -151,8 +151,8 @@ struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
stack: Vec<PointIndex>, stack: Vec<PointIndex>,
} }
impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> { impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self { fn new(cx: LivenessContext<'a, 'typeck, 'b, 'tcx>) -> Self {
let num_points = cx.elements.num_points(); let num_points = cx.elements.num_points();
LivenessResults { LivenessResults {
cx, cx,
@ -505,7 +505,7 @@ impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tc
} }
} }
impl<'tcx> LivenessContext<'_, '_, '_, '_, 'tcx> { impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
/// Returns `true` if the local variable (or some part of it) is initialized at the current /// Returns `true` if the local variable (or some part of it) is initialized at the current
/// cursor position. Callers should call one of the `seek` methods immediately before to point /// cursor position. Callers should call one of the `seek` methods immediately before to point
/// the cursor to the desired location. /// the cursor to the desired location.

View file

@ -116,7 +116,7 @@ mod relate_tys;
/// - `flow_inits` -- results of a maybe-init dataflow analysis /// - `flow_inits` -- results of a maybe-init dataflow analysis
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
/// - `elements` -- MIR region map /// - `elements` -- MIR region map
pub(crate) fn type_check<'mir, 'tcx>( pub(crate) fn type_check<'a, 'tcx>(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
@ -125,7 +125,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
location_table: &LocationTable, location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>, all_facts: &mut Option<AllFacts>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
elements: &Rc<DenseLocationMap>, elements: &Rc<DenseLocationMap>,
upvars: &[&ty::CapturedPlace<'tcx>], upvars: &[&ty::CapturedPlace<'tcx>],

View file

@ -423,8 +423,8 @@ impl<'tcx> UniversalRegions<'tcx> {
} }
} }
struct UniversalRegionsBuilder<'cx, 'tcx> { struct UniversalRegionsBuilder<'infcx, 'tcx> {
infcx: &'cx BorrowckInferCtxt<'tcx>, infcx: &'infcx BorrowckInferCtxt<'tcx>,
mir_def: LocalDefId, mir_def: LocalDefId,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
} }

View file

@ -7,7 +7,7 @@ use tracing::debug;
use crate::MirBorrowckCtxt; use crate::MirBorrowckCtxt;
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
/// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
/// of the `unused_mut` lint. /// of the `unused_mut` lint.
/// ///
@ -46,13 +46,13 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// MIR visitor for collecting used mutable variables. /// MIR visitor for collecting used mutable variables.
/// The 'visit lifetime represents the duration of the MIR walk. /// The 'visit lifetime represents the duration of the MIR walk.
struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'infcx, 'tcx> { struct GatherUsedMutsVisitor<'a, 'b, 'infcx, 'tcx> {
temporary_used_locals: FxIndexSet<Local>, temporary_used_locals: FxIndexSet<Local>,
never_initialized_mut_locals: &'visit mut FxIndexSet<Local>, never_initialized_mut_locals: &'a mut FxIndexSet<Local>,
mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx>, mbcx: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
} }
impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> { impl GatherUsedMutsVisitor<'_, '_, '_, '_> {
fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) { fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
// Remove any locals that we found were initialized from the // Remove any locals that we found were initialized from the
// `never_initialized_mut_locals` set. At the end, the only remaining locals will // `never_initialized_mut_locals` set. At the end, the only remaining locals will
@ -64,7 +64,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> {
} }
} }
impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, '_, 'tcx> { impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, 'tcx> {
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
debug!("visit_terminator: terminator={:?}", terminator); debug!("visit_terminator: terminator={:?}", terminator);
match &terminator.kind { match &terminator.kind {

View file

@ -72,8 +72,11 @@ fn is_valid_cmse_inputs<'tcx>(
let mut span = None; let mut span = None;
let mut accum = 0u64; let mut accum = 0u64;
for (index, arg_def) in fn_sig.inputs().iter().enumerate() { // this type is only used for layout computation, which does not rely on regions
let layout = tcx.layout_of(ParamEnv::reveal_all().and(*arg_def.skip_binder()))?; let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
for (index, ty) in fn_sig.inputs().iter().enumerate() {
let layout = tcx.layout_of(ParamEnv::reveal_all().and(*ty))?;
let align = layout.layout.align().abi.bytes(); let align = layout.layout.align().abi.bytes();
let size = layout.layout.size().bytes(); let size = layout.layout.size().bytes();
@ -98,7 +101,10 @@ fn is_valid_cmse_output<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
fn_sig: ty::PolyFnSig<'tcx>, fn_sig: ty::PolyFnSig<'tcx>,
) -> Result<bool, &'tcx LayoutError<'tcx>> { ) -> Result<bool, &'tcx LayoutError<'tcx>> {
let mut ret_ty = fn_sig.output().skip_binder(); // this type is only used for layout computation, which does not rely on regions
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
let mut ret_ty = fn_sig.output();
let layout = tcx.layout_of(ParamEnv::reveal_all().and(ret_ty))?; let layout = tcx.layout_of(ParamEnv::reveal_all().and(ret_ty))?;
let size = layout.layout.size().bytes(); let size = layout.layout.size().bytes();

View file

@ -51,15 +51,15 @@ use crate::{
/// Similarly, at a given `drop` statement, the set-intersection /// Similarly, at a given `drop` statement, the set-intersection
/// between this data and `MaybeUninitializedPlaces` yields the set of /// between this data and `MaybeUninitializedPlaces` yields the set of
/// places that would require a dynamic drop-flag at that statement. /// places that would require a dynamic drop-flag at that statement.
pub struct MaybeInitializedPlaces<'a, 'mir, 'tcx> { pub struct MaybeInitializedPlaces<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
skip_unreachable_unwind: bool, skip_unreachable_unwind: bool,
} }
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
MaybeInitializedPlaces { tcx, body, move_data, skip_unreachable_unwind: false } MaybeInitializedPlaces { tcx, body, move_data, skip_unreachable_unwind: false }
} }
@ -85,7 +85,7 @@ impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
} }
} }
impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
fn move_data(&self) -> &MoveData<'tcx> { fn move_data(&self) -> &MoveData<'tcx> {
self.move_data self.move_data
} }
@ -126,17 +126,17 @@ impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx
/// Similarly, at a given `drop` statement, the set-intersection /// Similarly, at a given `drop` statement, the set-intersection
/// between this data and `MaybeInitializedPlaces` yields the set of /// between this data and `MaybeInitializedPlaces` yields the set of
/// places that would require a dynamic drop-flag at that statement. /// places that would require a dynamic drop-flag at that statement.
pub struct MaybeUninitializedPlaces<'a, 'mir, 'tcx> { pub struct MaybeUninitializedPlaces<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
mark_inactive_variants_as_uninit: bool, mark_inactive_variants_as_uninit: bool,
skip_unreachable_unwind: BitSet<mir::BasicBlock>, skip_unreachable_unwind: BitSet<mir::BasicBlock>,
} }
impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
MaybeUninitializedPlaces { MaybeUninitializedPlaces {
tcx, tcx,
body, body,
@ -165,7 +165,7 @@ impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
} }
} }
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> { impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
fn move_data(&self) -> &MoveData<'tcx> { fn move_data(&self) -> &MoveData<'tcx> {
self.move_data self.move_data
} }
@ -251,24 +251,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
/// c = S; // {a, b, c, d } /// c = S; // {a, b, c, d }
/// } /// }
/// ``` /// ```
pub struct EverInitializedPlaces<'a, 'mir, 'tcx> { pub struct EverInitializedPlaces<'a, 'tcx> {
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
} }
impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
pub fn new(body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self { pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
EverInitializedPlaces { body, move_data } EverInitializedPlaces { body, move_data }
} }
} }
impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> { impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> {
fn move_data(&self) -> &MoveData<'tcx> { fn move_data(&self) -> &MoveData<'tcx> {
self.move_data self.move_data
} }
} }
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
fn update_bits( fn update_bits(
trans: &mut impl GenKill<MovePathIndex>, trans: &mut impl GenKill<MovePathIndex>,
path: MovePathIndex, path: MovePathIndex,
@ -281,7 +281,7 @@ impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
} }
} }
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> { impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
fn update_bits( fn update_bits(
trans: &mut impl GenKill<MovePathIndex>, trans: &mut impl GenKill<MovePathIndex>,
path: MovePathIndex, path: MovePathIndex,
@ -307,7 +307,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
} }
} }
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
/// There can be many more `MovePathIndex` than there are locals in a MIR body. /// There can be many more `MovePathIndex` than there are locals in a MIR body.
/// We use a chunked bitset to avoid paying too high a memory footprint. /// We use a chunked bitset to avoid paying too high a memory footprint.
type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>; type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>;
@ -329,7 +329,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
} }
} }
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
type Idx = MovePathIndex; type Idx = MovePathIndex;
fn domain_size(&self, _: &Body<'tcx>) -> usize { fn domain_size(&self, _: &Body<'tcx>) -> usize {
@ -442,7 +442,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
} }
} }
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
/// There can be many more `MovePathIndex` than there are locals in a MIR body. /// There can be many more `MovePathIndex` than there are locals in a MIR body.
/// We use a chunked bitset to avoid paying too high a memory footprint. /// We use a chunked bitset to avoid paying too high a memory footprint.
type Domain = ChunkedBitSet<MovePathIndex>; type Domain = ChunkedBitSet<MovePathIndex>;
@ -466,7 +466,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
} }
} }
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
type Idx = MovePathIndex; type Idx = MovePathIndex;
fn domain_size(&self, _: &Body<'tcx>) -> usize { fn domain_size(&self, _: &Body<'tcx>) -> usize {
@ -643,7 +643,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
} }
} }
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
/// There can be many more `InitIndex` than there are locals in a MIR body. /// There can be many more `InitIndex` than there are locals in a MIR body.
/// We use a chunked bitset to avoid paying too high a memory footprint. /// We use a chunked bitset to avoid paying too high a memory footprint.
type Domain = ChunkedBitSet<InitIndex>; type Domain = ChunkedBitSet<InitIndex>;
@ -662,7 +662,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
} }
} }
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> { impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
type Idx = InitIndex; type Idx = InitIndex;
fn domain_size(&self, _: &Body<'tcx>) -> usize { fn domain_size(&self, _: &Body<'tcx>) -> usize {

View file

@ -16,6 +16,7 @@ use super::{
struct MoveDataBuilder<'a, 'tcx, F> { struct MoveDataBuilder<'a, 'tcx, F> {
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
loc: Location,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
data: MoveData<'tcx>, data: MoveData<'tcx>,
@ -56,6 +57,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
MoveDataBuilder { MoveDataBuilder {
body, body,
loc: Location::START,
tcx, tcx,
param_env, param_env,
data: MoveData { data: MoveData {
@ -107,7 +109,7 @@ enum MovePathResult {
Error, Error,
} }
impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> { impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
/// This creates a MovePath for a given place, returning an `MovePathError` /// This creates a MovePath for a given place, returning an `MovePathError`
/// if that place can't be moved from. /// if that place can't be moved from.
/// ///
@ -116,7 +118,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
/// ///
/// Maybe we should have separate "borrowck" and "moveck" modes. /// Maybe we should have separate "borrowck" and "moveck" modes.
fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult { fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
let data = &mut self.builder.data; let data = &mut self.data;
debug!("lookup({:?})", place); debug!("lookup({:?})", place);
let Some(mut base) = data.rev_lookup.find_local(place.local) else { let Some(mut base) = data.rev_lookup.find_local(place.local) else {
@ -131,8 +133,8 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
let mut union_path = None; let mut union_path = None;
for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) { for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) {
let body = self.builder.body; let body = self.body;
let tcx = self.builder.tcx; let tcx = self.tcx;
let place_ty = place_ref.ty(body, tcx).ty; let place_ty = place_ref.ty(body, tcx).ty;
if place_ty.references_error() { if place_ty.references_error() {
return MovePathResult::Error; return MovePathResult::Error;
@ -238,7 +240,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
| ProjectionElem::Downcast(_, _) => (), | ProjectionElem::Downcast(_, _) => (),
} }
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty; let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
if !(self.builder.filter)(elem_ty) { if !(self.filter)(elem_ty) {
return MovePathResult::Error; return MovePathResult::Error;
} }
if union_path.is_none() { if union_path.is_none() {
@ -274,7 +276,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
data: MoveData { rev_lookup, move_paths, path_map, init_path_map, .. }, data: MoveData { rev_lookup, move_paths, path_map, init_path_map, .. },
tcx, tcx,
.. ..
} = self.builder; } = self;
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || { *rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx)) new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
}) })
@ -285,9 +287,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
// drop), so this not being a valid move path is OK. // drop), so this not being a valid move path is OK.
let _ = self.move_path_for(place); let _ = self.move_path_for(place);
} }
}
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
fn finalize(self) -> MoveData<'tcx> { fn finalize(self) -> MoveData<'tcx> {
debug!("{}", { debug!("{}", {
debug!("moves for {:?}:", self.body.span); debug!("moves for {:?}:", self.body.span);
@ -317,12 +317,12 @@ pub(super) fn gather_moves<'tcx>(
for (bb, block) in body.basic_blocks.iter_enumerated() { for (bb, block) in body.basic_blocks.iter_enumerated() {
for (i, stmt) in block.statements.iter().enumerate() { for (i, stmt) in block.statements.iter().enumerate() {
let source = Location { block: bb, statement_index: i }; builder.loc = Location { block: bb, statement_index: i };
builder.gather_statement(source, stmt); builder.gather_statement(stmt);
} }
let terminator_loc = Location { block: bb, statement_index: block.statements.len() }; builder.loc = Location { block: bb, statement_index: block.statements.len() };
builder.gather_terminator(terminator_loc, block.terminator()); builder.gather_terminator(block.terminator());
} }
builder.finalize() builder.finalize()
@ -345,30 +345,14 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
} }
} }
fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
debug!("gather_statement({:?}, {:?})", loc, stmt);
(Gatherer { builder: self, loc }).gather_statement(stmt);
}
fn gather_terminator(&mut self, loc: Location, term: &Terminator<'tcx>) {
debug!("gather_terminator({:?}, {:?})", loc, term);
(Gatherer { builder: self, loc }).gather_terminator(term);
}
}
struct Gatherer<'b, 'a, 'tcx, F> {
builder: &'b mut MoveDataBuilder<'a, 'tcx, F>,
loc: Location,
}
impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
fn gather_statement(&mut self, stmt: &Statement<'tcx>) { fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
debug!("gather_statement({:?}, {:?})", self.loc, stmt);
match &stmt.kind { match &stmt.kind {
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => { StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
let local = place.as_local().unwrap(); let local = place.as_local().unwrap();
assert!(self.builder.body.local_decls[local].is_deref_temp()); assert!(self.body.local_decls[local].is_deref_temp());
let rev_lookup = &mut self.builder.data.rev_lookup; let rev_lookup = &mut self.data.rev_lookup;
rev_lookup.un_derefer.insert(local, reffed.as_ref()); rev_lookup.un_derefer.insert(local, reffed.as_ref());
let base_local = rev_lookup.un_derefer.deref_chain(local).first().unwrap().local; let base_local = rev_lookup.un_derefer.deref_chain(local).first().unwrap().local;
@ -380,7 +364,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
// Box starts out uninitialized - need to create a separate // Box starts out uninitialized - need to create a separate
// move-path for the interior so it will be separate from // move-path for the interior so it will be separate from
// the exterior. // the exterior.
self.create_move_path(self.builder.tcx.mk_place_deref(*place)); self.create_move_path(self.tcx.mk_place_deref(*place));
self.gather_init(place.as_ref(), InitKind::Shallow); self.gather_init(place.as_ref(), InitKind::Shallow);
} else { } else {
self.gather_init(place.as_ref(), InitKind::Deep); self.gather_init(place.as_ref(), InitKind::Deep);
@ -393,7 +377,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
StatementKind::StorageLive(_) => {} StatementKind::StorageLive(_) => {}
StatementKind::StorageDead(local) => { StatementKind::StorageDead(local) => {
// DerefTemp locals (results of CopyForDeref) don't actually move anything. // DerefTemp locals (results of CopyForDeref) don't actually move anything.
if !self.builder.body.local_decls[*local].is_deref_temp() { if !self.body.local_decls[*local].is_deref_temp() {
self.gather_move(Place::from(*local)); self.gather_move(Place::from(*local));
} }
} }
@ -443,6 +427,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
} }
fn gather_terminator(&mut self, term: &Terminator<'tcx>) { fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
debug!("gather_terminator({:?}, {:?})", self.loc, term);
match term.kind { match term.kind {
TerminatorKind::Goto { target: _ } TerminatorKind::Goto { target: _ }
| TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseEdge { .. }
@ -551,7 +536,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
// `ConstIndex` patterns. This is done to ensure that all move paths // `ConstIndex` patterns. This is done to ensure that all move paths
// are disjoint, which is expected by drop elaboration. // are disjoint, which is expected by drop elaboration.
let base_place = let base_place =
Place { local: place.local, projection: self.builder.tcx.mk_place_elems(base) }; Place { local: place.local, projection: self.tcx.mk_place_elems(base) };
let base_path = match self.move_path_for(base_place) { let base_path = match self.move_path_for(base_place) {
MovePathResult::Path(path) => path, MovePathResult::Path(path) => path,
MovePathResult::Union(path) => { MovePathResult::Union(path) => {
@ -562,11 +547,9 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
return; return;
} }
}; };
let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty; let base_ty = base_place.ty(self.body, self.tcx).ty;
let len: u64 = match base_ty.kind() { let len: u64 = match base_ty.kind() {
ty::Array(_, size) => { ty::Array(_, size) => size.eval_target_usize(self.tcx, self.param_env),
size.eval_target_usize(self.builder.tcx, self.builder.param_env)
}
_ => bug!("from_end: false slice pattern of non-array type"), _ => bug!("from_end: false slice pattern of non-array type"),
}; };
for offset in from..to { for offset in from..to {
@ -587,13 +570,13 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
} }
fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) { fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) {
let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc }); let move_out = self.data.moves.push(MoveOut { path, source: self.loc });
debug!( debug!(
"gather_move({:?}, {:?}): adding move {:?} of {:?}", "gather_move({:?}, {:?}): adding move {:?} of {:?}",
self.loc, place, move_out, path self.loc, place, move_out, path
); );
self.builder.data.path_map[path].push(move_out); self.data.path_map[path].push(move_out);
self.builder.data.loc_map[self.loc].push(move_out); self.data.loc_map[self.loc].push(move_out);
} }
fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) { fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
@ -604,13 +587,13 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
// Check if we are assigning into a field of a union, if so, lookup the place // Check if we are assigning into a field of a union, if so, lookup the place
// of the union so it is marked as initialized again. // of the union so it is marked as initialized again.
if let Some((place_base, ProjectionElem::Field(_, _))) = place.last_projection() { if let Some((place_base, ProjectionElem::Field(_, _))) = place.last_projection() {
if place_base.ty(self.builder.body, self.builder.tcx).ty.is_union() { if place_base.ty(self.body, self.tcx).ty.is_union() {
place = place_base; place = place_base;
} }
} }
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) { if let LookupResult::Exact(path) = self.data.rev_lookup.find(place) {
let init = self.builder.data.inits.push(Init { let init = self.data.inits.push(Init {
location: InitLocation::Statement(self.loc), location: InitLocation::Statement(self.loc),
path, path,
kind, kind,
@ -621,8 +604,8 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
self.loc, place, init, path self.loc, place, init, path
); );
self.builder.data.init_path_map[path].push(init); self.data.init_path_map[path].push(init);
self.builder.data.init_loc_map[self.loc].push(init); self.data.init_loc_map[self.loc].push(init);
} }
} }
} }

View file

@ -923,14 +923,14 @@ impl<'tcx> Map<'tcx> {
} }
} }
struct PlaceCollector<'a, 'b, 'tcx> { struct PlaceCollector<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'b Body<'tcx>, body: &'a Body<'tcx>,
map: &'a mut Map<'tcx>, map: &'a mut Map<'tcx>,
assignments: FxIndexSet<(PlaceIndex, PlaceIndex)>, assignments: FxIndexSet<(PlaceIndex, PlaceIndex)>,
} }
impl<'tcx> PlaceCollector<'_, '_, 'tcx> { impl<'tcx> PlaceCollector<'_, 'tcx> {
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
fn register_place(&mut self, place: Place<'tcx>) -> Option<PlaceIndex> { fn register_place(&mut self, place: Place<'tcx>) -> Option<PlaceIndex> {
// Create a place for this projection. // Create a place for this projection.
@ -967,7 +967,7 @@ impl<'tcx> PlaceCollector<'_, '_, 'tcx> {
} }
} }
impl<'tcx> Visitor<'tcx> for PlaceCollector<'_, '_, 'tcx> { impl<'tcx> Visitor<'tcx> for PlaceCollector<'_, 'tcx> {
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, _: Location) { fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, _: Location) {
if !ctxt.is_use() { if !ctxt.is_use() {

View file

@ -20,7 +20,7 @@ use rustc_target::spec::PanicStrategy;
/// This forces all unwinds, in panic=abort mode happening in foreign code, to /// This forces all unwinds, in panic=abort mode happening in foreign code, to
/// trigger a process abort. /// trigger a process abort.
#[derive(PartialEq)] #[derive(PartialEq)]
pub struct AbortUnwindingCalls; pub(super) struct AbortUnwindingCalls;
impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls { impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@ -50,9 +50,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
// with a function call, and whose function we're calling may unwind. // with a function call, and whose function we're calling may unwind.
// This will filter to functions with `extern "C-unwind"` ABIs, for // This will filter to functions with `extern "C-unwind"` ABIs, for
// example. // example.
let mut calls_to_terminate = Vec::new(); for block in body.basic_blocks.as_mut() {
let mut cleanups_to_remove = Vec::new();
for (id, block) in body.basic_blocks.iter_enumerated() {
if block.is_cleanup { if block.is_cleanup {
continue; continue;
} }
@ -61,7 +59,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
let call_can_unwind = match &terminator.kind { let call_can_unwind = match &terminator.kind {
TerminatorKind::Call { func, .. } => { TerminatorKind::Call { func, .. } => {
let ty = func.ty(body, tcx); let ty = func.ty(&body.local_decls, tcx);
let sig = ty.fn_sig(tcx); let sig = ty.fn_sig(tcx);
let fn_def_id = match ty.kind() { let fn_def_id = match ty.kind() {
ty::FnPtr(..) => None, ty::FnPtr(..) => None,
@ -86,31 +84,20 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
_ => continue, _ => continue,
}; };
if !call_can_unwind {
// If this function call can't unwind, then there's no need for it // If this function call can't unwind, then there's no need for it
// to have a landing pad. This means that we can remove any cleanup // to have a landing pad. This means that we can remove any cleanup
// registered for it. // registered for it.
if !call_can_unwind { let cleanup = block.terminator_mut().unwind_mut().unwrap();
cleanups_to_remove.push(id); *cleanup = UnwindAction::Unreachable;
continue; } else if !body_can_unwind {
}
// Otherwise if this function can unwind, then if the outer function // Otherwise if this function can unwind, then if the outer function
// can also unwind there's nothing to do. If the outer function // can also unwind there's nothing to do. If the outer function
// can't unwind, however, we need to change the landing pad for this // can't unwind, however, we need to change the landing pad for this
// function call to one that aborts. // function call to one that aborts.
if !body_can_unwind { let cleanup = block.terminator_mut().unwind_mut().unwrap();
calls_to_terminate.push(id);
}
}
for id in calls_to_terminate {
let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap();
*cleanup = UnwindAction::Terminate(UnwindTerminateReason::Abi); *cleanup = UnwindAction::Terminate(UnwindTerminateReason::Abi);
} }
for id in cleanups_to_remove {
let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap();
*cleanup = UnwindAction::Unreachable;
} }
// We may have invalidated some `cleanup` blocks so clean those up now. // We may have invalidated some `cleanup` blocks so clean those up now.

View file

@ -4,11 +4,11 @@ use rustc_middle::ty::TyCtxt;
use tracing::debug; use tracing::debug;
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum AddCallGuards { pub(super) enum AddCallGuards {
AllCallEdges, AllCallEdges,
CriticalCallEdges, CriticalCallEdges,
} }
pub use self::AddCallGuards::*; pub(super) use self::AddCallGuards::*;
/** /**
* Breaks outgoing critical edges for call terminators in the MIR. * Breaks outgoing critical edges for call terminators in the MIR.
@ -37,7 +37,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
} }
impl AddCallGuards { impl AddCallGuards {
pub fn add_call_guards(&self, body: &mut Body<'_>) { pub(super) fn add_call_guards(&self, body: &mut Body<'_>) {
let mut pred_count: IndexVec<_, _> = let mut pred_count: IndexVec<_, _> =
body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect(); body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect();
pred_count[START_BLOCK] += 1; pred_count[START_BLOCK] += 1;

View file

@ -35,7 +35,7 @@ use crate::util;
/// ///
/// The storage instructions are required to avoid stack space /// The storage instructions are required to avoid stack space
/// blowup. /// blowup.
pub struct AddMovesForPackedDrops; pub(super) struct AddMovesForPackedDrops;
impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops { impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@ -44,7 +44,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
} }
} }
pub fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let patch = add_moves_for_packed_drops_patch(tcx, body); let patch = add_moves_for_packed_drops_patch(tcx, body);
patch.apply(body); patch.apply(body);
} }

View file

@ -8,7 +8,7 @@ use rustc_hir::LangItem;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct AddRetag; pub(super) struct AddRetag;
/// Determine whether this type may contain a reference (or box), and thus needs retagging. /// Determine whether this type may contain a reference (or box), and thus needs retagging.
/// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this. /// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this.

View file

@ -1,15 +1,14 @@
use rustc_index::IndexVec;
use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub struct Subtyper; pub(super) struct Subtyper;
pub struct SubTypeChecker<'a, 'tcx> { struct SubTypeChecker<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
patcher: MirPatch<'tcx>, patcher: MirPatch<'tcx>,
local_decls: &'a IndexVec<Local, LocalDecl<'tcx>>, local_decls: &'a LocalDecls<'tcx>,
} }
impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> { impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
@ -52,7 +51,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
// // gets transformed to // // gets transformed to
// let temp: rval_ty = rval; // let temp: rval_ty = rval;
// let place: place_ty = temp as place_ty; // let place: place_ty = temp as place_ty;
pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let patch = MirPatch::new(body); let patch = MirPatch::new(body);
let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls }; let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };

View file

@ -7,7 +7,7 @@ use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
use rustc_session::Session; use rustc_session::Session;
use tracing::{debug, trace}; use tracing::{debug, trace};
pub struct CheckAlignment; pub(super) struct CheckAlignment;
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment { impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
fn is_enabled(&self, sess: &Session) -> bool { fn is_enabled(&self, sess: &Session) -> bool {

View file

@ -8,7 +8,7 @@ use rustc_span::Span;
use crate::errors; use crate::errors;
pub struct CheckConstItemMutation; pub(super) struct CheckConstItemMutation;
impl<'tcx> crate::MirLint<'tcx> for CheckConstItemMutation { impl<'tcx> crate::MirLint<'tcx> for CheckConstItemMutation {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {

View file

@ -5,7 +5,7 @@ use rustc_middle::ty::{self, TyCtxt};
use crate::{errors, util}; use crate::{errors, util};
pub struct CheckPackedRef; pub(super) struct CheckPackedRef;
impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef { impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {

View file

@ -21,7 +21,7 @@ use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, Termi
use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub struct CleanupPostBorrowck; pub(super) struct CleanupPostBorrowck;
impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

View file

@ -17,7 +17,7 @@ use crate::ssa::SsaLocals;
/// where each of the locals is only assigned once. /// where each of the locals is only assigned once.
/// ///
/// We want to replace all those locals by `_a`, either copied or moved. /// We want to replace all those locals by `_a`, either copied or moved.
pub struct CopyProp; pub(super) struct CopyProp;
impl<'tcx> crate::MirPass<'tcx> for CopyProp { impl<'tcx> crate::MirPass<'tcx> for CopyProp {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -53,7 +53,7 @@
mod by_move_body; mod by_move_body;
use std::{iter, ops}; use std::{iter, ops};
pub use by_move_body::coroutine_by_move_body_def_id; pub(super) use by_move_body::coroutine_by_move_body_def_id;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::pluralize; use rustc_errors::pluralize;
use rustc_hir as hir; use rustc_hir as hir;
@ -85,7 +85,7 @@ use tracing::{debug, instrument, trace};
use crate::deref_separator::deref_finder; use crate::deref_separator::deref_finder;
use crate::{abort_unwinding_calls, errors, pass_manager as pm, simplify}; use crate::{abort_unwinding_calls, errors, pass_manager as pm, simplify};
pub struct StateTransform; pub(super) struct StateTransform;
struct RenameLocalVisitor<'tcx> { struct RenameLocalVisitor<'tcx> {
from: Local, from: Local,
@ -872,9 +872,9 @@ fn compute_storage_conflicts<'mir, 'tcx>(
storage_conflicts storage_conflicts
} }
struct StorageConflictVisitor<'mir, 'tcx, 's> { struct StorageConflictVisitor<'a, 'tcx> {
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
saved_locals: &'s CoroutineSavedLocals, saved_locals: &'a CoroutineSavedLocals,
// FIXME(tmandry): Consider using sparse bitsets here once we have good // FIXME(tmandry): Consider using sparse bitsets here once we have good
// benchmarks for coroutines. // benchmarks for coroutines.
local_conflicts: BitMatrix<Local, Local>, local_conflicts: BitMatrix<Local, Local>,
@ -882,8 +882,8 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> {
eligible_storage_live: BitSet<Local>, eligible_storage_live: BitSet<Local>,
} }
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
for StorageConflictVisitor<'mir, 'tcx, '_> for StorageConflictVisitor<'a, 'tcx>
{ {
type FlowState = BitSet<Local>; type FlowState = BitSet<Local>;
@ -891,7 +891,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
&mut self, &mut self,
_results: &mut R, _results: &mut R,
state: &Self::FlowState, state: &Self::FlowState,
_statement: &'mir Statement<'tcx>, _statement: &'a Statement<'tcx>,
loc: Location, loc: Location,
) { ) {
self.apply_state(state, loc); self.apply_state(state, loc);
@ -901,14 +901,14 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
&mut self, &mut self,
_results: &mut R, _results: &mut R,
state: &Self::FlowState, state: &Self::FlowState,
_terminator: &'mir Terminator<'tcx>, _terminator: &'a Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
self.apply_state(state, loc); self.apply_state(state, loc);
} }
} }
impl StorageConflictVisitor<'_, '_, '_> { impl StorageConflictVisitor<'_, '_> {
fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) { fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) {
// Ignore unreachable blocks. // Ignore unreachable blocks.
if let TerminatorKind::Unreachable = self.body.basic_blocks[loc.block].terminator().kind { if let TerminatorKind::Unreachable = self.body.basic_blocks[loc.block].terminator().kind {
@ -1199,7 +1199,7 @@ fn insert_panic_block<'tcx>(
message: AssertMessage<'tcx>, message: AssertMessage<'tcx>,
) -> BasicBlock { ) -> BasicBlock {
let assert_block = BasicBlock::new(body.basic_blocks.len()); let assert_block = BasicBlock::new(body.basic_blocks.len());
let term = TerminatorKind::Assert { let kind = TerminatorKind::Assert {
cond: Operand::Constant(Box::new(ConstOperand { cond: Operand::Constant(Box::new(ConstOperand {
span: body.span, span: body.span,
user_ty: None, user_ty: None,
@ -1211,14 +1211,7 @@ fn insert_panic_block<'tcx>(
unwind: UnwindAction::Continue, unwind: UnwindAction::Continue,
}; };
let source_info = SourceInfo::outermost(body.span); insert_term_block(body, kind)
body.basic_blocks_mut().push(BasicBlockData {
statements: Vec::new(),
terminator: Some(Terminator { source_info, kind: term }),
is_cleanup: false,
});
assert_block
} }
fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {

View file

@ -82,7 +82,7 @@ use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::abi::{FieldIdx, VariantIdx};
pub fn coroutine_by_move_body_def_id<'tcx>( pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
coroutine_def_id: LocalDefId, coroutine_def_id: LocalDefId,
) -> DefId { ) -> DefId {

View file

@ -12,7 +12,7 @@ const CONST_SWITCH_BONUS: usize = 10;
/// Verify that the callee body is compatible with the caller. /// Verify that the callee body is compatible with the caller.
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct CostChecker<'b, 'tcx> { pub(super) struct CostChecker<'b, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
penalty: usize, penalty: usize,
@ -22,7 +22,7 @@ pub(crate) struct CostChecker<'b, 'tcx> {
} }
impl<'b, 'tcx> CostChecker<'b, 'tcx> { impl<'b, 'tcx> CostChecker<'b, 'tcx> {
pub fn new( pub(super) fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
instance: Option<ty::Instance<'tcx>>, instance: Option<ty::Instance<'tcx>>,
@ -36,7 +36,7 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
/// Needed because the `CostChecker` is used sometimes for just blocks, /// Needed because the `CostChecker` is used sometimes for just blocks,
/// and even the full `Inline` doesn't call `visit_body`, so there's nowhere /// and even the full `Inline` doesn't call `visit_body`, so there's nowhere
/// to put this logic in the visitor. /// to put this logic in the visitor.
pub fn add_function_level_costs(&mut self) { pub(super) fn add_function_level_costs(&mut self) {
fn is_call_like(bbd: &BasicBlockData<'_>) -> bool { fn is_call_like(bbd: &BasicBlockData<'_>) -> bool {
use TerminatorKind::*; use TerminatorKind::*;
match bbd.terminator().kind { match bbd.terminator().kind {
@ -64,7 +64,7 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
} }
} }
pub fn cost(&self) -> usize { pub(super) fn cost(&self) -> usize {
usize::saturating_sub(self.penalty, self.bonus) usize::saturating_sub(self.penalty, self.bonus)
} }

View file

@ -1,4 +1,4 @@
pub mod query; pub(super) mod query;
mod counters; mod counters;
mod graph; mod graph;
@ -32,7 +32,7 @@ use crate::coverage::mappings::ExtractedMappings;
/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected /// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen /// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
/// to construct the coverage map. /// to construct the coverage map.
pub struct InstrumentCoverage; pub(super) struct InstrumentCoverage;
impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage { impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -10,7 +10,7 @@ use rustc_span::sym;
use crate::{inline, pass_manager as pm}; use crate::{inline, pass_manager as pm};
pub fn provide(providers: &mut Providers) { pub(super) fn provide(providers: &mut Providers) {
providers.cross_crate_inlinable = cross_crate_inlinable; providers.cross_crate_inlinable = cross_crate_inlinable;
} }

View file

@ -8,7 +8,7 @@ use rustc_middle::mir::{
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use tracing::instrument; use tracing::instrument;
pub struct CtfeLimit; pub(super) struct CtfeLimit;
impl<'tcx> crate::MirPass<'tcx> for CtfeLimit { impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
#[instrument(skip(self, _tcx, body))] #[instrument(skip(self, _tcx, body))]

View file

@ -26,7 +26,7 @@ use tracing::{debug, debug_span, instrument};
const BLOCK_LIMIT: usize = 100; const BLOCK_LIMIT: usize = 100;
const PLACE_LIMIT: usize = 100; const PLACE_LIMIT: usize = 100;
pub struct DataflowConstProp; pub(super) struct DataflowConstProp;
impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp { impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
@ -332,7 +332,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
} }
impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map<'tcx>) -> Self { fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map<'tcx>) -> Self {
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
Self { Self {
map, map,
@ -838,14 +838,14 @@ impl<'tcx> MutVisitor<'tcx> for Patch<'tcx> {
} }
} }
struct OperandCollector<'tcx, 'map, 'locals, 'a> { struct OperandCollector<'a, 'locals, 'tcx> {
state: &'a State<FlatSet<Scalar>>, state: &'a State<FlatSet<Scalar>>,
visitor: &'a mut Collector<'tcx, 'locals>, visitor: &'a mut Collector<'tcx, 'locals>,
ecx: &'map mut InterpCx<'tcx, DummyMachine>, ecx: &'a mut InterpCx<'tcx, DummyMachine>,
map: &'map Map<'tcx>, map: &'a Map<'tcx>,
} }
impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> { impl<'tcx> Visitor<'tcx> for OperandCollector<'_, '_, 'tcx> {
fn visit_projection_elem( fn visit_projection_elem(
&mut self, &mut self,
_: PlaceRef<'tcx>, _: PlaceRef<'tcx>,

View file

@ -28,7 +28,7 @@ use crate::util::is_within_packed;
/// ///
/// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It /// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It
/// can be generated via the [`borrowed_locals`] function. /// can be generated via the [`borrowed_locals`] function.
pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let borrowed_locals = borrowed_locals(body); let borrowed_locals = borrowed_locals(body);
// If the user requests complete debuginfo, mark the locals that appear in it as live, so // If the user requests complete debuginfo, mark the locals that appear in it as live, so
@ -127,7 +127,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
} }
} }
pub enum DeadStoreElimination { pub(super) enum DeadStoreElimination {
Initial, Initial,
Final, Final,
} }

View file

@ -150,7 +150,7 @@ fn type_will_always_be_passed_directly(ty: Ty<'_>) -> bool {
/// body of the function instead of just the signature. These can be useful for optimization /// body of the function instead of just the signature. These can be useful for optimization
/// purposes on a best-effort basis. We compute them here and store them into the crate metadata so /// purposes on a best-effort basis. We compute them here and store them into the crate metadata so
/// dependent crates can use them. /// dependent crates can use them.
pub fn deduced_param_attrs<'tcx>( pub(super) fn deduced_param_attrs<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: LocalDefId, def_id: LocalDefId,
) -> &'tcx [DeducedParamAttrs] { ) -> &'tcx [DeducedParamAttrs] {

View file

@ -13,7 +13,7 @@ use tracing::debug;
use super::simplify::simplify_cfg; use super::simplify::simplify_cfg;
pub struct DeduplicateBlocks; pub(super) struct DeduplicateBlocks;
impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks { impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -1,16 +1,15 @@
use rustc_index::IndexVec;
use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
use rustc_middle::mir::visit::{MutVisitor, PlaceContext}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub struct Derefer; pub(super) struct Derefer;
pub struct DerefChecker<'a, 'tcx> { struct DerefChecker<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
patcher: MirPatch<'tcx>, patcher: MirPatch<'tcx>,
local_decls: &'a IndexVec<Local, LocalDecl<'tcx>>, local_decls: &'a LocalDecls<'tcx>,
} }
impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> { impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> {
@ -67,7 +66,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> {
} }
} }
pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { pub(super) fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let patch = MirPatch::new(body); let patch = MirPatch::new(body);
let mut checker = DerefChecker { tcx, patcher: patch, local_decls: &body.local_decls }; let mut checker = DerefChecker { tcx, patcher: patch, local_decls: &body.local_decls };

View file

@ -146,7 +146,7 @@ use rustc_mir_dataflow::points::{save_as_intervals, DenseLocationMap, PointIndex
use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::Analysis;
use tracing::{debug, trace}; use tracing::{debug, trace};
pub struct DestinationPropagation; pub(super) struct DestinationPropagation;
impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation { impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -7,7 +7,7 @@ use rustc_middle::mir::{write_mir_pretty, Body};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::config::{OutFileName, OutputType}; use rustc_session::config::{OutFileName, OutputType};
pub struct Marker(pub &'static str); pub(super) struct Marker(pub &'static str);
impl<'tcx> crate::MirPass<'tcx> for Marker { impl<'tcx> crate::MirPass<'tcx> for Marker {
fn name(&self) -> &'static str { fn name(&self) -> &'static str {

View file

@ -90,7 +90,7 @@ use super::simplify::simplify_cfg;
/// | ... | /// | ... |
/// ================= /// =================
/// ``` /// ```
pub struct EarlyOtherwiseBranch; pub(super) struct EarlyOtherwiseBranch;
impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
@ -310,42 +310,28 @@ fn verify_candidate_branch<'tcx>(
) -> bool { ) -> bool {
// In order for the optimization to be correct, the branch must... // In order for the optimization to be correct, the branch must...
// ...have exactly one statement // ...have exactly one statement
let [statement] = branch.statements.as_slice() else { if let [statement] = branch.statements.as_slice()
return false;
};
// ...assign the discriminant of `place` in that statement // ...assign the discriminant of `place` in that statement
let StatementKind::Assign(boxed) = &statement.kind else { return false }; && let StatementKind::Assign(boxed) = &statement.kind
let (discr_place, Rvalue::Discriminant(from_place)) = &**boxed else { return false }; && let (discr_place, Rvalue::Discriminant(from_place)) = &**boxed
if *from_place != place { && *from_place == place
return false;
}
// ...make that assignment to a local // ...make that assignment to a local
if discr_place.projection.len() != 0 { && discr_place.projection.is_empty()
return false;
}
// ...terminate on a `SwitchInt` that invalidates that local // ...terminate on a `SwitchInt` that invalidates that local
let TerminatorKind::SwitchInt { discr: switch_op, targets, .. } = &branch.terminator().kind && let TerminatorKind::SwitchInt { discr: switch_op, targets, .. } =
else { &branch.terminator().kind
return false; && *switch_op == Operand::Move(*discr_place)
};
if *switch_op != Operand::Move(*discr_place) {
return false;
}
// ...fall through to `destination` if the switch misses // ...fall through to `destination` if the switch misses
if destination != targets.otherwise() { && destination == targets.otherwise()
return false;
}
// ...have a branch for value `value` // ...have a branch for value `value`
let mut iter = targets.iter(); && let mut iter = targets.iter()
let Some((target_value, _)) = iter.next() else { && let Some((target_value, _)) = iter.next()
return false; && target_value == value
};
if target_value != value {
return false;
}
// ...and have no more branches // ...and have no more branches
if let Some(_) = iter.next() { && iter.next().is_none()
return false; {
}
true true
} else {
false
}
} }

View file

@ -11,7 +11,7 @@ use rustc_middle::ty::{Ty, TyCtxt};
use rustc_target::abi::FieldIdx; use rustc_target::abi::FieldIdx;
/// Constructs the types used when accessing a Box's pointer /// Constructs the types used when accessing a Box's pointer
pub fn build_ptr_tys<'tcx>( fn build_ptr_tys<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
pointee: Ty<'tcx>, pointee: Ty<'tcx>,
unique_did: DefId, unique_did: DefId,
@ -26,7 +26,7 @@ pub fn build_ptr_tys<'tcx>(
} }
/// Constructs the projection needed to access a Box's pointer /// Constructs the projection needed to access a Box's pointer
pub fn build_projection<'tcx>( pub(super) fn build_projection<'tcx>(
unique_ty: Ty<'tcx>, unique_ty: Ty<'tcx>,
nonnull_ty: Ty<'tcx>, nonnull_ty: Ty<'tcx>,
ptr_ty: Ty<'tcx>, ptr_ty: Ty<'tcx>,
@ -88,15 +88,16 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
} }
} }
pub struct ElaborateBoxDerefs; pub(super) struct ElaborateBoxDerefs;
impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs { impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if let Some(def_id) = tcx.lang_items().owned_box() { // If box is not present, this pass doesn't need to do anything.
let Some(def_id) = tcx.lang_items().owned_box() else { return };
let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did; let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
let Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def() let Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def() else {
else {
span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
}; };
@ -132,9 +133,8 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
let (unique_ty, nonnull_ty, ptr_ty) = let (unique_ty, nonnull_ty, ptr_ty) =
build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did); build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did);
new_projections.extend_from_slice(&build_projection( new_projections
unique_ty, nonnull_ty, ptr_ty, .extend_from_slice(&build_projection(unique_ty, nonnull_ty, ptr_ty));
));
new_projections.push(PlaceElem::Deref); new_projections.push(PlaceElem::Deref);
} else if let Some(new_projections) = new_projections.as_mut() { } else if let Some(new_projections) = new_projections.as_mut() {
// Keep building up our projections list once we've started it. // Keep building up our projections list once we've started it.
@ -148,8 +148,5 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
} }
} }
} }
} else {
// box is not present, this pass doesn't need to do anything
}
} }
} }

View file

@ -47,7 +47,7 @@ use crate::deref_separator::deref_finder;
/// } /// }
/// } /// }
/// ``` /// ```
pub struct ElaborateDrops; pub(super) struct ElaborateDrops;
impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops { impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
#[instrument(level = "trace", skip(self, tcx, body))] #[instrument(level = "trace", skip(self, tcx, body))]
@ -98,9 +98,9 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
/// Records unwind edges which are known to be unreachable, because they are in `drop` terminators /// Records unwind edges which are known to be unreachable, because they are in `drop` terminators
/// that can't drop anything. /// that can't drop anything.
#[instrument(level = "trace", skip(body, flow_inits), ret)] #[instrument(level = "trace", skip(body, flow_inits), ret)]
fn compute_dead_unwinds<'mir, 'tcx>( fn compute_dead_unwinds<'a, 'tcx>(
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
) -> BitSet<BasicBlock> { ) -> BitSet<BasicBlock> {
// We only need to do this pass once, because unwind edges can only // We only need to do this pass once, because unwind edges can only
// reach cleanup blocks, which can't have unwind edges themselves. // reach cleanup blocks, which can't have unwind edges themselves.
@ -121,12 +121,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
dead_unwinds dead_unwinds
} }
struct InitializationData<'a, 'mir, 'tcx> { struct InitializationData<'a, 'tcx> {
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>, inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, uninits: ResultsCursor<'a, 'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
} }
impl InitializationData<'_, '_, '_> { impl InitializationData<'_, '_> {
fn seek_before(&mut self, loc: Location) { fn seek_before(&mut self, loc: Location) {
self.inits.seek_before_primary_effect(loc); self.inits.seek_before_primary_effect(loc);
self.uninits.seek_before_primary_effect(loc); self.uninits.seek_before_primary_effect(loc);
@ -137,45 +137,35 @@ impl InitializationData<'_, '_, '_> {
} }
} }
struct Elaborator<'a, 'b, 'mir, 'tcx> { impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
ctxt: &'a mut ElaborateDropsCtxt<'b, 'mir, 'tcx>,
}
impl fmt::Debug for Elaborator<'_, '_, '_, '_> {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
type Path = MovePathIndex; type Path = MovePathIndex;
fn patch(&mut self) -> &mut MirPatch<'tcx> { fn patch(&mut self) -> &mut MirPatch<'tcx> {
&mut self.ctxt.patch &mut self.patch
} }
fn body(&self) -> &'a Body<'tcx> { fn body(&self) -> &'a Body<'tcx> {
self.ctxt.body self.body
} }
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.ctxt.tcx self.tcx
} }
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.ctxt.param_env() self.param_env()
} }
#[instrument(level = "debug", skip(self), ret)] #[instrument(level = "debug", skip(self), ret)]
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle { fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
let ((maybe_live, maybe_dead), multipart) = match mode { let ((maybe_live, maybe_dead), multipart) = match mode {
DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false), DropFlagMode::Shallow => (self.init_data.maybe_live_dead(path), false),
DropFlagMode::Deep => { DropFlagMode::Deep => {
let mut some_live = false; let mut some_live = false;
let mut some_dead = false; let mut some_dead = false;
let mut children_count = 0; let mut children_count = 0;
on_all_children_bits(self.ctxt.move_data(), path, |child| { on_all_children_bits(self.move_data(), path, |child| {
let (live, dead) = self.ctxt.init_data.maybe_live_dead(child); let (live, dead) = self.init_data.maybe_live_dead(child);
debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead)); debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead));
some_live |= live; some_live |= live;
some_dead |= dead; some_dead |= dead;
@ -195,25 +185,25 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
fn clear_drop_flag(&mut self, loc: Location, path: Self::Path, mode: DropFlagMode) { fn clear_drop_flag(&mut self, loc: Location, path: Self::Path, mode: DropFlagMode) {
match mode { match mode {
DropFlagMode::Shallow => { DropFlagMode::Shallow => {
self.ctxt.set_drop_flag(loc, path, DropFlagState::Absent); self.set_drop_flag(loc, path, DropFlagState::Absent);
} }
DropFlagMode::Deep => { DropFlagMode::Deep => {
on_all_children_bits(self.ctxt.move_data(), path, |child| { on_all_children_bits(self.move_data(), path, |child| {
self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent) self.set_drop_flag(loc, child, DropFlagState::Absent)
}); });
} }
} }
} }
fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option<Self::Path> { fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option<Self::Path> {
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| match e {
ProjectionElem::Field(idx, _) => idx == field, ProjectionElem::Field(idx, _) => idx == field,
_ => false, _ => false,
}) })
} }
fn array_subpath(&self, path: Self::Path, index: u64, size: u64) -> Option<Self::Path> { fn array_subpath(&self, path: Self::Path, index: u64, size: u64) -> Option<Self::Path> {
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| match e {
ProjectionElem::ConstantIndex { offset, min_length, from_end } => { ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
debug_assert!(size == min_length, "min_length should be exact for arrays"); debug_assert!(size == min_length, "min_length should be exact for arrays");
assert!(!from_end, "from_end should not be used for array element ConstantIndex"); assert!(!from_end, "from_end should not be used for array element ConstantIndex");
@ -224,34 +214,40 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
} }
fn deref_subpath(&self, path: Self::Path) -> Option<Self::Path> { fn deref_subpath(&self, path: Self::Path) -> Option<Self::Path> {
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| { rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| {
e == ProjectionElem::Deref e == ProjectionElem::Deref
}) })
} }
fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path> { fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path> {
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| match e {
ProjectionElem::Downcast(_, idx) => idx == variant, ProjectionElem::Downcast(_, idx) => idx == variant,
_ => false, _ => false,
}) })
} }
fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>> { fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>> {
self.ctxt.drop_flag(path).map(Operand::Copy) self.drop_flag(path).map(Operand::Copy)
} }
} }
struct ElaborateDropsCtxt<'a, 'mir, 'tcx> { struct ElaborateDropsCtxt<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'a Body<'tcx>,
env: &'a MoveDataParamEnv<'tcx>, env: &'a MoveDataParamEnv<'tcx>,
init_data: InitializationData<'a, 'mir, 'tcx>, init_data: InitializationData<'a, 'tcx>,
drop_flags: IndexVec<MovePathIndex, Option<Local>>, drop_flags: IndexVec<MovePathIndex, Option<Local>>,
patch: MirPatch<'tcx>, patch: MirPatch<'tcx>,
} }
impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> { impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
fn move_data(&self) -> &'b MoveData<'tcx> { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> {
fn move_data(&self) -> &'a MoveData<'tcx> {
&self.env.move_data &self.env.move_data
} }
@ -370,15 +366,7 @@ impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
} }
}; };
self.init_data.seek_before(self.body.terminator_loc(bb)); self.init_data.seek_before(self.body.terminator_loc(bb));
elaborate_drop( elaborate_drop(self, terminator.source_info, place, path, target, unwind, bb)
&mut Elaborator { ctxt: self },
terminator.source_info,
place,
path,
target,
unwind,
bb,
)
} }
LookupResult::Parent(None) => {} LookupResult::Parent(None) => {}
LookupResult::Parent(Some(_)) => { LookupResult::Parent(Some(_)) => {

View file

@ -64,7 +64,7 @@ impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> {
} }
impl AssertLintKind { impl AssertLintKind {
pub fn lint(&self) -> &'static Lint { pub(crate) fn lint(&self) -> &'static Lint {
match self { match self {
AssertLintKind::ArithmeticOverflow => lint::builtin::ARITHMETIC_OVERFLOW, AssertLintKind::ArithmeticOverflow => lint::builtin::ARITHMETIC_OVERFLOW,
AssertLintKind::UnconditionalPanic => lint::builtin::UNCONDITIONAL_PANIC, AssertLintKind::UnconditionalPanic => lint::builtin::UNCONDITIONAL_PANIC,

View file

@ -11,7 +11,7 @@ use rustc_target::spec::abi::Abi;
use crate::errors; use crate::errors;
pub struct FunctionItemReferences; pub(super) struct FunctionItemReferences;
impl<'tcx> crate::MirLint<'tcx> for FunctionItemReferences { impl<'tcx> crate::MirLint<'tcx> for FunctionItemReferences {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {

View file

@ -109,7 +109,7 @@ use tracing::{debug, instrument, trace};
use crate::ssa::{AssignedValue, SsaLocals}; use crate::ssa::{AssignedValue, SsaLocals};
pub struct GVN; pub(super) struct GVN;
impl<'tcx> crate::MirPass<'tcx> for GVN { impl<'tcx> crate::MirPass<'tcx> for GVN {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -32,9 +32,11 @@ pub(crate) mod cycle;
const TOP_DOWN_DEPTH_LIMIT: usize = 5; const TOP_DOWN_DEPTH_LIMIT: usize = 5;
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
// by custom rustc drivers, running all the steps by themselves. See #114628.
pub struct Inline; pub struct Inline;
#[derive(Copy, Clone, Debug)] #[derive(Clone, Debug)]
struct CallSite<'tcx> { struct CallSite<'tcx> {
callee: Instance<'tcx>, callee: Instance<'tcx>,
fn_sig: ty::PolyFnSig<'tcx>, fn_sig: ty::PolyFnSig<'tcx>,
@ -156,7 +158,6 @@ impl<'tcx> Inliner<'tcx> {
match self.try_inlining(caller_body, &callsite) { match self.try_inlining(caller_body, &callsite) {
Err(reason) => { Err(reason) => {
debug!("not-inlined {} [{}]", callsite.callee, reason); debug!("not-inlined {} [{}]", callsite.callee, reason);
continue;
} }
Ok(new_blocks) => { Ok(new_blocks) => {
debug!("inlined {}", callsite.callee); debug!("inlined {}", callsite.callee);
@ -638,7 +639,7 @@ impl<'tcx> Inliner<'tcx> {
); );
let dest_ty = dest.ty(caller_body, self.tcx); let dest_ty = dest.ty(caller_body, self.tcx);
let temp = let temp =
Place::from(self.new_call_temp(caller_body, &callsite, dest_ty, return_block)); Place::from(self.new_call_temp(caller_body, callsite, dest_ty, return_block));
caller_body[callsite.block].statements.push(Statement { caller_body[callsite.block].statements.push(Statement {
source_info: callsite.source_info, source_info: callsite.source_info,
kind: StatementKind::Assign(Box::new((temp, dest))), kind: StatementKind::Assign(Box::new((temp, dest))),
@ -657,7 +658,7 @@ impl<'tcx> Inliner<'tcx> {
true, true,
self.new_call_temp( self.new_call_temp(
caller_body, caller_body,
&callsite, callsite,
destination.ty(caller_body, self.tcx).ty, destination.ty(caller_body, self.tcx).ty,
return_block, return_block,
), ),
@ -665,7 +666,7 @@ impl<'tcx> Inliner<'tcx> {
}; };
// Copy the arguments if needed. // Copy the arguments if needed.
let args = self.make_call_args(args, &callsite, caller_body, &callee_body, return_block); let args = self.make_call_args(args, callsite, caller_body, &callee_body, return_block);
let mut integrator = Integrator { let mut integrator = Integrator {
args: &args, args: &args,

View file

@ -13,13 +13,13 @@ use rustc_target::spec::abi::Abi;
use crate::simplify::simplify_duplicate_switch_targets; use crate::simplify::simplify_duplicate_switch_targets;
use crate::take_array; use crate::take_array;
pub enum InstSimplify { pub(super) enum InstSimplify {
BeforeInline, BeforeInline,
AfterSimplifyCfg, AfterSimplifyCfg,
} }
impl InstSimplify { impl InstSimplify {
pub fn name(&self) -> &'static str { fn name(&self) -> &'static str {
match self { match self {
InstSimplify::BeforeInline => "InstSimplify-before-inline", InstSimplify::BeforeInline => "InstSimplify-before-inline",
InstSimplify::AfterSimplifyCfg => "InstSimplify-after-simplifycfg", InstSimplify::AfterSimplifyCfg => "InstSimplify-after-simplifycfg",

View file

@ -55,7 +55,7 @@ use tracing::{debug, instrument, trace};
use crate::cost_checker::CostChecker; use crate::cost_checker::CostChecker;
pub struct JumpThreading; pub(super) struct JumpThreading;
const MAX_BACKTRACK: usize = 5; const MAX_BACKTRACK: usize = 5;
const MAX_COST: usize = 100; const MAX_COST: usize = 100;

View file

@ -26,7 +26,7 @@ use tracing::{debug, instrument, trace};
use crate::errors::{AssertLint, AssertLintKind}; use crate::errors::{AssertLint, AssertLintKind};
pub struct KnownPanicsLint; pub(super) struct KnownPanicsLint;
impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint { impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
@ -852,7 +852,7 @@ const MAX_ALLOC_LIMIT: u64 = 1024;
/// The mode that `ConstProp` is allowed to run in for a given `Local`. /// The mode that `ConstProp` is allowed to run in for a given `Local`.
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum ConstPropMode { enum ConstPropMode {
/// The `Local` can be propagated into and reads of this `Local` can also be propagated. /// The `Local` can be propagated into and reads of this `Local` can also be propagated.
FullConstProp, FullConstProp,
/// The `Local` can only be propagated into and from its own block. /// The `Local` can only be propagated into and from its own block.
@ -864,7 +864,7 @@ pub enum ConstPropMode {
/// A visitor that determines locals in a MIR body /// A visitor that determines locals in a MIR body
/// that can be const propagated /// that can be const propagated
pub struct CanConstProp { struct CanConstProp {
can_const_prop: IndexVec<Local, ConstPropMode>, can_const_prop: IndexVec<Local, ConstPropMode>,
// False at the beginning. Once set, no more assignments are allowed to that local. // False at the beginning. Once set, no more assignments are allowed to that local.
found_assignment: BitSet<Local>, found_assignment: BitSet<Local>,
@ -872,7 +872,7 @@ pub struct CanConstProp {
impl CanConstProp { impl CanConstProp {
/// Returns true if `local` can be propagated /// Returns true if `local` can be propagated
pub fn check<'tcx>( fn check<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,

View file

@ -23,7 +23,7 @@ use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants};
/// In summary, what this does is at runtime determine which enum variant is active, /// In summary, what this does is at runtime determine which enum variant is active,
/// and instead of copying all the bytes of the largest possible variant, /// and instead of copying all the bytes of the largest possible variant,
/// copy only the bytes for the currently active variant. /// copy only the bytes for the currently active variant.
pub struct EnumSizeOpt { pub(super) struct EnumSizeOpt {
pub(crate) discrepancy: u64, pub(crate) discrepancy: u64,
} }

View file

@ -11,6 +11,7 @@
#![feature(round_char_boundary)] #![feature(round_char_boundary)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(yeet_expr)] #![feature(yeet_expr)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end // tidy-alphabetical-end
use hir::ConstContext; use hir::ConstContext;
@ -72,6 +73,8 @@ mod errors;
mod ffi_unwind_calls; mod ffi_unwind_calls;
mod function_item_references; mod function_item_references;
mod gvn; mod gvn;
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
// by custom rustc drivers, running all the steps by themselves. See #114628.
pub mod inline; pub mod inline;
mod instsimplify; mod instsimplify;
mod jump_threading; mod jump_threading;
@ -459,8 +462,8 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
tcx.alloc_steal_mir(body) tcx.alloc_steal_mir(body)
} }
// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden // Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
// by custom rustc drivers, running all the steps by themselves. // by custom rustc drivers, running all the steps by themselves. See #114628.
pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial)); assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
let did = body.source.def_id(); let did = body.source.def_id();

View file

@ -13,7 +13,7 @@ use rustc_mir_dataflow::impls::{MaybeStorageDead, MaybeStorageLive};
use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::{Analysis, ResultsCursor}; use rustc_mir_dataflow::{Analysis, ResultsCursor};
pub fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) { pub(super) fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
let always_live_locals = &always_storage_live_locals(body); let always_live_locals = &always_storage_live_locals(body);
let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals)) let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))

View file

@ -7,7 +7,7 @@ use rustc_span::symbol::sym;
use crate::take_array; use crate::take_array;
pub struct LowerIntrinsics; pub(super) struct LowerIntrinsics;
impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics { impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@ -35,7 +35,7 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
sym::forget => { sym::forget => {
if let Some(target) = *target { let target = target.unwrap();
block.statements.push(Statement { block.statements.push(Statement {
source_info: terminator.source_info, source_info: terminator.source_info,
kind: StatementKind::Assign(Box::new(( kind: StatementKind::Assign(Box::new((
@ -49,7 +49,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
}); });
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
}
sym::copy_nonoverlapping => { sym::copy_nonoverlapping => {
let target = target.unwrap(); let target = target.unwrap();
let Ok([src, dst, count]) = take_array(args) else { let Ok([src, dst, count]) = take_array(args) else {
@ -121,7 +120,7 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
if let Some(target) = *target { let target = target.unwrap();
let Ok([lhs, rhs]) = take_array(args) else { let Ok([lhs, rhs]) = take_array(args) else {
bug!("Wrong arguments for {} intrinsic", intrinsic.name); bug!("Wrong arguments for {} intrinsic", intrinsic.name);
}; };
@ -140,9 +139,8 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
}); });
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
}
sym::size_of | sym::min_align_of => { sym::size_of | sym::min_align_of => {
if let Some(target) = *target { let target = target.unwrap();
let tp_ty = generic_args.type_at(0); let tp_ty = generic_args.type_at(0);
let null_op = match intrinsic.name { let null_op = match intrinsic.name {
sym::size_of => NullOp::SizeOf, sym::size_of => NullOp::SizeOf,
@ -158,7 +156,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
}); });
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
}
sym::read_via_copy => { sym::read_via_copy => {
let Ok([arg]) = take_array(args) else { let Ok([arg]) = take_array(args) else {
span_bug!(terminator.source_info.span, "Wrong number of arguments"); span_bug!(terminator.source_info.span, "Wrong number of arguments");
@ -219,7 +216,14 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
sym::discriminant_value => { sym::discriminant_value => {
if let (Some(target), Some(arg)) = (*target, args[0].node.place()) { let target = target.unwrap();
let Ok([arg]) = take_array(args) else {
span_bug!(
terminator.source_info.span,
"Wrong arguments for discriminant_value intrinsic"
);
};
let arg = arg.node.place().unwrap();
let arg = tcx.mk_place_deref(arg); let arg = tcx.mk_place_deref(arg);
block.statements.push(Statement { block.statements.push(Statement {
source_info: terminator.source_info, source_info: terminator.source_info,
@ -230,7 +234,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
}); });
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
}
sym::offset => { sym::offset => {
let target = target.unwrap(); let target = target.unwrap();
let Ok([ptr, delta]) = take_array(args) else { let Ok([ptr, delta]) = take_array(args) else {
@ -267,7 +270,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
Rvalue::Cast(CastKind::Transmute, arg.node, dst_ty), Rvalue::Cast(CastKind::Transmute, arg.node, dst_ty),
))), ))),
}); });
if let Some(target) = *target { if let Some(target) = *target {
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} else { } else {
@ -299,7 +301,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
Rvalue::Aggregate(Box::new(kind), fields.into()), Rvalue::Aggregate(Box::new(kind), fields.into()),
))), ))),
}); });
terminator.kind = TerminatorKind::Goto { target }; terminator.kind = TerminatorKind::Goto { target };
} }
sym::ptr_metadata => { sym::ptr_metadata => {

View file

@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub struct LowerSliceLenCalls; pub(super) struct LowerSliceLenCalls;
impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls { impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
@ -17,7 +17,7 @@ impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
} }
} }
pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let language_items = tcx.lang_items(); let language_items = tcx.lang_items();
let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else { let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
// there is no lang item to compare to :) // there is no lang item to compare to :)

View file

@ -10,7 +10,7 @@ use rustc_type_ir::TyKind::*;
use super::simplify::simplify_cfg; use super::simplify::simplify_cfg;
pub struct MatchBranchSimplification; pub(super) struct MatchBranchSimplification;
impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification { impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -5,7 +5,7 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
pub struct MentionedItems; pub(super) struct MentionedItems;
struct MentionedItemsVisitor<'a, 'tcx> { struct MentionedItemsVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View file

@ -7,7 +7,7 @@ use rustc_middle::ty::TyCtxt;
use crate::simplify; use crate::simplify;
pub struct MultipleReturnTerminators; pub(super) struct MultipleReturnTerminators;
impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators { impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -30,7 +30,7 @@ use tracing::{debug, trace};
/// ///
/// [#47954]: https://github.com/rust-lang/rust/pull/47954 /// [#47954]: https://github.com/rust-lang/rust/pull/47954
/// [#71003]: https://github.com/rust-lang/rust/pull/71003 /// [#71003]: https://github.com/rust-lang/rust/pull/71003
pub struct RenameReturnPlace; pub(super) struct RenameReturnPlace;
impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace { impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -269,12 +269,7 @@ pub(super) fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when
validate::Validator { when, mir_phase: body.phase }.run_pass(tcx, body); validate::Validator { when, mir_phase: body.phase }.run_pass(tcx, body);
} }
pub(super) fn dump_mir_for_pass<'tcx>( fn dump_mir_for_pass<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, pass_name: &str, is_after: bool) {
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
pass_name: &str,
is_after: bool,
) {
mir::dump_mir( mir::dump_mir(
tcx, tcx,
true, true,

View file

@ -15,7 +15,7 @@ use rustc_session::Session;
/// ///
/// Thus after this pass, all the successors of a block are later than it in the /// Thus after this pass, all the successors of a block are later than it in the
/// `IndexVec`, unless that successor is a back-edge (such as from a loop). /// `IndexVec`, unless that successor is a back-edge (such as from a loop).
pub struct ReorderBasicBlocks; pub(super) struct ReorderBasicBlocks;
impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks { impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks {
fn is_enabled(&self, _session: &Session) -> bool { fn is_enabled(&self, _session: &Session) -> bool {
@ -43,7 +43,7 @@ impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks {
/// assigned or referenced will have a smaller number. /// assigned or referenced will have a smaller number.
/// ///
/// (Does not reorder arguments nor the [`RETURN_PLACE`].) /// (Does not reorder arguments nor the [`RETURN_PLACE`].)
pub struct ReorderLocals; pub(super) struct ReorderLocals;
impl<'tcx> crate::MirPass<'tcx> for ReorderLocals { impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
fn is_enabled(&self, _session: &Session) -> bool { fn is_enabled(&self, _session: &Session) -> bool {
@ -135,8 +135,8 @@ impl<'tcx> Visitor<'tcx> for LocalFinder {
} }
struct LocalUpdater<'tcx> { struct LocalUpdater<'tcx> {
pub map: IndexVec<Local, Local>, map: IndexVec<Local, Local>,
pub tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
} }
impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {

View file

@ -37,7 +37,7 @@ use tracing::{debug, instrument};
/// After this pass is run, `promoted_fragments` will hold the MIR body corresponding to each /// After this pass is run, `promoted_fragments` will hold the MIR body corresponding to each
/// newly created `Constant`. /// newly created `Constant`.
#[derive(Default)] #[derive(Default)]
pub struct PromoteTemps<'tcx> { pub(super) struct PromoteTemps<'tcx> {
pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>, pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
} }

View file

@ -70,7 +70,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
/// ///
/// For immutable borrows, we do not need to preserve such uniqueness property, /// For immutable borrows, we do not need to preserve such uniqueness property,
/// so we perform all the possible instantiations without removing the `_1 = &_2` statement. /// so we perform all the possible instantiations without removing the `_1 = &_2` statement.
pub struct ReferencePropagation; pub(super) struct ReferencePropagation;
impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation { impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -8,7 +8,7 @@ use tracing::debug;
/// A pass that removes noop landing pads and replaces jumps to them with /// A pass that removes noop landing pads and replaces jumps to them with
/// `UnwindAction::Continue`. This is important because otherwise LLVM generates /// `UnwindAction::Continue`. This is important because otherwise LLVM generates
/// terrible code for these. /// terrible code for these.
pub struct RemoveNoopLandingPads; pub(super) struct RemoveNoopLandingPads;
impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads { impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -4,7 +4,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use tracing::trace; use tracing::trace;
pub struct RemovePlaceMention; pub(super) struct RemovePlaceMention;
impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention { impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -4,7 +4,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use tracing::trace; use tracing::trace;
pub struct RemoveStorageMarkers; pub(super) struct RemoveStorageMarkers;
impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers { impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -14,7 +14,7 @@ use rustc_target::abi::FieldIdx;
/// like [#90770]. /// like [#90770].
/// ///
/// [#90770]: https://github.com/rust-lang/rust/issues/90770 /// [#90770]: https://github.com/rust-lang/rust/issues/90770
pub struct RemoveUninitDrops; pub(super) struct RemoveUninitDrops;
impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops { impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

View file

@ -10,7 +10,7 @@ use tracing::{debug, trace};
use super::simplify::simplify_cfg; use super::simplify::simplify_cfg;
pub struct RemoveUnneededDrops; pub(super) struct RemoveUnneededDrops;
impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops { impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

View file

@ -4,7 +4,7 @@ use rustc_middle::mir::visit::*;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct RemoveZsts; pub(super) struct RemoveZsts;
impl<'tcx> crate::MirPass<'tcx> for RemoveZsts { impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -1,7 +1,7 @@
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{traversal, Body, ConstOperand, Location}; use rustc_middle::mir::{traversal, Body, ConstOperand, Location};
pub struct RequiredConstsVisitor<'a, 'tcx> { pub(super) struct RequiredConstsVisitor<'a, 'tcx> {
required_consts: &'a mut Vec<ConstOperand<'tcx>>, required_consts: &'a mut Vec<ConstOperand<'tcx>>,
} }
@ -10,7 +10,7 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
RequiredConstsVisitor { required_consts } RequiredConstsVisitor { required_consts }
} }
pub fn compute_required_consts(body: &mut Body<'tcx>) { pub(super) fn compute_required_consts(body: &mut Body<'tcx>) {
let mut required_consts = Vec::new(); let mut required_consts = Vec::new();
let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts); let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts);
for (bb, bb_data) in traversal::reverse_postorder(&body) { for (bb, bb_data) in traversal::reverse_postorder(&body) {

View file

@ -4,7 +4,7 @@ use rustc_middle::mir::visit::*;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct RevealAll; pub(super) struct RevealAll;
impl<'tcx> crate::MirPass<'tcx> for RevealAll { impl<'tcx> crate::MirPass<'tcx> for RevealAll {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

View file

@ -26,7 +26,7 @@ use crate::{
mod async_destructor_ctor; mod async_destructor_ctor;
pub fn provide(providers: &mut Providers) { pub(super) fn provide(providers: &mut Providers) {
providers.mir_shims = make_shim; providers.mir_shims = make_shim;
} }
@ -331,7 +331,7 @@ fn new_body<'tcx>(
body body
} }
pub struct DropShimElaborator<'a, 'tcx> { pub(super) struct DropShimElaborator<'a, 'tcx> {
pub body: &'a Body<'tcx>, pub body: &'a Body<'tcx>,
pub patch: MirPatch<'tcx>, pub patch: MirPatch<'tcx>,
pub tcx: TyCtxt<'tcx>, pub tcx: TyCtxt<'tcx>,
@ -913,7 +913,7 @@ fn build_call_shim<'tcx>(
body body
} }
pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
debug_assert!(tcx.is_constructor(ctor_id)); debug_assert!(tcx.is_constructor(ctor_id));
let param_env = tcx.param_env_reveal_all_normalized(ctor_id); let param_env = tcx.param_env_reveal_all_normalized(ctor_id);

View file

@ -23,7 +23,7 @@ use tracing::debug;
use super::{local_decls_for_sig, new_body}; use super::{local_decls_for_sig, new_body};
pub fn build_async_destructor_ctor_shim<'tcx>( pub(super) fn build_async_destructor_ctor_shim<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
ty: Option<Ty<'tcx>>, ty: Option<Ty<'tcx>>,

View file

@ -35,7 +35,7 @@ use rustc_span::DUMMY_SP;
use smallvec::SmallVec; use smallvec::SmallVec;
use tracing::{debug, trace}; use tracing::{debug, trace};
pub enum SimplifyCfg { pub(super) enum SimplifyCfg {
Initial, Initial,
PromoteConsts, PromoteConsts,
RemoveFalseEdges, RemoveFalseEdges,
@ -50,7 +50,7 @@ pub enum SimplifyCfg {
} }
impl SimplifyCfg { impl SimplifyCfg {
pub fn name(&self) -> &'static str { fn name(&self) -> &'static str {
match self { match self {
SimplifyCfg::Initial => "SimplifyCfg-initial", SimplifyCfg::Initial => "SimplifyCfg-initial",
SimplifyCfg::PromoteConsts => "SimplifyCfg-promote-consts", SimplifyCfg::PromoteConsts => "SimplifyCfg-promote-consts",
@ -66,7 +66,7 @@ impl SimplifyCfg {
} }
} }
pub(crate) fn simplify_cfg(body: &mut Body<'_>) { pub(super) fn simplify_cfg(body: &mut Body<'_>) {
CfgSimplifier::new(body).simplify(); CfgSimplifier::new(body).simplify();
remove_dead_blocks(body); remove_dead_blocks(body);
@ -85,13 +85,13 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyCfg {
} }
} }
pub struct CfgSimplifier<'a, 'tcx> { struct CfgSimplifier<'a, 'tcx> {
basic_blocks: &'a mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>, basic_blocks: &'a mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
pred_count: IndexVec<BasicBlock, u32>, pred_count: IndexVec<BasicBlock, u32>,
} }
impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
pub fn new(body: &'a mut Body<'tcx>) -> Self { fn new(body: &'a mut Body<'tcx>) -> Self {
let mut pred_count = IndexVec::from_elem(0u32, &body.basic_blocks); let mut pred_count = IndexVec::from_elem(0u32, &body.basic_blocks);
// we can't use mir.predecessors() here because that counts // we can't use mir.predecessors() here because that counts
@ -111,7 +111,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
CfgSimplifier { basic_blocks, pred_count } CfgSimplifier { basic_blocks, pred_count }
} }
pub fn simplify(mut self) { fn simplify(mut self) {
self.strip_nops(); self.strip_nops();
// Vec of the blocks that should be merged. We store the indices here, instead of the // Vec of the blocks that should be merged. We store the indices here, instead of the
@ -280,7 +280,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
} }
} }
pub fn simplify_duplicate_switch_targets(terminator: &mut Terminator<'_>) { pub(super) fn simplify_duplicate_switch_targets(terminator: &mut Terminator<'_>) {
if let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind { if let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind {
let otherwise = targets.otherwise(); let otherwise = targets.otherwise();
if targets.iter().any(|t| t.1 == otherwise) { if targets.iter().any(|t| t.1 == otherwise) {
@ -292,7 +292,7 @@ pub fn simplify_duplicate_switch_targets(terminator: &mut Terminator<'_>) {
} }
} }
pub(crate) fn remove_dead_blocks(body: &mut Body<'_>) { pub(super) fn remove_dead_blocks(body: &mut Body<'_>) {
let should_deduplicate_unreachable = |bbdata: &BasicBlockData<'_>| { let should_deduplicate_unreachable = |bbdata: &BasicBlockData<'_>| {
// CfgSimplifier::simplify leaves behind some unreachable basic blocks without a // CfgSimplifier::simplify leaves behind some unreachable basic blocks without a
// terminator. Those blocks will be deleted by remove_dead_blocks, but we run just // terminator. Those blocks will be deleted by remove_dead_blocks, but we run just
@ -360,7 +360,7 @@ pub(crate) fn remove_dead_blocks(body: &mut Body<'_>) {
} }
} }
pub enum SimplifyLocals { pub(super) enum SimplifyLocals {
BeforeConstProp, BeforeConstProp,
AfterGVN, AfterGVN,
Final, Final,
@ -385,7 +385,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
} }
} }
pub fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) { pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) {
// First, we're going to get a count of *actual* uses for every `Local`. // First, we're going to get a count of *actual* uses for every `Local`.
let mut used_locals = UsedLocals::new(body); let mut used_locals = UsedLocals::new(body);
@ -397,7 +397,7 @@ pub fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) {
remove_unused_definitions_helper(&mut used_locals, body); remove_unused_definitions_helper(&mut used_locals, body);
} }
pub fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) { fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
// First, we're going to get a count of *actual* uses for every `Local`. // First, we're going to get a count of *actual* uses for every `Local`.
let mut used_locals = UsedLocals::new(body); let mut used_locals = UsedLocals::new(body);

View file

@ -2,10 +2,11 @@ use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use tracing::trace; use tracing::trace;
pub enum SimplifyConstCondition { pub(super) enum SimplifyConstCondition {
AfterConstProp, AfterConstProp,
Final, Final,
} }
/// A pass that replaces a branch with a goto when its condition is known. /// A pass that replaces a branch with a goto when its condition is known.
impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition { impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
fn name(&self) -> &'static str { fn name(&self) -> &'static str {

View file

@ -23,7 +23,7 @@ use tracing::trace;
/// ```ignore (MIR) /// ```ignore (MIR)
/// switchInt(_4) -> [43i32: bb3, otherwise: bb2]; /// switchInt(_4) -> [43i32: bb3, otherwise: bb2];
/// ``` /// ```
pub struct SimplifyComparisonIntegral; pub(super) struct SimplifyComparisonIntegral;
impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -19,7 +19,7 @@ use rustc_middle::ty::TyCtxt;
/// ///
/// It also removes *never*-used constants, since it had all the information /// It also removes *never*-used constants, since it had all the information
/// needed to do that too, including updating the debug info. /// needed to do that too, including updating the debug info.
pub struct SingleUseConsts; pub(super) struct SingleUseConsts;
impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts { impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -11,7 +11,7 @@ use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields};
use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use tracing::{debug, instrument}; use tracing::{debug, instrument};
pub struct ScalarReplacementOfAggregates; pub(super) struct ScalarReplacementOfAggregates;
impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates { impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -16,7 +16,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_middle::ty::{ParamEnv, TyCtxt};
use tracing::{debug, instrument, trace}; use tracing::{debug, instrument, trace};
pub struct SsaLocals { pub(super) struct SsaLocals {
/// Assignments to each local. This defines whether the local is SSA. /// Assignments to each local. This defines whether the local is SSA.
assignments: IndexVec<Local, Set1<DefLocation>>, assignments: IndexVec<Local, Set1<DefLocation>>,
/// We visit the body in reverse postorder, to ensure each local is assigned before it is used. /// We visit the body in reverse postorder, to ensure each local is assigned before it is used.
@ -32,14 +32,18 @@ pub struct SsaLocals {
borrowed_locals: BitSet<Local>, borrowed_locals: BitSet<Local>,
} }
pub enum AssignedValue<'a, 'tcx> { pub(super) enum AssignedValue<'a, 'tcx> {
Arg, Arg,
Rvalue(&'a mut Rvalue<'tcx>), Rvalue(&'a mut Rvalue<'tcx>),
Terminator, Terminator,
} }
impl SsaLocals { impl SsaLocals {
pub fn new<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ParamEnv<'tcx>) -> SsaLocals { pub(super) fn new<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
param_env: ParamEnv<'tcx>,
) -> SsaLocals {
let assignment_order = Vec::with_capacity(body.local_decls.len()); let assignment_order = Vec::with_capacity(body.local_decls.len());
let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls); let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
@ -101,25 +105,25 @@ impl SsaLocals {
ssa ssa
} }
pub fn num_locals(&self) -> usize { pub(super) fn num_locals(&self) -> usize {
self.assignments.len() self.assignments.len()
} }
pub fn locals(&self) -> impl Iterator<Item = Local> { pub(super) fn locals(&self) -> impl Iterator<Item = Local> {
self.assignments.indices() self.assignments.indices()
} }
pub fn is_ssa(&self, local: Local) -> bool { pub(super) fn is_ssa(&self, local: Local) -> bool {
matches!(self.assignments[local], Set1::One(_)) matches!(self.assignments[local], Set1::One(_))
} }
/// Return the number of uses if a local that are not "Deref". /// Return the number of uses if a local that are not "Deref".
pub fn num_direct_uses(&self, local: Local) -> u32 { pub(super) fn num_direct_uses(&self, local: Local) -> u32 {
self.direct_uses[local] self.direct_uses[local]
} }
#[inline] #[inline]
pub fn assignment_dominates( pub(super) fn assignment_dominates(
&self, &self,
dominators: &Dominators<BasicBlock>, dominators: &Dominators<BasicBlock>,
local: Local, local: Local,
@ -131,7 +135,7 @@ impl SsaLocals {
} }
} }
pub fn assignments<'a, 'tcx>( pub(super) fn assignments<'a, 'tcx>(
&'a self, &'a self,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a { ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a {
@ -148,7 +152,7 @@ impl SsaLocals {
}) })
} }
pub fn for_each_assignment_mut<'tcx>( pub(super) fn for_each_assignment_mut<'tcx>(
&self, &self,
basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>, basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
mut f: impl FnMut(Local, AssignedValue<'_, 'tcx>, Location), mut f: impl FnMut(Local, AssignedValue<'_, 'tcx>, Location),
@ -194,17 +198,17 @@ impl SsaLocals {
/// _d => _a // transitively through _c /// _d => _a // transitively through _c
/// ///
/// Exception: we do not see through the return place, as it cannot be instantiated. /// Exception: we do not see through the return place, as it cannot be instantiated.
pub fn copy_classes(&self) -> &IndexSlice<Local, Local> { pub(super) fn copy_classes(&self) -> &IndexSlice<Local, Local> {
&self.copy_classes &self.copy_classes
} }
/// Set of SSA locals that are immutably borrowed. /// Set of SSA locals that are immutably borrowed.
pub fn borrowed_locals(&self) -> &BitSet<Local> { pub(super) fn borrowed_locals(&self) -> &BitSet<Local> {
&self.borrowed_locals &self.borrowed_locals
} }
/// Make a property uniform on a copy equivalence class by removing elements. /// Make a property uniform on a copy equivalence class by removing elements.
pub fn meet_copy_equivalence(&self, property: &mut BitSet<Local>) { pub(super) fn meet_copy_equivalence(&self, property: &mut BitSet<Local>) {
// Consolidate to have a local iff all its copies are. // Consolidate to have a local iff all its copies are.
// //
// `copy_classes` defines equivalence classes between locals. The `local`s that recursively // `copy_classes` defines equivalence classes between locals. The `local`s that recursively

View file

@ -12,7 +12,7 @@ use rustc_middle::ty::{Ty, TyCtxt};
use rustc_target::abi::{Abi, Variants}; use rustc_target::abi::{Abi, Variants};
use tracing::trace; use tracing::trace;
pub struct UnreachableEnumBranching; pub(super) struct UnreachableEnumBranching;
fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> { fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
if let TerminatorKind::SwitchInt { discr: Operand::Move(p), .. } = terminator { if let TerminatorKind::SwitchInt { discr: Operand::Move(p), .. } = terminator {

View file

@ -10,7 +10,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_target::abi::Size; use rustc_target::abi::Size;
pub struct UnreachablePropagation; pub(super) struct UnreachablePropagation;
impl crate::MirPass<'_> for UnreachablePropagation { impl crate::MirPass<'_> for UnreachablePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool { fn is_enabled(&self, sess: &rustc_session::Session) -> bool {

View file

@ -26,7 +26,7 @@ enum EdgeKind {
Normal, Normal,
} }
pub struct Validator { pub(super) struct Validator {
/// Describes at which point in the pipeline this validation is happening. /// Describes at which point in the pipeline this validation is happening.
pub when: String, pub when: String,
/// The phase for which we are upholding the dialect. If the given phase forbids a specific /// The phase for which we are upholding the dialect. If the given phase forbids a specific
@ -531,7 +531,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
/// ///
/// `caller_body` is used to detect cycles in MIR inlining and MIR validation before /// `caller_body` is used to detect cycles in MIR inlining and MIR validation before
/// `optimized_mir` is available. /// `optimized_mir` is available.
pub fn validate_types<'tcx>( pub(super) fn validate_types<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
mir_phase: MirPhase, mir_phase: MirPhase,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,

View file

@ -625,11 +625,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if let ObligationCauseCode::WhereClause(_, span) if let ObligationCauseCode::WhereClause(_, span)
| ObligationCauseCode::WhereClauseInExpr(_, span, ..) = | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
&trace.cause.code().peel_derives() &trace.cause.code().peel_derives()
&& !span.is_dummy()
{ {
let span = *span; let span = *span;
self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup) let mut err = self.report_concrete_failure(
.with_span_note(span, "the lifetime requirement is introduced here") generic_param_scope,
placeholder_origin,
sub,
sup,
);
if !span.is_dummy() {
err =
err.with_span_note(span, "the lifetime requirement is introduced here");
}
err
} else { } else {
unreachable!( unreachable!(
"control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."

View file

@ -641,7 +641,7 @@
#stack-protector = "none" #stack-protector = "none"
# Prints each test name as it is executed, to help debug issues in the test harness itself. # Prints each test name as it is executed, to help debug issues in the test harness itself.
#verbose-tests = false #verbose-tests = if is_verbose { true } else { false }
# Flag indicating whether tests are compiled with optimizations (the -O flag). # Flag indicating whether tests are compiled with optimizations (the -O flag).
#optimize-tests = true #optimize-tests = true

View file

@ -15,7 +15,6 @@ impl char {
/// for you: /// for you:
/// ///
/// ``` /// ```
/// #![feature(char_min)]
/// let dist = u32::from(char::MAX) - u32::from(char::MIN); /// let dist = u32::from(char::MAX) - u32::from(char::MIN);
/// let size = (char::MIN..=char::MAX).count() as u32; /// let size = (char::MIN..=char::MAX).count() as u32;
/// assert!(size < dist); /// assert!(size < dist);
@ -29,7 +28,6 @@ impl char {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(char_min)]
/// # fn something_which_returns_char() -> char { 'a' } /// # fn something_which_returns_char() -> char { 'a' }
/// let c: char = something_which_returns_char(); /// let c: char = something_which_returns_char();
/// assert!(char::MIN <= c); /// assert!(char::MIN <= c);
@ -37,7 +35,7 @@ impl char {
/// let value_at_min = u32::from(char::MIN); /// let value_at_min = u32::from(char::MIN);
/// assert_eq!(char::from_u32(value_at_min), Some('\0')); /// assert_eq!(char::from_u32(value_at_min), Some('\0'));
/// ``` /// ```
#[unstable(feature = "char_min", issue = "114298")] #[stable(feature = "char_min", since = "CURRENT_RUSTC_VERSION")]
pub const MIN: char = '\0'; pub const MIN: char = '\0';
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`. /// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
@ -48,7 +46,6 @@ impl char {
/// for you: /// for you:
/// ///
/// ``` /// ```
/// #![feature(char_min)]
/// let dist = u32::from(char::MAX) - u32::from(char::MIN); /// let dist = u32::from(char::MAX) - u32::from(char::MIN);
/// let size = (char::MIN..=char::MAX).count() as u32; /// let size = (char::MIN..=char::MAX).count() as u32;
/// assert!(size < dist); /// assert!(size < dist);

View file

@ -1,7 +1,5 @@
use rand::RngCore; use rand::RngCore;
#[cfg(target_os = "macos")]
use crate::ffi::{c_char, c_int};
use crate::fs::{self, File, FileTimes, OpenOptions}; use crate::fs::{self, File, FileTimes, OpenOptions};
use crate::io::prelude::*; use crate::io::prelude::*;
use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom};
@ -16,8 +14,6 @@ use crate::os::unix::fs::symlink as junction_point;
use crate::os::windows::fs::{junction_point, symlink_dir, symlink_file, OpenOptionsExt}; use crate::os::windows::fs::{junction_point, symlink_dir, symlink_file, OpenOptionsExt};
use crate::path::Path; use crate::path::Path;
use crate::sync::Arc; use crate::sync::Arc;
#[cfg(target_os = "macos")]
use crate::sys::weak::weak;
use crate::sys_common::io::test::{tmpdir, TempDir}; use crate::sys_common::io::test::{tmpdir, TempDir};
use crate::time::{Duration, Instant, SystemTime}; use crate::time::{Duration, Instant, SystemTime};
use crate::{env, str, thread}; use crate::{env, str, thread};
@ -80,17 +76,6 @@ pub fn got_symlink_permission(tmpdir: &TempDir) -> bool {
} }
} }
#[cfg(target_os = "macos")]
fn able_to_not_follow_symlinks_while_hard_linking() -> bool {
weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
linkat.get().is_some()
}
#[cfg(not(target_os = "macos"))]
fn able_to_not_follow_symlinks_while_hard_linking() -> bool {
return true;
}
#[test] #[test]
fn file_test_io_smoke_test() { fn file_test_io_smoke_test() {
let message = "it's alright. have a good time"; let message = "it's alright. have a good time";
@ -1456,9 +1441,6 @@ fn symlink_hard_link() {
if !got_symlink_permission(&tmpdir) { if !got_symlink_permission(&tmpdir) {
return; return;
}; };
if !able_to_not_follow_symlinks_while_hard_linking() {
return;
}
// Create "file", a file. // Create "file", a file.
check!(fs::File::create(tmpdir.join("file"))); check!(fs::File::create(tmpdir.join("file")));

View file

@ -1600,6 +1600,9 @@ impl Config {
config.verbose = cmp::max(config.verbose, flags.verbose as usize); config.verbose = cmp::max(config.verbose, flags.verbose as usize);
// Verbose flag is a good default for `rust.verbose-tests`.
config.verbose_tests = config.is_verbose();
if let Some(install) = toml.install { if let Some(install) = toml.install {
let Install { prefix, sysconfdir, docdir, bindir, libdir, mandir, datadir } = install; let Install { prefix, sysconfdir, docdir, bindir, libdir, mandir, datadir } = install;
config.prefix = prefix.map(PathBuf::from); config.prefix = prefix.map(PathBuf::from);

View file

@ -317,3 +317,12 @@ fn order_of_clippy_rules() {
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
#[test]
fn verbose_tests_default_value() {
let config = Config::parse(Flags::parse(&["build".into(), "compiler".into()]));
assert_eq!(config.verbose_tests, false);
let config = Config::parse(Flags::parse(&["build".into(), "compiler".into(), "-v".into()]));
assert_eq!(config.verbose_tests, true);
}

View file

@ -88,6 +88,9 @@ struct Renderer<'a> {
builder: &'a Builder<'a>, builder: &'a Builder<'a>,
tests_count: Option<usize>, tests_count: Option<usize>,
executed_tests: usize, executed_tests: usize,
/// Number of tests that were skipped due to already being up-to-date
/// (i.e. no relevant changes occurred since they last ran).
up_to_date_tests: usize,
terse_tests_in_line: usize, terse_tests_in_line: usize,
} }
@ -100,6 +103,7 @@ impl<'a> Renderer<'a> {
builder, builder,
tests_count: None, tests_count: None,
executed_tests: 0, executed_tests: 0,
up_to_date_tests: 0,
terse_tests_in_line: 0, terse_tests_in_line: 0,
} }
} }
@ -127,6 +131,12 @@ impl<'a> Renderer<'a> {
} }
} }
} }
if self.up_to_date_tests > 0 {
let n = self.up_to_date_tests;
let s = if n > 1 { "s" } else { "" };
println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n");
}
} }
/// Renders the stdout characters one by one /// Renders the stdout characters one by one
@ -149,6 +159,11 @@ impl<'a> Renderer<'a> {
fn render_test_outcome(&mut self, outcome: Outcome<'_>, test: &TestOutcome) { fn render_test_outcome(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
self.executed_tests += 1; self.executed_tests += 1;
// Keep this in sync with the "up-to-date" ignore message inserted by compiletest.
if let Outcome::Ignored { reason: Some("up-to-date") } = outcome {
self.up_to_date_tests += 1;
}
#[cfg(feature = "build-metrics")] #[cfg(feature = "build-metrics")]
self.builder.metrics.record_test( self.builder.metrics.record_test(
&test.name, &test.name,

@ -1 +1 @@
Subproject commit eeba2cb9c37ab74118a4fb5e5233f7397e4a91f8 Subproject commit b3ca7ade0f87d7e3fb538776defc5b2cc4188172

@ -1 +1 @@
Subproject commit ff5d61d56f11e1986bfa9652c6aff7731576c37d Subproject commit dbae36bf3f8410aa4313b3bad42e374735d48a9d

@ -1 +1 @@
Subproject commit 0668397076da350c404dadcf07b6cbc433ad3743 Subproject commit 687faf9958c52116d003b41dfd29cc1cf44f5311

@ -1 +1 @@
Subproject commit 859786c5bc99301bbc22fc631a5c2b341860da08 Subproject commit c79ec345f08a1e94494cdc8c999709a90203fd88

@ -1 +1 @@
Subproject commit fa928a6d19e1666d8d811dfe3fd35cdad3b4e459 Subproject commit 0ed9229f5b6f7824b333beabd7e3d5ba4b9bd971

Some files were not shown because too many files have changed in this diff Show more