mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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:
commit
c2f74c3f92
@ -8,7 +8,7 @@ use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
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> {
|
||||
self.infcx.dcx()
|
||||
}
|
||||
|
@ -15,24 +15,24 @@ use tracing::debug;
|
||||
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
|
||||
|
||||
/// The results of the dataflow analyses used by the borrow checker.
|
||||
pub(crate) struct BorrowckResults<'a, 'mir, 'tcx> {
|
||||
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
|
||||
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
pub(crate) struct BorrowckResults<'a, 'tcx> {
|
||||
pub(crate) borrows: Results<'tcx, Borrows<'a, 'tcx>>,
|
||||
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
|
||||
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'tcx>>,
|
||||
}
|
||||
|
||||
/// The transient state of the dataflow analyses used by the borrow checker.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct BorrowckFlowState<'a, 'mir, 'tcx> {
|
||||
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
pub(crate) struct BorrowckFlowState<'a, 'tcx> {
|
||||
pub(crate) borrows: <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
pub(crate) uninits: <MaybeUninitializedPlaces<'a, '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.
|
||||
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
|
||||
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;
|
||||
type Direction = <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Direction;
|
||||
type FlowState = BorrowckFlowState<'a, 'tcx>;
|
||||
|
||||
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
|
||||
BorrowckFlowState {
|
||||
@ -106,10 +106,9 @@ rustc_index::newtype_index! {
|
||||
/// `BorrowIndex`, and maps each such index to a `BorrowData`
|
||||
/// describing the borrow. These indexes are used for representing the
|
||||
/// borrows in compact bitvectors.
|
||||
pub struct Borrows<'a, 'mir, 'tcx> {
|
||||
pub struct Borrows<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
|
||||
body: &'a Body<'tcx>,
|
||||
borrow_set: &'a BorrowSet<'tcx>,
|
||||
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(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
borrow_set: &'a BorrowSet<'tcx>,
|
||||
) -> 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>;
|
||||
|
||||
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.
|
||||
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
|
||||
/// `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;
|
||||
|
||||
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 {
|
||||
fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl DebugWithContext<Borrows<'_, '_>> for BorrowIndex {
|
||||
fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", ctxt.location(*self))
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> {
|
||||
|
||||
pub(crate) fn report_error(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
error_element: RegionElement,
|
||||
cause: ObligationCause<'tcx>,
|
||||
@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> {
|
||||
#[instrument(level = "debug", skip(self, mbcx))]
|
||||
fn report_error(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
error_element: RegionElement,
|
||||
cause: ObligationCause<'tcx>,
|
||||
@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -277,7 +277,7 @@ where
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -324,7 +324,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: 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>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
_cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
|
@ -69,7 +69,7 @@ enum StorageDeadOrDrop<'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(
|
||||
&mut self,
|
||||
location: Location,
|
||||
@ -4358,11 +4358,7 @@ enum AnnotatedBorrowFnSignature<'tcx> {
|
||||
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
||||
/// Annotate the provided diagnostic with information about borrow from the fn signature that
|
||||
/// helps explain.
|
||||
pub(crate) fn emit(
|
||||
&self,
|
||||
cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>,
|
||||
diag: &mut Diag<'_>,
|
||||
) -> String {
|
||||
pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, '_, 'tcx>, diag: &mut Diag<'_>) -> String {
|
||||
match self {
|
||||
&AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
|
||||
diag.span_label(
|
||||
|
@ -390,7 +390,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||
fn free_region_constraint_info(
|
||||
&self,
|
||||
borrow_region: RegionVid,
|
||||
|
@ -68,7 +68,7 @@ pub(super) struct DescribePlaceOpt {
|
||||
|
||||
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
|
||||
/// is moved after being invoked.
|
||||
///
|
||||
@ -772,7 +772,7 @@ struct CapturedMessageOpt {
|
||||
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.
|
||||
pub(super) fn move_spans(
|
||||
&self,
|
||||
|
@ -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) {
|
||||
let grouped_errors = self.group_move_errors();
|
||||
for error in grouped_errors {
|
||||
|
@ -32,7 +32,7 @@ pub(crate) enum AccessKind {
|
||||
Mutate,
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn report_mutability_error(
|
||||
&mut self,
|
||||
access_place: Place<'tcx>,
|
||||
|
@ -76,7 +76,7 @@ impl OutlivesSuggestionBuilder {
|
||||
/// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`.
|
||||
fn region_vid_to_name(
|
||||
&self,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_>,
|
||||
region: RegionVid,
|
||||
) -> Option<RegionName> {
|
||||
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.
|
||||
fn compile_all_suggestions(
|
||||
&self,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_>,
|
||||
) -> SmallVec<[SuggestedConstraint; 2]> {
|
||||
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.
|
||||
pub(crate) fn intermediate_suggestion(
|
||||
&mut self,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_>,
|
||||
errci: &ErrorConstraintInfo<'_>,
|
||||
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
|
||||
/// 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.
|
||||
if self.constraints_to_add.is_empty() {
|
||||
debug!("No constraints to suggest.");
|
||||
|
@ -156,7 +156,7 @@ pub(crate) struct ErrorConstraintInfo<'tcx> {
|
||||
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
|
||||
/// 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
|
||||
|
@ -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 {
|
||||
self.body.source.def_id().expect_local()
|
||||
}
|
||||
|
@ -304,11 +304,11 @@ fn do_mir_borrowck<'tcx>(
|
||||
promoted_mbcx.report_move_errors();
|
||||
diags = promoted_mbcx.diags;
|
||||
|
||||
struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> {
|
||||
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>,
|
||||
struct MoveVisitor<'a, 'b, '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) {
|
||||
if let Operand::Move(place) = operand {
|
||||
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>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
|
||||
/// 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
|
||||
// 3. assignments do not affect things loaned out as immutable
|
||||
// 4. moves do not affect things loaned out in any way
|
||||
impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||
for MirBorrowckCtxt<'a, 'mir, '_, 'tcx>
|
||||
impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
|
||||
for MirBorrowckCtxt<'a, '_, 'tcx>
|
||||
{
|
||||
type FlowState = Flows<'a, 'mir, 'tcx>;
|
||||
type FlowState = Flows<'a, 'tcx>;
|
||||
|
||||
fn visit_statement_before_primary_effect(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
stmt: &'mir Statement<'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
stmt: &'a Statement<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
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(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
term: &'mir Terminator<'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
term: &'a Terminator<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
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(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
term: &'mir Terminator<'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
term: &'a Terminator<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
let span = term.source_info.span;
|
||||
@ -972,8 +972,8 @@ impl InitializationRequiringAction {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
fn body(&self) -> &'mir Body<'tcx> {
|
||||
impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
fn body(&self) -> &'a Body<'tcx> {
|
||||
self.body
|
||||
}
|
||||
|
||||
@ -989,7 +989,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
place_span: (Place<'tcx>, Span),
|
||||
kind: (AccessDepth, ReadOrWrite),
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
let (sd, rw) = kind;
|
||||
|
||||
@ -1039,7 +1039,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
place_span: (Place<'tcx>, Span),
|
||||
sd: AccessDepth,
|
||||
rw: ReadOrWrite,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) -> bool {
|
||||
let mut error_reported = false;
|
||||
let borrow_set = Rc::clone(&self.borrow_set);
|
||||
@ -1180,7 +1180,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
location: Location,
|
||||
place_span: (Place<'tcx>, Span),
|
||||
kind: AccessDepth,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
// Write of P[i] or *P requires P init'd.
|
||||
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(
|
||||
&mut self,
|
||||
location: Location,
|
||||
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
(rvalue, span): (&'a Rvalue<'tcx>, Span),
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
match rvalue {
|
||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||
@ -1455,8 +1455,8 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
fn consume_operand(
|
||||
&mut self,
|
||||
location: Location,
|
||||
(operand, span): (&'mir Operand<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
(operand, span): (&'a Operand<'tcx>, Span),
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
match *operand {
|
||||
Operand::Copy(place) => {
|
||||
@ -1576,12 +1576,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_activations(
|
||||
&mut self,
|
||||
location: Location,
|
||||
span: Span,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
) {
|
||||
fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'a, 'tcx>) {
|
||||
// Two-phase borrow support: For each activation that is newly
|
||||
// generated at this statement, check if it interferes with
|
||||
// another borrow.
|
||||
@ -1744,7 +1739,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
location: Location,
|
||||
desired_action: InitializationRequiringAction,
|
||||
place_span: (PlaceRef<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
let maybe_uninits = &flow_state.uninits;
|
||||
|
||||
@ -1849,7 +1844,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
location: Location,
|
||||
desired_action: InitializationRequiringAction,
|
||||
place_span: (PlaceRef<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
let maybe_uninits = &flow_state.uninits;
|
||||
|
||||
@ -1948,7 +1943,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
&mut self,
|
||||
location: Location,
|
||||
(place, span): (Place<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
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>(
|
||||
this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>,
|
||||
fn check_parent_of_field<'a, 'tcx>(
|
||||
this: &mut MirBorrowckCtxt<'a, '_, 'tcx>,
|
||||
location: Location,
|
||||
base: PlaceRef<'tcx>,
|
||||
span: Span,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
// rust-lang/rust#21232: Until Rust allows reads from the
|
||||
// initialized parts of partially initialized structs, we
|
||||
@ -2105,7 +2100,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
(place, span): (Place<'tcx>, Span),
|
||||
kind: ReadOrWrite,
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
location: Location,
|
||||
) -> bool {
|
||||
debug!(
|
||||
@ -2221,7 +2216,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
fn is_local_ever_initialized(
|
||||
&self,
|
||||
local: Local,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) -> Option<InitIndex> {
|
||||
let mpi = self.move_data.rev_lookup.find_local(local)?;
|
||||
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
|
||||
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 {
|
||||
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
|
||||
// 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>) {
|
||||
self.diags.buffer_error(diag);
|
||||
}
|
||||
|
@ -75,14 +75,14 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
|
||||
/// Computes the (non-lexical) regions from the input MIR.
|
||||
///
|
||||
/// This may result in errors being reported.
|
||||
pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
pub(crate) fn compute_regions<'a, 'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
universal_regions: UniversalRegions<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
||||
location_table: &LocationTable,
|
||||
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>,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||
@ -301,13 +301,13 @@ pub(super) fn dump_nll_mir<'tcx>(
|
||||
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
pub(super) fn dump_annotation<'tcx, 'cx>(
|
||||
infcx: &'cx BorrowckInferCtxt<'tcx>,
|
||||
pub(super) fn dump_annotation<'tcx, 'infcx>(
|
||||
infcx: &'infcx BorrowckInferCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'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 base_def_id = tcx.typeck_root_def_id(body.source.def_id());
|
||||
|
@ -34,7 +34,7 @@ pub(super) enum PrefixSet {
|
||||
Shallow,
|
||||
}
|
||||
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||
/// Returns an iterator over the prefixes of `place`
|
||||
/// (inclusive) from longest to smallest, potentially
|
||||
/// terminating the iteration early based on `kind`.
|
||||
|
@ -30,11 +30,11 @@ mod trace;
|
||||
///
|
||||
/// N.B., this computation requires normalization; therefore, it must be
|
||||
/// performed before
|
||||
pub(super) fn generate<'mir, 'tcx>(
|
||||
pub(super) fn generate<'a, 'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
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>,
|
||||
) {
|
||||
debug!("liveness::generate");
|
||||
|
@ -37,11 +37,11 @@ use crate::type_check::{NormalizeLocation, TypeChecker};
|
||||
/// DROP-LIVE set are to the liveness sets for regions found in the
|
||||
/// `dropck_outlives` result of the variable's type (in particular,
|
||||
/// this respects `#[may_dangle]` annotations).
|
||||
pub(super) fn trace<'mir, 'tcx>(
|
||||
pub(super) fn trace<'a, 'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
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>,
|
||||
relevant_live_locals: Vec<Local>,
|
||||
boring_locals: Vec<Local>,
|
||||
@ -99,29 +99,29 @@ pub(super) fn trace<'mir, 'tcx>(
|
||||
}
|
||||
|
||||
/// 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.
|
||||
typeck: &'me mut TypeChecker<'typeck, 'tcx>,
|
||||
typeck: &'a mut TypeChecker<'typeck, 'tcx>,
|
||||
|
||||
/// Defines the `PointIndex` mapping
|
||||
elements: &'me DenseLocationMap,
|
||||
elements: &'a DenseLocationMap,
|
||||
|
||||
/// MIR we are analyzing.
|
||||
body: &'me Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
|
||||
/// 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.
|
||||
drop_data: FxIndexMap<Ty<'tcx>, DropData<'tcx>>,
|
||||
|
||||
/// Results of dataflow tracking which variables (and paths) have been
|
||||
/// 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
|
||||
/// dropped.
|
||||
local_use_map: &'me LocalUseMap,
|
||||
local_use_map: &'a LocalUseMap,
|
||||
}
|
||||
|
||||
struct DropData<'tcx> {
|
||||
@ -129,8 +129,8 @@ struct DropData<'tcx> {
|
||||
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
|
||||
}
|
||||
|
||||
struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>,
|
||||
struct LivenessResults<'a, 'typeck, 'b, 'tcx> {
|
||||
cx: LivenessContext<'a, 'typeck, 'b, 'tcx>,
|
||||
|
||||
/// Set of points that define the current local.
|
||||
defs: BitSet<PointIndex>,
|
||||
@ -151,8 +151,8 @@ struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
stack: Vec<PointIndex>,
|
||||
}
|
||||
|
||||
impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self {
|
||||
impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
|
||||
fn new(cx: LivenessContext<'a, 'typeck, 'b, 'tcx>) -> Self {
|
||||
let num_points = cx.elements.num_points();
|
||||
LivenessResults {
|
||||
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
|
||||
/// cursor position. Callers should call one of the `seek` methods immediately before to point
|
||||
/// the cursor to the desired location.
|
||||
|
@ -116,7 +116,7 @@ mod relate_tys;
|
||||
/// - `flow_inits` -- results of a maybe-init dataflow analysis
|
||||
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
|
||||
/// - `elements` -- MIR region map
|
||||
pub(crate) fn type_check<'mir, 'tcx>(
|
||||
pub(crate) fn type_check<'a, 'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
@ -125,7 +125,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
location_table: &LocationTable,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
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>,
|
||||
elements: &Rc<DenseLocationMap>,
|
||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||
|
@ -423,8 +423,8 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
struct UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
infcx: &'cx BorrowckInferCtxt<'tcx>,
|
||||
struct UniversalRegionsBuilder<'infcx, 'tcx> {
|
||||
infcx: &'infcx BorrowckInferCtxt<'tcx>,
|
||||
mir_def: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use tracing::debug;
|
||||
|
||||
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
|
||||
/// of the `unused_mut` lint.
|
||||
///
|
||||
@ -46,13 +46,13 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
|
||||
/// MIR visitor for collecting used mutable variables.
|
||||
/// 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>,
|
||||
never_initialized_mut_locals: &'visit mut FxIndexSet<Local>,
|
||||
mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx>,
|
||||
never_initialized_mut_locals: &'a mut FxIndexSet<Local>,
|
||||
mbcx: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> {
|
||||
impl GatherUsedMutsVisitor<'_, '_, '_, '_> {
|
||||
fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
|
||||
// Remove any locals that we found were initialized from the
|
||||
// `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) {
|
||||
debug!("visit_terminator: terminator={:?}", terminator);
|
||||
match &terminator.kind {
|
||||
|
@ -72,8 +72,11 @@ fn is_valid_cmse_inputs<'tcx>(
|
||||
let mut span = None;
|
||||
let mut accum = 0u64;
|
||||
|
||||
for (index, arg_def) in fn_sig.inputs().iter().enumerate() {
|
||||
let layout = tcx.layout_of(ParamEnv::reveal_all().and(*arg_def.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);
|
||||
|
||||
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 size = layout.layout.size().bytes();
|
||||
@ -98,7 +101,10 @@ fn is_valid_cmse_output<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fn_sig: ty::PolyFnSig<'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 size = layout.layout.size().bytes();
|
||||
|
||||
|
@ -51,15 +51,15 @@ use crate::{
|
||||
/// Similarly, at a given `drop` statement, the set-intersection
|
||||
/// between this data and `MaybeUninitializedPlaces` yields the set of
|
||||
/// 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>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
skip_unreachable_unwind: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
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 }
|
||||
}
|
||||
|
||||
@ -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> {
|
||||
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
|
||||
/// between this data and `MaybeInitializedPlaces` yields the set of
|
||||
/// 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>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
|
||||
mark_inactive_variants_as_uninit: bool,
|
||||
skip_unreachable_unwind: BitSet<mir::BasicBlock>,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
MaybeUninitializedPlaces {
|
||||
tcx,
|
||||
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> {
|
||||
self.move_data
|
||||
}
|
||||
@ -251,24 +251,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
|
||||
/// c = S; // {a, b, c, d }
|
||||
/// }
|
||||
/// ```
|
||||
pub struct EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
body: &'mir Body<'tcx>,
|
||||
pub struct EverInitializedPlaces<'a, 'tcx> {
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
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> {
|
||||
self.move_data
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
fn update_bits(
|
||||
trans: &mut impl GenKill<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(
|
||||
trans: &mut impl GenKill<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.
|
||||
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||
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;
|
||||
|
||||
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.
|
||||
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||
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;
|
||||
|
||||
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.
|
||||
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||
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;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
|
@ -16,6 +16,7 @@ use super::{
|
||||
|
||||
struct MoveDataBuilder<'a, 'tcx, F> {
|
||||
body: &'a Body<'tcx>,
|
||||
loc: Location,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
data: MoveData<'tcx>,
|
||||
@ -56,6 +57,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
|
||||
|
||||
MoveDataBuilder {
|
||||
body,
|
||||
loc: Location::START,
|
||||
tcx,
|
||||
param_env,
|
||||
data: MoveData {
|
||||
@ -107,7 +109,7 @@ enum MovePathResult {
|
||||
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`
|
||||
/// 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.
|
||||
fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
|
||||
let data = &mut self.builder.data;
|
||||
let data = &mut self.data;
|
||||
|
||||
debug!("lookup({:?})", place);
|
||||
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;
|
||||
|
||||
for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) {
|
||||
let body = self.builder.body;
|
||||
let tcx = self.builder.tcx;
|
||||
let body = self.body;
|
||||
let tcx = self.tcx;
|
||||
let place_ty = place_ref.ty(body, tcx).ty;
|
||||
if place_ty.references_error() {
|
||||
return MovePathResult::Error;
|
||||
@ -238,7 +240,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
| ProjectionElem::Downcast(_, _) => (),
|
||||
}
|
||||
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;
|
||||
}
|
||||
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, .. },
|
||||
tcx,
|
||||
..
|
||||
} = self.builder;
|
||||
} = self;
|
||||
*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))
|
||||
})
|
||||
@ -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.
|
||||
let _ = self.move_path_for(place);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
|
||||
fn finalize(self) -> MoveData<'tcx> {
|
||||
debug!("{}", {
|
||||
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 (i, stmt) in block.statements.iter().enumerate() {
|
||||
let source = Location { block: bb, statement_index: i };
|
||||
builder.gather_statement(source, stmt);
|
||||
builder.loc = Location { block: bb, statement_index: i };
|
||||
builder.gather_statement(stmt);
|
||||
}
|
||||
|
||||
let terminator_loc = Location { block: bb, statement_index: block.statements.len() };
|
||||
builder.gather_terminator(terminator_loc, block.terminator());
|
||||
builder.loc = Location { block: bb, statement_index: block.statements.len() };
|
||||
builder.gather_terminator(block.terminator());
|
||||
}
|
||||
|
||||
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>) {
|
||||
debug!("gather_statement({:?}, {:?})", self.loc, stmt);
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
|
||||
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());
|
||||
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
|
||||
// move-path for the interior so it will be separate from
|
||||
// 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);
|
||||
} else {
|
||||
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::StorageDead(local) => {
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
@ -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>) {
|
||||
debug!("gather_terminator({:?}, {:?})", self.loc, term);
|
||||
match term.kind {
|
||||
TerminatorKind::Goto { target: _ }
|
||||
| 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
|
||||
// are disjoint, which is expected by drop elaboration.
|
||||
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) {
|
||||
MovePathResult::Path(path) => path,
|
||||
MovePathResult::Union(path) => {
|
||||
@ -562,11 +547,9 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
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() {
|
||||
ty::Array(_, size) => {
|
||||
size.eval_target_usize(self.builder.tcx, self.builder.param_env)
|
||||
}
|
||||
ty::Array(_, size) => size.eval_target_usize(self.tcx, self.param_env),
|
||||
_ => bug!("from_end: false slice pattern of non-array type"),
|
||||
};
|
||||
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) {
|
||||
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!(
|
||||
"gather_move({:?}, {:?}): adding move {:?} of {:?}",
|
||||
self.loc, place, move_out, path
|
||||
);
|
||||
self.builder.data.path_map[path].push(move_out);
|
||||
self.builder.data.loc_map[self.loc].push(move_out);
|
||||
self.data.path_map[path].push(move_out);
|
||||
self.data.loc_map[self.loc].push(move_out);
|
||||
}
|
||||
|
||||
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
|
||||
// of the union so it is marked as initialized again.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) {
|
||||
let init = self.builder.data.inits.push(Init {
|
||||
if let LookupResult::Exact(path) = self.data.rev_lookup.find(place) {
|
||||
let init = self.data.inits.push(Init {
|
||||
location: InitLocation::Statement(self.loc),
|
||||
path,
|
||||
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.builder.data.init_path_map[path].push(init);
|
||||
self.builder.data.init_loc_map[self.loc].push(init);
|
||||
self.data.init_path_map[path].push(init);
|
||||
self.data.init_loc_map[self.loc].push(init);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -923,14 +923,14 @@ impl<'tcx> Map<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaceCollector<'a, 'b, 'tcx> {
|
||||
struct PlaceCollector<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'b Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
map: &'a mut Map<'tcx>,
|
||||
assignments: FxIndexSet<(PlaceIndex, PlaceIndex)>,
|
||||
}
|
||||
|
||||
impl<'tcx> PlaceCollector<'_, '_, 'tcx> {
|
||||
impl<'tcx> PlaceCollector<'_, 'tcx> {
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
fn register_place(&mut self, place: Place<'tcx>) -> Option<PlaceIndex> {
|
||||
// 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))]
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, _: Location) {
|
||||
if !ctxt.is_use() {
|
||||
|
@ -20,7 +20,7 @@ use rustc_target::spec::PanicStrategy;
|
||||
/// This forces all unwinds, in panic=abort mode happening in foreign code, to
|
||||
/// trigger a process abort.
|
||||
#[derive(PartialEq)]
|
||||
pub struct AbortUnwindingCalls;
|
||||
pub(super) struct AbortUnwindingCalls;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
|
||||
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.
|
||||
// This will filter to functions with `extern "C-unwind"` ABIs, for
|
||||
// example.
|
||||
let mut calls_to_terminate = Vec::new();
|
||||
let mut cleanups_to_remove = Vec::new();
|
||||
for (id, block) in body.basic_blocks.iter_enumerated() {
|
||||
for block in body.basic_blocks.as_mut() {
|
||||
if block.is_cleanup {
|
||||
continue;
|
||||
}
|
||||
@ -61,7 +59,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
|
||||
|
||||
let call_can_unwind = match &terminator.kind {
|
||||
TerminatorKind::Call { func, .. } => {
|
||||
let ty = func.ty(body, tcx);
|
||||
let ty = func.ty(&body.local_decls, tcx);
|
||||
let sig = ty.fn_sig(tcx);
|
||||
let fn_def_id = match ty.kind() {
|
||||
ty::FnPtr(..) => None,
|
||||
@ -86,31 +84,20 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
// 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
|
||||
// registered for it.
|
||||
if !call_can_unwind {
|
||||
cleanups_to_remove.push(id);
|
||||
continue;
|
||||
// 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
|
||||
// registered for it.
|
||||
let cleanup = block.terminator_mut().unwind_mut().unwrap();
|
||||
*cleanup = UnwindAction::Unreachable;
|
||||
} else if !body_can_unwind {
|
||||
// Otherwise if this function can unwind, then 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
|
||||
// function call to one that aborts.
|
||||
let cleanup = block.terminator_mut().unwind_mut().unwrap();
|
||||
*cleanup = UnwindAction::Terminate(UnwindTerminateReason::Abi);
|
||||
}
|
||||
|
||||
// Otherwise if this function can unwind, then 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
|
||||
// function call to one that aborts.
|
||||
if !body_can_unwind {
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -4,11 +4,11 @@ use rustc_middle::ty::TyCtxt;
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum AddCallGuards {
|
||||
pub(super) enum AddCallGuards {
|
||||
AllCallEdges,
|
||||
CriticalCallEdges,
|
||||
}
|
||||
pub use self::AddCallGuards::*;
|
||||
pub(super) use self::AddCallGuards::*;
|
||||
|
||||
/**
|
||||
* Breaks outgoing critical edges for call terminators in the MIR.
|
||||
@ -37,7 +37,7 @@ impl<'tcx> crate::MirPass<'tcx> for 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<_, _> =
|
||||
body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect();
|
||||
pred_count[START_BLOCK] += 1;
|
||||
|
@ -35,7 +35,7 @@ use crate::util;
|
||||
///
|
||||
/// The storage instructions are required to avoid stack space
|
||||
/// blowup.
|
||||
pub struct AddMovesForPackedDrops;
|
||||
pub(super) struct AddMovesForPackedDrops;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
|
||||
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);
|
||||
patch.apply(body);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use rustc_hir::LangItem;
|
||||
use rustc_middle::mir::*;
|
||||
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.
|
||||
/// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this.
|
||||
|
@ -1,15 +1,14 @@
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::patch::MirPatch;
|
||||
use rustc_middle::mir::visit::MutVisitor;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct Subtyper;
|
||||
pub(super) struct Subtyper;
|
||||
|
||||
pub struct SubTypeChecker<'a, 'tcx> {
|
||||
struct SubTypeChecker<'a, 'tcx> {
|
||||
tcx: TyCtxt<'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> {
|
||||
@ -52,7 +51,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
|
||||
// // gets transformed to
|
||||
// let temp: rval_ty = rval;
|
||||
// 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 mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
|
||||
|
||||
|
@ -7,7 +7,7 @@ use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
pub struct CheckAlignment;
|
||||
pub(super) struct CheckAlignment;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
|
||||
fn is_enabled(&self, sess: &Session) -> bool {
|
||||
|
@ -8,7 +8,7 @@ use rustc_span::Span;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
pub struct CheckConstItemMutation;
|
||||
pub(super) struct CheckConstItemMutation;
|
||||
|
||||
impl<'tcx> crate::MirLint<'tcx> for CheckConstItemMutation {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
|
@ -5,7 +5,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
||||
|
||||
use crate::{errors, util};
|
||||
|
||||
pub struct CheckPackedRef;
|
||||
pub(super) struct CheckPackedRef;
|
||||
|
||||
impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
|
@ -21,7 +21,7 @@ use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, Termi
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct CleanupPostBorrowck;
|
||||
pub(super) struct CleanupPostBorrowck;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
|
||||
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
@ -17,7 +17,7 @@ use crate::ssa::SsaLocals;
|
||||
/// where each of the locals is only assigned once.
|
||||
///
|
||||
/// 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 {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -53,7 +53,7 @@
|
||||
mod by_move_body;
|
||||
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_errors::pluralize;
|
||||
use rustc_hir as hir;
|
||||
@ -85,7 +85,7 @@ use tracing::{debug, instrument, trace};
|
||||
use crate::deref_separator::deref_finder;
|
||||
use crate::{abort_unwinding_calls, errors, pass_manager as pm, simplify};
|
||||
|
||||
pub struct StateTransform;
|
||||
pub(super) struct StateTransform;
|
||||
|
||||
struct RenameLocalVisitor<'tcx> {
|
||||
from: Local,
|
||||
@ -872,9 +872,9 @@ fn compute_storage_conflicts<'mir, 'tcx>(
|
||||
storage_conflicts
|
||||
}
|
||||
|
||||
struct StorageConflictVisitor<'mir, 'tcx, 's> {
|
||||
body: &'mir Body<'tcx>,
|
||||
saved_locals: &'s CoroutineSavedLocals,
|
||||
struct StorageConflictVisitor<'a, 'tcx> {
|
||||
body: &'a Body<'tcx>,
|
||||
saved_locals: &'a CoroutineSavedLocals,
|
||||
// FIXME(tmandry): Consider using sparse bitsets here once we have good
|
||||
// benchmarks for coroutines.
|
||||
local_conflicts: BitMatrix<Local, Local>,
|
||||
@ -882,8 +882,8 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> {
|
||||
eligible_storage_live: BitSet<Local>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||
for StorageConflictVisitor<'mir, 'tcx, '_>
|
||||
impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
|
||||
for StorageConflictVisitor<'a, 'tcx>
|
||||
{
|
||||
type FlowState = BitSet<Local>;
|
||||
|
||||
@ -891,7 +891,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
state: &Self::FlowState,
|
||||
_statement: &'mir Statement<'tcx>,
|
||||
_statement: &'a Statement<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
self.apply_state(state, loc);
|
||||
@ -901,14 +901,14 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
state: &Self::FlowState,
|
||||
_terminator: &'mir Terminator<'tcx>,
|
||||
_terminator: &'a Terminator<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
self.apply_state(state, loc);
|
||||
}
|
||||
}
|
||||
|
||||
impl StorageConflictVisitor<'_, '_, '_> {
|
||||
impl StorageConflictVisitor<'_, '_> {
|
||||
fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) {
|
||||
// Ignore unreachable blocks.
|
||||
if let TerminatorKind::Unreachable = self.body.basic_blocks[loc.block].terminator().kind {
|
||||
@ -1199,7 +1199,7 @@ fn insert_panic_block<'tcx>(
|
||||
message: AssertMessage<'tcx>,
|
||||
) -> BasicBlock {
|
||||
let assert_block = BasicBlock::new(body.basic_blocks.len());
|
||||
let term = TerminatorKind::Assert {
|
||||
let kind = TerminatorKind::Assert {
|
||||
cond: Operand::Constant(Box::new(ConstOperand {
|
||||
span: body.span,
|
||||
user_ty: None,
|
||||
@ -1211,14 +1211,7 @@ fn insert_panic_block<'tcx>(
|
||||
unwind: UnwindAction::Continue,
|
||||
};
|
||||
|
||||
let source_info = SourceInfo::outermost(body.span);
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: Vec::new(),
|
||||
terminator: Some(Terminator { source_info, kind: term }),
|
||||
is_cleanup: false,
|
||||
});
|
||||
|
||||
assert_block
|
||||
insert_term_block(body, kind)
|
||||
}
|
||||
|
||||
fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
|
@ -82,7 +82,7 @@ use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::symbol::kw;
|
||||
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>,
|
||||
coroutine_def_id: LocalDefId,
|
||||
) -> DefId {
|
||||
|
@ -12,7 +12,7 @@ const CONST_SWITCH_BONUS: usize = 10;
|
||||
|
||||
/// Verify that the callee body is compatible with the caller.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CostChecker<'b, 'tcx> {
|
||||
pub(super) struct CostChecker<'b, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
penalty: usize,
|
||||
@ -22,7 +22,7 @@ pub(crate) struct CostChecker<'b, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'b, 'tcx> CostChecker<'b, 'tcx> {
|
||||
pub fn new(
|
||||
pub(super) fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'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,
|
||||
/// and even the full `Inline` doesn't call `visit_body`, so there's nowhere
|
||||
/// 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 {
|
||||
use TerminatorKind::*;
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub mod query;
|
||||
pub(super) mod query;
|
||||
|
||||
mod counters;
|
||||
mod graph;
|
||||
@ -32,7 +32,7 @@ use crate::coverage::mappings::ExtractedMappings;
|
||||
/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
|
||||
/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
|
||||
/// to construct the coverage map.
|
||||
pub struct InstrumentCoverage;
|
||||
pub(super) struct InstrumentCoverage;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -10,7 +10,7 @@ use rustc_span::sym;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use rustc_middle::mir::{
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::instrument;
|
||||
|
||||
pub struct CtfeLimit;
|
||||
pub(super) struct CtfeLimit;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
|
||||
#[instrument(skip(self, _tcx, body))]
|
||||
|
@ -26,7 +26,7 @@ use tracing::{debug, debug_span, instrument};
|
||||
const BLOCK_LIMIT: usize = 100;
|
||||
const PLACE_LIMIT: usize = 100;
|
||||
|
||||
pub struct DataflowConstProp;
|
||||
pub(super) struct DataflowConstProp;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
|
||||
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> {
|
||||
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());
|
||||
Self {
|
||||
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>>,
|
||||
visitor: &'a mut Collector<'tcx, 'locals>,
|
||||
ecx: &'map mut InterpCx<'tcx, DummyMachine>,
|
||||
map: &'map Map<'tcx>,
|
||||
ecx: &'a mut InterpCx<'tcx, DummyMachine>,
|
||||
map: &'a Map<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
|
||||
impl<'tcx> Visitor<'tcx> for OperandCollector<'_, '_, 'tcx> {
|
||||
fn visit_projection_elem(
|
||||
&mut self,
|
||||
_: PlaceRef<'tcx>,
|
||||
|
@ -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
|
||||
/// 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);
|
||||
|
||||
// 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,
|
||||
Final,
|
||||
}
|
||||
|
@ -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
|
||||
/// purposes on a best-effort basis. We compute them here and store them into the crate metadata so
|
||||
/// dependent crates can use them.
|
||||
pub fn deduced_param_attrs<'tcx>(
|
||||
pub(super) fn deduced_param_attrs<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> &'tcx [DeducedParamAttrs] {
|
||||
|
@ -13,7 +13,7 @@ use tracing::debug;
|
||||
|
||||
use super::simplify::simplify_cfg;
|
||||
|
||||
pub struct DeduplicateBlocks;
|
||||
pub(super) struct DeduplicateBlocks;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -1,16 +1,15 @@
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::patch::MirPatch;
|
||||
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
|
||||
use rustc_middle::mir::visit::{MutVisitor, PlaceContext};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct Derefer;
|
||||
pub(super) struct Derefer;
|
||||
|
||||
pub struct DerefChecker<'a, 'tcx> {
|
||||
struct DerefChecker<'a, 'tcx> {
|
||||
tcx: TyCtxt<'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> {
|
||||
@ -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 mut checker = DerefChecker { tcx, patcher: patch, local_decls: &body.local_decls };
|
||||
|
||||
|
@ -146,7 +146,7 @@ use rustc_mir_dataflow::points::{save_as_intervals, DenseLocationMap, PointIndex
|
||||
use rustc_mir_dataflow::Analysis;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
pub struct DestinationPropagation;
|
||||
pub(super) struct DestinationPropagation;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -7,7 +7,7 @@ use rustc_middle::mir::{write_mir_pretty, Body};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
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 {
|
||||
fn name(&self) -> &'static str {
|
||||
|
@ -90,7 +90,7 @@ use super::simplify::simplify_cfg;
|
||||
/// | ... |
|
||||
/// =================
|
||||
/// ```
|
||||
pub struct EarlyOtherwiseBranch;
|
||||
pub(super) struct EarlyOtherwiseBranch;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
@ -310,42 +310,28 @@ fn verify_candidate_branch<'tcx>(
|
||||
) -> bool {
|
||||
// In order for the optimization to be correct, the branch must...
|
||||
// ...have exactly one statement
|
||||
let [statement] = branch.statements.as_slice() else {
|
||||
return false;
|
||||
};
|
||||
// ...assign the discriminant of `place` in that statement
|
||||
let StatementKind::Assign(boxed) = &statement.kind else { return false };
|
||||
let (discr_place, Rvalue::Discriminant(from_place)) = &**boxed else { return false };
|
||||
if *from_place != place {
|
||||
return false;
|
||||
if let [statement] = branch.statements.as_slice()
|
||||
// ...assign the discriminant of `place` in that statement
|
||||
&& let StatementKind::Assign(boxed) = &statement.kind
|
||||
&& let (discr_place, Rvalue::Discriminant(from_place)) = &**boxed
|
||||
&& *from_place == place
|
||||
// ...make that assignment to a local
|
||||
&& discr_place.projection.is_empty()
|
||||
// ...terminate on a `SwitchInt` that invalidates that local
|
||||
&& let TerminatorKind::SwitchInt { discr: switch_op, targets, .. } =
|
||||
&branch.terminator().kind
|
||||
&& *switch_op == Operand::Move(*discr_place)
|
||||
// ...fall through to `destination` if the switch misses
|
||||
&& destination == targets.otherwise()
|
||||
// ...have a branch for value `value`
|
||||
&& let mut iter = targets.iter()
|
||||
&& let Some((target_value, _)) = iter.next()
|
||||
&& target_value == value
|
||||
// ...and have no more branches
|
||||
&& iter.next().is_none()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
// ...make that assignment to a local
|
||||
if discr_place.projection.len() != 0 {
|
||||
return false;
|
||||
}
|
||||
// ...terminate on a `SwitchInt` that invalidates that local
|
||||
let TerminatorKind::SwitchInt { discr: switch_op, targets, .. } = &branch.terminator().kind
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
if *switch_op != Operand::Move(*discr_place) {
|
||||
return false;
|
||||
}
|
||||
// ...fall through to `destination` if the switch misses
|
||||
if destination != targets.otherwise() {
|
||||
return false;
|
||||
}
|
||||
// ...have a branch for value `value`
|
||||
let mut iter = targets.iter();
|
||||
let Some((target_value, _)) = iter.next() else {
|
||||
return false;
|
||||
};
|
||||
if target_value != value {
|
||||
return false;
|
||||
}
|
||||
// ...and have no more branches
|
||||
if let Some(_) = iter.next() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
|
||||
/// Constructs the types used when accessing a Box's pointer
|
||||
pub fn build_ptr_tys<'tcx>(
|
||||
fn build_ptr_tys<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
pointee: Ty<'tcx>,
|
||||
unique_did: DefId,
|
||||
@ -26,7 +26,7 @@ pub fn build_ptr_tys<'tcx>(
|
||||
}
|
||||
|
||||
/// 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>,
|
||||
nonnull_ty: Ty<'tcx>,
|
||||
ptr_ty: Ty<'tcx>,
|
||||
@ -88,68 +88,65 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ElaborateBoxDerefs;
|
||||
pub(super) struct ElaborateBoxDerefs;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if let Some(def_id) = tcx.lang_items().owned_box() {
|
||||
let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
|
||||
// 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 Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def()
|
||||
else {
|
||||
span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
|
||||
};
|
||||
let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
|
||||
|
||||
let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::ZERO].did;
|
||||
let Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def() else {
|
||||
span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
|
||||
};
|
||||
|
||||
let patch = MirPatch::new(body);
|
||||
let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::ZERO].did;
|
||||
|
||||
let local_decls = &mut body.local_decls;
|
||||
let patch = MirPatch::new(body);
|
||||
|
||||
let mut visitor =
|
||||
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
|
||||
let local_decls = &mut body.local_decls;
|
||||
|
||||
for (block, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
|
||||
visitor.visit_basic_block_data(block, data);
|
||||
}
|
||||
let mut visitor =
|
||||
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
|
||||
|
||||
visitor.patch.apply(body);
|
||||
for (block, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
|
||||
visitor.visit_basic_block_data(block, data);
|
||||
}
|
||||
|
||||
for debug_info in body.var_debug_info.iter_mut() {
|
||||
if let VarDebugInfoContents::Place(place) = &mut debug_info.value {
|
||||
let mut new_projections: Option<Vec<_>> = None;
|
||||
visitor.patch.apply(body);
|
||||
|
||||
for (base, elem) in place.iter_projections() {
|
||||
let base_ty = base.ty(&body.local_decls, tcx).ty;
|
||||
for debug_info in body.var_debug_info.iter_mut() {
|
||||
if let VarDebugInfoContents::Place(place) = &mut debug_info.value {
|
||||
let mut new_projections: Option<Vec<_>> = None;
|
||||
|
||||
if let PlaceElem::Deref = elem
|
||||
&& let Some(boxed_ty) = base_ty.boxed_ty()
|
||||
{
|
||||
// Clone the projections before us, since now we need to mutate them.
|
||||
let new_projections =
|
||||
new_projections.get_or_insert_with(|| base.projection.to_vec());
|
||||
for (base, elem) in place.iter_projections() {
|
||||
let base_ty = base.ty(&body.local_decls, tcx).ty;
|
||||
|
||||
let (unique_ty, nonnull_ty, ptr_ty) =
|
||||
build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did);
|
||||
if let PlaceElem::Deref = elem
|
||||
&& let Some(boxed_ty) = base_ty.boxed_ty()
|
||||
{
|
||||
// Clone the projections before us, since now we need to mutate them.
|
||||
let new_projections =
|
||||
new_projections.get_or_insert_with(|| base.projection.to_vec());
|
||||
|
||||
new_projections.extend_from_slice(&build_projection(
|
||||
unique_ty, nonnull_ty, ptr_ty,
|
||||
));
|
||||
new_projections.push(PlaceElem::Deref);
|
||||
} else if let Some(new_projections) = new_projections.as_mut() {
|
||||
// Keep building up our projections list once we've started it.
|
||||
new_projections.push(elem);
|
||||
}
|
||||
}
|
||||
let (unique_ty, nonnull_ty, ptr_ty) =
|
||||
build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did);
|
||||
|
||||
// Store the mutated projections if we actually changed something.
|
||||
if let Some(new_projections) = new_projections {
|
||||
place.projection = tcx.mk_place_elems(&new_projections);
|
||||
new_projections
|
||||
.extend_from_slice(&build_projection(unique_ty, nonnull_ty, ptr_ty));
|
||||
new_projections.push(PlaceElem::Deref);
|
||||
} else if let Some(new_projections) = new_projections.as_mut() {
|
||||
// Keep building up our projections list once we've started it.
|
||||
new_projections.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the mutated projections if we actually changed something.
|
||||
if let Some(new_projections) = new_projections {
|
||||
place.projection = tcx.mk_place_elems(&new_projections);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// box is not present, this pass doesn't need to do anything
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ use crate::deref_separator::deref_finder;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub struct ElaborateDrops;
|
||||
pub(super) struct ElaborateDrops;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
|
||||
#[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
|
||||
/// that can't drop anything.
|
||||
#[instrument(level = "trace", skip(body, flow_inits), ret)]
|
||||
fn compute_dead_unwinds<'mir, 'tcx>(
|
||||
body: &'mir Body<'tcx>,
|
||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
|
||||
fn compute_dead_unwinds<'a, 'tcx>(
|
||||
body: &'a Body<'tcx>,
|
||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
) -> BitSet<BasicBlock> {
|
||||
// We only need to do this pass once, because unwind edges can only
|
||||
// reach cleanup blocks, which can't have unwind edges themselves.
|
||||
@ -121,12 +121,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
|
||||
dead_unwinds
|
||||
}
|
||||
|
||||
struct InitializationData<'a, 'mir, 'tcx> {
|
||||
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
struct InitializationData<'a, 'tcx> {
|
||||
inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
uninits: ResultsCursor<'a, 'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
|
||||
}
|
||||
|
||||
impl InitializationData<'_, '_, '_> {
|
||||
impl InitializationData<'_, '_> {
|
||||
fn seek_before(&mut self, loc: Location) {
|
||||
self.inits.seek_before_primary_effect(loc);
|
||||
self.uninits.seek_before_primary_effect(loc);
|
||||
@ -137,45 +137,35 @@ impl InitializationData<'_, '_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
struct Elaborator<'a, 'b, 'mir, '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> {
|
||||
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
|
||||
type Path = MovePathIndex;
|
||||
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx> {
|
||||
&mut self.ctxt.patch
|
||||
&mut self.patch
|
||||
}
|
||||
|
||||
fn body(&self) -> &'a Body<'tcx> {
|
||||
self.ctxt.body
|
||||
self.body
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.ctxt.tcx
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.ctxt.param_env()
|
||||
self.param_env()
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
|
||||
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 => {
|
||||
let mut some_live = false;
|
||||
let mut some_dead = false;
|
||||
let mut children_count = 0;
|
||||
on_all_children_bits(self.ctxt.move_data(), path, |child| {
|
||||
let (live, dead) = self.ctxt.init_data.maybe_live_dead(child);
|
||||
on_all_children_bits(self.move_data(), path, |child| {
|
||||
let (live, dead) = self.init_data.maybe_live_dead(child);
|
||||
debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead));
|
||||
some_live |= live;
|
||||
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) {
|
||||
match mode {
|
||||
DropFlagMode::Shallow => {
|
||||
self.ctxt.set_drop_flag(loc, path, DropFlagState::Absent);
|
||||
self.set_drop_flag(loc, path, DropFlagState::Absent);
|
||||
}
|
||||
DropFlagMode::Deep => {
|
||||
on_all_children_bits(self.ctxt.move_data(), path, |child| {
|
||||
self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent)
|
||||
on_all_children_bits(self.move_data(), path, |child| {
|
||||
self.set_drop_flag(loc, child, DropFlagState::Absent)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
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 } => {
|
||||
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");
|
||||
@ -224,34 +214,40 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
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,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
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>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
env: &'a MoveDataParamEnv<'tcx>,
|
||||
init_data: InitializationData<'a, 'mir, 'tcx>,
|
||||
init_data: InitializationData<'a, 'tcx>,
|
||||
drop_flags: IndexVec<MovePathIndex, Option<Local>>,
|
||||
patch: MirPatch<'tcx>,
|
||||
}
|
||||
|
||||
impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
|
||||
fn move_data(&self) -> &'b MoveData<'tcx> {
|
||||
impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
|
||||
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
|
||||
}
|
||||
|
||||
@ -370,15 +366,7 @@ impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
|
||||
}
|
||||
};
|
||||
self.init_data.seek_before(self.body.terminator_loc(bb));
|
||||
elaborate_drop(
|
||||
&mut Elaborator { ctxt: self },
|
||||
terminator.source_info,
|
||||
place,
|
||||
path,
|
||||
target,
|
||||
unwind,
|
||||
bb,
|
||||
)
|
||||
elaborate_drop(self, terminator.source_info, place, path, target, unwind, bb)
|
||||
}
|
||||
LookupResult::Parent(None) => {}
|
||||
LookupResult::Parent(Some(_)) => {
|
||||
|
@ -64,7 +64,7 @@ impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> {
|
||||
}
|
||||
|
||||
impl AssertLintKind {
|
||||
pub fn lint(&self) -> &'static Lint {
|
||||
pub(crate) fn lint(&self) -> &'static Lint {
|
||||
match self {
|
||||
AssertLintKind::ArithmeticOverflow => lint::builtin::ARITHMETIC_OVERFLOW,
|
||||
AssertLintKind::UnconditionalPanic => lint::builtin::UNCONDITIONAL_PANIC,
|
||||
|
@ -11,7 +11,7 @@ use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
pub struct FunctionItemReferences;
|
||||
pub(super) struct FunctionItemReferences;
|
||||
|
||||
impl<'tcx> crate::MirLint<'tcx> for FunctionItemReferences {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
|
@ -109,7 +109,7 @@ use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::ssa::{AssignedValue, SsaLocals};
|
||||
|
||||
pub struct GVN;
|
||||
pub(super) struct GVN;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for GVN {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -32,9 +32,11 @@ pub(crate) mod cycle;
|
||||
|
||||
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;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
struct CallSite<'tcx> {
|
||||
callee: Instance<'tcx>,
|
||||
fn_sig: ty::PolyFnSig<'tcx>,
|
||||
@ -156,7 +158,6 @@ impl<'tcx> Inliner<'tcx> {
|
||||
match self.try_inlining(caller_body, &callsite) {
|
||||
Err(reason) => {
|
||||
debug!("not-inlined {} [{}]", callsite.callee, reason);
|
||||
continue;
|
||||
}
|
||||
Ok(new_blocks) => {
|
||||
debug!("inlined {}", callsite.callee);
|
||||
@ -638,7 +639,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
);
|
||||
let dest_ty = dest.ty(caller_body, self.tcx);
|
||||
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 {
|
||||
source_info: callsite.source_info,
|
||||
kind: StatementKind::Assign(Box::new((temp, dest))),
|
||||
@ -657,7 +658,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
true,
|
||||
self.new_call_temp(
|
||||
caller_body,
|
||||
&callsite,
|
||||
callsite,
|
||||
destination.ty(caller_body, self.tcx).ty,
|
||||
return_block,
|
||||
),
|
||||
@ -665,7 +666,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
};
|
||||
|
||||
// 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 {
|
||||
args: &args,
|
||||
|
@ -13,13 +13,13 @@ use rustc_target::spec::abi::Abi;
|
||||
use crate::simplify::simplify_duplicate_switch_targets;
|
||||
use crate::take_array;
|
||||
|
||||
pub enum InstSimplify {
|
||||
pub(super) enum InstSimplify {
|
||||
BeforeInline,
|
||||
AfterSimplifyCfg,
|
||||
}
|
||||
|
||||
impl InstSimplify {
|
||||
pub fn name(&self) -> &'static str {
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
InstSimplify::BeforeInline => "InstSimplify-before-inline",
|
||||
InstSimplify::AfterSimplifyCfg => "InstSimplify-after-simplifycfg",
|
||||
|
@ -55,7 +55,7 @@ use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::cost_checker::CostChecker;
|
||||
|
||||
pub struct JumpThreading;
|
||||
pub(super) struct JumpThreading;
|
||||
|
||||
const MAX_BACKTRACK: usize = 5;
|
||||
const MAX_COST: usize = 100;
|
||||
|
@ -26,7 +26,7 @@ use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::errors::{AssertLint, AssertLintKind};
|
||||
|
||||
pub struct KnownPanicsLint;
|
||||
pub(super) struct KnownPanicsLint;
|
||||
|
||||
impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint {
|
||||
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`.
|
||||
#[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.
|
||||
FullConstProp,
|
||||
/// 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
|
||||
/// that can be const propagated
|
||||
pub struct CanConstProp {
|
||||
struct CanConstProp {
|
||||
can_const_prop: IndexVec<Local, ConstPropMode>,
|
||||
// False at the beginning. Once set, no more assignments are allowed to that local.
|
||||
found_assignment: BitSet<Local>,
|
||||
@ -872,7 +872,7 @@ pub struct CanConstProp {
|
||||
|
||||
impl CanConstProp {
|
||||
/// Returns true if `local` can be propagated
|
||||
pub fn check<'tcx>(
|
||||
fn check<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
|
@ -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,
|
||||
/// and instead of copying all the bytes of the largest possible variant,
|
||||
/// copy only the bytes for the currently active variant.
|
||||
pub struct EnumSizeOpt {
|
||||
pub(super) struct EnumSizeOpt {
|
||||
pub(crate) discrepancy: u64,
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(yeet_expr)]
|
||||
#![warn(unreachable_pub)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
use hir::ConstContext;
|
||||
@ -72,6 +73,8 @@ mod errors;
|
||||
mod ffi_unwind_calls;
|
||||
mod function_item_references;
|
||||
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;
|
||||
mod instsimplify;
|
||||
mod jump_threading;
|
||||
@ -459,8 +462,8 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
|
||||
tcx.alloc_steal_mir(body)
|
||||
}
|
||||
|
||||
// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden
|
||||
// by custom rustc drivers, running all the steps by themselves.
|
||||
// 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 fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
|
||||
let did = body.source.def_id();
|
||||
|
@ -13,7 +13,7 @@ use rustc_mir_dataflow::impls::{MaybeStorageDead, MaybeStorageLive};
|
||||
use rustc_mir_dataflow::storage::always_storage_live_locals;
|
||||
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 maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
|
||||
|
@ -7,7 +7,7 @@ use rustc_span::symbol::sym;
|
||||
|
||||
use crate::take_array;
|
||||
|
||||
pub struct LowerIntrinsics;
|
||||
pub(super) struct LowerIntrinsics;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
@ -35,20 +35,19 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::forget => {
|
||||
if let Some(target) = *target {
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
|
||||
span: terminator.source_info.span,
|
||||
user_ty: None,
|
||||
const_: Const::zero_sized(tcx.types.unit),
|
||||
}))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
let target = target.unwrap();
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
|
||||
span: terminator.source_info.span,
|
||||
user_ty: None,
|
||||
const_: Const::zero_sized(tcx.types.unit),
|
||||
}))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::copy_nonoverlapping => {
|
||||
let target = target.unwrap();
|
||||
@ -121,43 +120,41 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
|
||||
if let Some(target) = *target {
|
||||
let Ok([lhs, rhs]) = take_array(args) else {
|
||||
bug!("Wrong arguments for {} intrinsic", intrinsic.name);
|
||||
};
|
||||
let bin_op = match intrinsic.name {
|
||||
sym::add_with_overflow => BinOp::AddWithOverflow,
|
||||
sym::sub_with_overflow => BinOp::SubWithOverflow,
|
||||
sym::mul_with_overflow => BinOp::MulWithOverflow,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
let target = target.unwrap();
|
||||
let Ok([lhs, rhs]) = take_array(args) else {
|
||||
bug!("Wrong arguments for {} intrinsic", intrinsic.name);
|
||||
};
|
||||
let bin_op = match intrinsic.name {
|
||||
sym::add_with_overflow => BinOp::AddWithOverflow,
|
||||
sym::sub_with_overflow => BinOp::SubWithOverflow,
|
||||
sym::mul_with_overflow => BinOp::MulWithOverflow,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::size_of | sym::min_align_of => {
|
||||
if let Some(target) = *target {
|
||||
let tp_ty = generic_args.type_at(0);
|
||||
let null_op = match intrinsic.name {
|
||||
sym::size_of => NullOp::SizeOf,
|
||||
sym::min_align_of => NullOp::AlignOf,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::NullaryOp(null_op, tp_ty),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
let target = target.unwrap();
|
||||
let tp_ty = generic_args.type_at(0);
|
||||
let null_op = match intrinsic.name {
|
||||
sym::size_of => NullOp::SizeOf,
|
||||
sym::min_align_of => NullOp::AlignOf,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::NullaryOp(null_op, tp_ty),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::read_via_copy => {
|
||||
let Ok([arg]) = take_array(args) else {
|
||||
@ -219,17 +216,23 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::discriminant_value => {
|
||||
if let (Some(target), Some(arg)) = (*target, args[0].node.place()) {
|
||||
let arg = tcx.mk_place_deref(arg);
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Discriminant(arg),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
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);
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Discriminant(arg),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::offset => {
|
||||
let target = target.unwrap();
|
||||
@ -267,7 +270,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
Rvalue::Cast(CastKind::Transmute, arg.node, dst_ty),
|
||||
))),
|
||||
});
|
||||
|
||||
if let Some(target) = *target {
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
} else {
|
||||
@ -299,7 +301,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
Rvalue::Aggregate(Box::new(kind), fields.into()),
|
||||
))),
|
||||
});
|
||||
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::ptr_metadata => {
|
||||
|
@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct LowerSliceLenCalls;
|
||||
pub(super) struct LowerSliceLenCalls;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
|
||||
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 Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
|
||||
// there is no lang item to compare to :)
|
||||
|
@ -10,7 +10,7 @@ use rustc_type_ir::TyKind::*;
|
||||
|
||||
use super::simplify::simplify_cfg;
|
||||
|
||||
pub struct MatchBranchSimplification;
|
||||
pub(super) struct MatchBranchSimplification;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -5,7 +5,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
||||
pub struct MentionedItems;
|
||||
pub(super) struct MentionedItems;
|
||||
|
||||
struct MentionedItemsVisitor<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -7,7 +7,7 @@ use rustc_middle::ty::TyCtxt;
|
||||
|
||||
use crate::simplify;
|
||||
|
||||
pub struct MultipleReturnTerminators;
|
||||
pub(super) struct MultipleReturnTerminators;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -30,7 +30,7 @@ use tracing::{debug, trace};
|
||||
///
|
||||
/// [#47954]: https://github.com/rust-lang/rust/pull/47954
|
||||
/// [#71003]: https://github.com/rust-lang/rust/pull/71003
|
||||
pub struct RenameReturnPlace;
|
||||
pub(super) struct RenameReturnPlace;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
pub(super) fn dump_mir_for_pass<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
pass_name: &str,
|
||||
is_after: bool,
|
||||
) {
|
||||
fn dump_mir_for_pass<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, pass_name: &str, is_after: bool) {
|
||||
mir::dump_mir(
|
||||
tcx,
|
||||
true,
|
||||
|
@ -15,7 +15,7 @@ use rustc_session::Session;
|
||||
///
|
||||
/// 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).
|
||||
pub struct ReorderBasicBlocks;
|
||||
pub(super) struct ReorderBasicBlocks;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks {
|
||||
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.
|
||||
///
|
||||
/// (Does not reorder arguments nor the [`RETURN_PLACE`].)
|
||||
pub struct ReorderLocals;
|
||||
pub(super) struct ReorderLocals;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
|
||||
fn is_enabled(&self, _session: &Session) -> bool {
|
||||
@ -135,8 +135,8 @@ impl<'tcx> Visitor<'tcx> for LocalFinder {
|
||||
}
|
||||
|
||||
struct LocalUpdater<'tcx> {
|
||||
pub map: IndexVec<Local, Local>,
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
map: IndexVec<Local, Local>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
|
||||
|
@ -37,7 +37,7 @@ use tracing::{debug, instrument};
|
||||
/// After this pass is run, `promoted_fragments` will hold the MIR body corresponding to each
|
||||
/// newly created `Constant`.
|
||||
#[derive(Default)]
|
||||
pub struct PromoteTemps<'tcx> {
|
||||
pub(super) struct PromoteTemps<'tcx> {
|
||||
pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
|
||||
///
|
||||
/// 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.
|
||||
pub struct ReferencePropagation;
|
||||
pub(super) struct ReferencePropagation;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -8,7 +8,7 @@ use tracing::debug;
|
||||
/// A pass that removes noop landing pads and replaces jumps to them with
|
||||
/// `UnwindAction::Continue`. This is important because otherwise LLVM generates
|
||||
/// terrible code for these.
|
||||
pub struct RemoveNoopLandingPads;
|
||||
pub(super) struct RemoveNoopLandingPads;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -4,7 +4,7 @@ use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::trace;
|
||||
|
||||
pub struct RemovePlaceMention;
|
||||
pub(super) struct RemovePlaceMention;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -4,7 +4,7 @@ use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::trace;
|
||||
|
||||
pub struct RemoveStorageMarkers;
|
||||
pub(super) struct RemoveStorageMarkers;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -14,7 +14,7 @@ use rustc_target::abi::FieldIdx;
|
||||
/// like [#90770].
|
||||
///
|
||||
/// [#90770]: https://github.com/rust-lang/rust/issues/90770
|
||||
pub struct RemoveUninitDrops;
|
||||
pub(super) struct RemoveUninitDrops;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
@ -10,7 +10,7 @@ use tracing::{debug, trace};
|
||||
|
||||
use super::simplify::simplify_cfg;
|
||||
|
||||
pub struct RemoveUnneededDrops;
|
||||
pub(super) struct RemoveUnneededDrops;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
@ -4,7 +4,7 @@ use rustc_middle::mir::visit::*;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub struct RemoveZsts;
|
||||
pub(super) struct RemoveZsts;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
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>>,
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
|
||||
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_visitor = RequiredConstsVisitor::new(&mut required_consts);
|
||||
for (bb, bb_data) in traversal::reverse_postorder(&body) {
|
||||
|
@ -4,7 +4,7 @@ use rustc_middle::mir::visit::*;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub struct RevealAll;
|
||||
pub(super) struct RevealAll;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for RevealAll {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
|
||||
mod async_destructor_ctor;
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
pub(super) fn provide(providers: &mut Providers) {
|
||||
providers.mir_shims = make_shim;
|
||||
}
|
||||
|
||||
@ -331,7 +331,7 @@ fn new_body<'tcx>(
|
||||
body
|
||||
}
|
||||
|
||||
pub struct DropShimElaborator<'a, 'tcx> {
|
||||
pub(super) struct DropShimElaborator<'a, 'tcx> {
|
||||
pub body: &'a Body<'tcx>,
|
||||
pub patch: MirPatch<'tcx>,
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
@ -913,7 +913,7 @@ fn build_call_shim<'tcx>(
|
||||
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));
|
||||
|
||||
let param_env = tcx.param_env_reveal_all_normalized(ctor_id);
|
||||
|
@ -23,7 +23,7 @@ use tracing::debug;
|
||||
|
||||
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>,
|
||||
def_id: DefId,
|
||||
ty: Option<Ty<'tcx>>,
|
||||
|
@ -35,7 +35,7 @@ use rustc_span::DUMMY_SP;
|
||||
use smallvec::SmallVec;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
pub enum SimplifyCfg {
|
||||
pub(super) enum SimplifyCfg {
|
||||
Initial,
|
||||
PromoteConsts,
|
||||
RemoveFalseEdges,
|
||||
@ -50,7 +50,7 @@ pub enum SimplifyCfg {
|
||||
}
|
||||
|
||||
impl SimplifyCfg {
|
||||
pub fn name(&self) -> &'static str {
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
SimplifyCfg::Initial => "SimplifyCfg-initial",
|
||||
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();
|
||||
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>>,
|
||||
pred_count: IndexVec<BasicBlock, u32>,
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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 }
|
||||
}
|
||||
|
||||
pub fn simplify(mut self) {
|
||||
fn simplify(mut self) {
|
||||
self.strip_nops();
|
||||
|
||||
// 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 {
|
||||
let otherwise = targets.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<'_>| {
|
||||
// CfgSimplifier::simplify leaves behind some unreachable basic blocks without a
|
||||
// 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,
|
||||
AfterGVN,
|
||||
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`.
|
||||
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);
|
||||
}
|
||||
|
||||
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`.
|
||||
let mut used_locals = UsedLocals::new(body);
|
||||
|
||||
|
@ -2,10 +2,11 @@ use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::trace;
|
||||
|
||||
pub enum SimplifyConstCondition {
|
||||
pub(super) enum SimplifyConstCondition {
|
||||
AfterConstProp,
|
||||
Final,
|
||||
}
|
||||
|
||||
/// A pass that replaces a branch with a goto when its condition is known.
|
||||
impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
|
||||
fn name(&self) -> &'static str {
|
||||
|
@ -23,7 +23,7 @@ use tracing::trace;
|
||||
/// ```ignore (MIR)
|
||||
/// switchInt(_4) -> [43i32: bb3, otherwise: bb2];
|
||||
/// ```
|
||||
pub struct SimplifyComparisonIntegral;
|
||||
pub(super) struct SimplifyComparisonIntegral;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -19,7 +19,7 @@ use rustc_middle::ty::TyCtxt;
|
||||
///
|
||||
/// It also removes *never*-used constants, since it had all the information
|
||||
/// needed to do that too, including updating the debug info.
|
||||
pub struct SingleUseConsts;
|
||||
pub(super) struct SingleUseConsts;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -11,7 +11,7 @@ use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields};
|
||||
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
pub struct ScalarReplacementOfAggregates;
|
||||
pub(super) struct ScalarReplacementOfAggregates;
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -16,7 +16,7 @@ use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{ParamEnv, TyCtxt};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
pub struct SsaLocals {
|
||||
pub(super) struct SsaLocals {
|
||||
/// Assignments to each local. This defines whether the local is SSA.
|
||||
assignments: IndexVec<Local, Set1<DefLocation>>,
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
pub enum AssignedValue<'a, 'tcx> {
|
||||
pub(super) enum AssignedValue<'a, 'tcx> {
|
||||
Arg,
|
||||
Rvalue(&'a mut Rvalue<'tcx>),
|
||||
Terminator,
|
||||
}
|
||||
|
||||
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 assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
|
||||
@ -101,25 +105,25 @@ impl SsaLocals {
|
||||
ssa
|
||||
}
|
||||
|
||||
pub fn num_locals(&self) -> usize {
|
||||
pub(super) fn num_locals(&self) -> usize {
|
||||
self.assignments.len()
|
||||
}
|
||||
|
||||
pub fn locals(&self) -> impl Iterator<Item = Local> {
|
||||
pub(super) fn locals(&self) -> impl Iterator<Item = Local> {
|
||||
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(_))
|
||||
}
|
||||
|
||||
/// 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]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assignment_dominates(
|
||||
pub(super) fn assignment_dominates(
|
||||
&self,
|
||||
dominators: &Dominators<BasicBlock>,
|
||||
local: Local,
|
||||
@ -131,7 +135,7 @@ impl SsaLocals {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assignments<'a, 'tcx>(
|
||||
pub(super) fn assignments<'a, 'tcx>(
|
||||
&'a self,
|
||||
body: &'a Body<'tcx>,
|
||||
) -> 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,
|
||||
basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
|
||||
mut f: impl FnMut(Local, AssignedValue<'_, 'tcx>, Location),
|
||||
@ -194,17 +198,17 @@ impl SsaLocals {
|
||||
/// _d => _a // transitively through _c
|
||||
///
|
||||
/// 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
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
/// 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.
|
||||
//
|
||||
// `copy_classes` defines equivalence classes between locals. The `local`s that recursively
|
||||
|
@ -12,7 +12,7 @@ use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_target::abi::{Abi, Variants};
|
||||
use tracing::trace;
|
||||
|
||||
pub struct UnreachableEnumBranching;
|
||||
pub(super) struct UnreachableEnumBranching;
|
||||
|
||||
fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
|
||||
if let TerminatorKind::SwitchInt { discr: Operand::Move(p), .. } = terminator {
|
||||
|
@ -10,7 +10,7 @@ use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_target::abi::Size;
|
||||
|
||||
pub struct UnreachablePropagation;
|
||||
pub(super) struct UnreachablePropagation;
|
||||
|
||||
impl crate::MirPass<'_> for UnreachablePropagation {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
|
@ -26,7 +26,7 @@ enum EdgeKind {
|
||||
Normal,
|
||||
}
|
||||
|
||||
pub struct Validator {
|
||||
pub(super) struct Validator {
|
||||
/// Describes at which point in the pipeline this validation is happening.
|
||||
pub when: String,
|
||||
/// 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
|
||||
/// `optimized_mir` is available.
|
||||
pub fn validate_types<'tcx>(
|
||||
pub(super) fn validate_types<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mir_phase: MirPhase,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -625,11 +625,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
if let ObligationCauseCode::WhereClause(_, span)
|
||||
| ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
|
||||
&trace.cause.code().peel_derives()
|
||||
&& !span.is_dummy()
|
||||
{
|
||||
let span = *span;
|
||||
self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
|
||||
.with_span_note(span, "the lifetime requirement is introduced here")
|
||||
let mut err = self.report_concrete_failure(
|
||||
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 {
|
||||
unreachable!(
|
||||
"control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
|
||||
|
@ -641,7 +641,7 @@
|
||||
#stack-protector = "none"
|
||||
|
||||
# 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).
|
||||
#optimize-tests = true
|
||||
|
@ -15,7 +15,6 @@ impl char {
|
||||
/// for you:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(char_min)]
|
||||
/// let dist = u32::from(char::MAX) - u32::from(char::MIN);
|
||||
/// let size = (char::MIN..=char::MAX).count() as u32;
|
||||
/// assert!(size < dist);
|
||||
@ -29,7 +28,6 @@ impl char {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(char_min)]
|
||||
/// # fn something_which_returns_char() -> char { 'a' }
|
||||
/// let c: char = something_which_returns_char();
|
||||
/// assert!(char::MIN <= c);
|
||||
@ -37,7 +35,7 @@ impl char {
|
||||
/// let value_at_min = u32::from(char::MIN);
|
||||
/// 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';
|
||||
|
||||
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
|
||||
@ -48,7 +46,6 @@ impl char {
|
||||
/// for you:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(char_min)]
|
||||
/// let dist = u32::from(char::MAX) - u32::from(char::MIN);
|
||||
/// let size = (char::MIN..=char::MAX).count() as u32;
|
||||
/// assert!(size < dist);
|
||||
|
@ -1,7 +1,5 @@
|
||||
use rand::RngCore;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::ffi::{c_char, c_int};
|
||||
use crate::fs::{self, File, FileTimes, OpenOptions};
|
||||
use crate::io::prelude::*;
|
||||
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::path::Path;
|
||||
use crate::sync::Arc;
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::sys::weak::weak;
|
||||
use crate::sys_common::io::test::{tmpdir, TempDir};
|
||||
use crate::time::{Duration, Instant, SystemTime};
|
||||
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]
|
||||
fn file_test_io_smoke_test() {
|
||||
let message = "it's alright. have a good time";
|
||||
@ -1456,9 +1441,6 @@ fn symlink_hard_link() {
|
||||
if !got_symlink_permission(&tmpdir) {
|
||||
return;
|
||||
};
|
||||
if !able_to_not_follow_symlinks_while_hard_linking() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create "file", a file.
|
||||
check!(fs::File::create(tmpdir.join("file")));
|
||||
|
@ -1600,6 +1600,9 @@ impl Config {
|
||||
|
||||
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 {
|
||||
let Install { prefix, sysconfdir, docdir, bindir, libdir, mandir, datadir } = install;
|
||||
config.prefix = prefix.map(PathBuf::from);
|
||||
|
@ -317,3 +317,12 @@ fn order_of_clippy_rules() {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ struct Renderer<'a> {
|
||||
builder: &'a Builder<'a>,
|
||||
tests_count: Option<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,
|
||||
}
|
||||
|
||||
@ -100,6 +103,7 @@ impl<'a> Renderer<'a> {
|
||||
builder,
|
||||
tests_count: None,
|
||||
executed_tests: 0,
|
||||
up_to_date_tests: 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
|
||||
@ -149,6 +159,11 @@ impl<'a> Renderer<'a> {
|
||||
fn render_test_outcome(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
|
||||
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")]
|
||||
self.builder.metrics.record_test(
|
||||
&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
Loading…
Reference in New Issue
Block a user