Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store a MirSource inside every Body #77430

Merged
merged 4 commits into from
Oct 4, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -10,12 +10,11 @@ use crate::ty::codec::{TyDecoder, TyEncoder};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{
self, AdtDef, CanonicalUserTypeAnnotations, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex,
};
use crate::ty::{self, List, Ty, TyCtxt};
use crate::ty::{AdtDef, InstanceDef, Region, UserTypeAnnotationIndex};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::def_id::DefId;
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc_hir::{self, GeneratorKind};
use rustc_target::abi::VariantIdx;

@@ -112,6 +111,38 @@ impl MirPhase {
}
}

/// Where a specific `mir::Body` comes from.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable)]
pub struct MirSource<'tcx> {
pub instance: InstanceDef<'tcx>,

/// If `Some`, this is a promoted rvalue within the parent function.
pub promoted: Option<Promoted>,
}

impl<'tcx> MirSource<'tcx> {
pub fn item(def_id: DefId) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn item(def_id: DefId) -> Self {
pub fn item(def: ty::WithOptParam<DefId>) -> Self {

my personal preference, makes it harder to get this wrong

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't mine. I've just moved it from transform/mod.rs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I still think that this would be a good change though 🤔 you don't have to do this in this PR

MirSource {
instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
promoted: None,
}
}

pub fn from_instance(instance: InstanceDef<'tcx>) -> Self {
MirSource { instance, promoted: None }
}

pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
self.instance.with_opt_param()
}

#[inline]
pub fn def_id(&self) -> DefId {
self.instance.def_id()
}
}

/// The lowered representation of a single function.
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
pub struct Body<'tcx> {
@@ -126,6 +157,8 @@ pub struct Body<'tcx> {
/// us to see the difference and forego optimization on the inlined promoted items.
pub phase: MirPhase,

pub source: MirSource<'tcx>,

/// A list of source scopes; these are referenced by statements
/// and used for debuginfo. Indexed by a `SourceScope`.
pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
@@ -151,7 +184,7 @@ pub struct Body<'tcx> {
pub local_decls: LocalDecls<'tcx>,

/// User type annotations.
pub user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
pub user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,

/// The number of arguments this function takes.
///
@@ -209,10 +242,11 @@ pub struct Body<'tcx> {

impl<'tcx> Body<'tcx> {
pub fn new(
source: MirSource<'tcx>,
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
source_scopes: IndexVec<SourceScope, SourceScopeData>,
local_decls: LocalDecls<'tcx>,
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
arg_count: usize,
var_debug_info: Vec<VarDebugInfo<'tcx>>,
span: Span,
@@ -228,6 +262,7 @@ impl<'tcx> Body<'tcx> {

let mut body = Body {
phase: MirPhase::Build,
source,
basic_blocks,
source_scopes,
yield_ty: None,
@@ -257,6 +292,7 @@ impl<'tcx> Body<'tcx> {
pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
let mut body = Body {
phase: MirPhase::Build,
source: MirSource::item(DefId::local(CRATE_DEF_INDEX)),
basic_blocks,
source_scopes: IndexVec::new(),
yield_ty: None,
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,8 @@ pub struct Instance<'tcx> {
pub substs: SubstsRef<'tcx>,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub enum InstanceDef<'tcx> {
/// A user-defined callable item.
///
11 changes: 2 additions & 9 deletions compiler/rustc_mir/src/borrow_check/mod.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind
use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, InstanceDef, ParamEnv, RegionVid, TyCtxt};
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt};
use rustc_session::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT, UNUSED_MUT};
use rustc_span::{Span, Symbol, DUMMY_SP};

@@ -36,7 +36,6 @@ use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathInd
use crate::dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveError};
use crate::dataflow::MoveDataParamEnv;
use crate::dataflow::{Analysis, BorrowckFlowState as Flows, BorrowckResults};
use crate::transform::MirSource;

use self::diagnostics::{AccessKind, RegionName};
use self::location::LocationTable;
@@ -236,13 +235,7 @@ fn do_mir_borrowck<'a, 'tcx>(

// Dump MIR results into a file, if that is enabled. This let us
// write unit-tests, as well as helping with debugging.
nll::dump_mir_results(
infcx,
MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None },
&body,
&regioncx,
&opt_closure_req,
);
nll::dump_mir_results(infcx, &body, &regioncx, &opt_closure_req);

// We also have a `#[rustc_regions]` annotation that causes us to dump
// information.
15 changes: 6 additions & 9 deletions compiler/rustc_mir/src/borrow_check/nll.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use rustc_middle::mir::{
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Promoted,
};
use rustc_middle::ty::{self, InstanceDef, RegionKind, RegionVid};
use rustc_middle::ty::{self, RegionKind, RegionVid};
use rustc_span::symbol::sym;
use std::env;
use std::fmt::Debug;
@@ -24,7 +24,6 @@ use polonius_engine::{Algorithm, Output};
use crate::dataflow::impls::MaybeInitializedPlaces;
use crate::dataflow::move_paths::{InitKind, InitLocation, MoveData};
use crate::dataflow::ResultsCursor;
use crate::transform::MirSource;
use crate::util as mir_util;
use crate::util::pretty;

@@ -72,8 +71,7 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
// Replace all remaining regions with fresh inference variables.
renumber::renumber_mir(infcx, body, promoted);

let source = MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None };
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(()));
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, body, |_, _| Ok(()));

universal_regions
}
@@ -315,16 +313,15 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(

pub(super) fn dump_mir_results<'a, 'tcx>(
infcx: &InferCtxt<'a, 'tcx>,
source: MirSource<'tcx>,
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
) {
if !mir_util::dump_enabled(infcx.tcx, "nll", source.def_id()) {
if !mir_util::dump_enabled(infcx.tcx, "nll", body.source.def_id()) {
return;
}

mir_util::dump_mir(infcx.tcx, None, "nll", &0, source, body, |pass_where, out| {
mir_util::dump_mir(infcx.tcx, None, "nll", &0, body, |pass_where, out| {
match pass_where {
// Before the CFG, dump out the values for each region variable.
PassWhere::BeforeCFG => {
@@ -352,14 +349,14 @@ pub(super) fn dump_mir_results<'a, 'tcx>(
// Also dump the inference graph constraints as a graphviz file.
let _: io::Result<()> = try {
let mut file =
pretty::create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, source)?;
pretty::create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, body.source)?;
regioncx.dump_graphviz_raw_constraints(&mut file)?;
};

// Also dump the inference graph constraints as a graphviz file.
let _: io::Result<()> = try {
let mut file =
pretty::create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, source)?;
pretty::create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, body.source)?;
regioncx.dump_graphviz_scc_constraints(&mut file)?;
};
}
37 changes: 21 additions & 16 deletions compiler/rustc_mir/src/shim.rs
Original file line number Diff line number Diff line change
@@ -78,8 +78,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
run_passes(
tcx,
&mut result,
instance,
None,
MirPhase::Const,
&[&[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
@@ -163,7 +161,9 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
block(&mut blocks, TerminatorKind::Goto { target: return_block });
block(&mut blocks, TerminatorKind::Return);

let mut body = new_body(blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
let source = MirSource::from_instance(ty::InstanceDef::DropGlue(def_id, ty));
let mut body =
new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);

if let Some(..) = ty {
// The first argument (index 0), but add 1 for the return value.
@@ -202,12 +202,14 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
}

fn new_body<'tcx>(
source: MirSource<'tcx>,
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
arg_count: usize,
span: Span,
) -> Body<'tcx> {
Body::new(
source,
basic_blocks,
IndexVec::from_elem_n(
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
@@ -344,7 +346,11 @@ impl CloneShimBuilder<'tcx> {
}

fn into_mir(self) -> Body<'tcx> {
new_body(self.blocks, self.local_decls, self.sig.inputs().len(), self.span)
let source = MirSource::from_instance(ty::InstanceDef::CloneShim(
self.def_id,
self.sig.inputs_and_output[0],
));
new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span)
}

fn source_info(&self) -> SourceInfo {
@@ -834,7 +840,8 @@ fn build_call_shim<'tcx>(
block(&mut blocks, vec![], TerminatorKind::Resume, true);
}

let mut body = new_body(blocks, local_decls, sig.inputs().len(), span);
let mut body =
new_body(MirSource::from_instance(instance), blocks, local_decls, sig.inputs().len(), span);

if let Abi::RustCall = sig.abi {
body.spread_arg = Some(Local::new(sig.inputs().len()));
@@ -897,18 +904,16 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
is_cleanup: false,
};

let body =
new_body(IndexVec::from_elem_n(start_block, 1), local_decls, sig.inputs().len(), span);

crate::util::dump_mir(
tcx,
None,
"mir_map",
&0,
crate::transform::MirSource::item(ctor_id),
&body,
|_, _| Ok(()),
let source = MirSource::item(ctor_id);
let body = new_body(
source,
IndexVec::from_elem_n(start_block, 1),
local_decls,
sig.inputs().len(),
span,
);

crate::util::dump_mir(tcx, None, "mir_map", &0, &body, |_, _| Ok(()));

body
}
4 changes: 2 additions & 2 deletions compiler/rustc_mir/src/transform/add_call_guards.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::transform::{MirPass, MirSource};
use crate::transform::MirPass;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
@@ -31,7 +31,7 @@ pub use self::AddCallGuards::*;
*/

impl<'tcx> MirPass<'tcx> for AddCallGuards {
fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
self.add_call_guards(body);
}
}
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;

use crate::transform::{MirPass, MirSource};
use crate::transform::MirPass;
use crate::util;
use crate::util::patch::MirPatch;

@@ -40,9 +40,9 @@ use crate::util::patch::MirPatch;
pub struct AddMovesForPackedDrops;

impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, body.span);
add_moves_for_packed_drops(tcx, body, src.def_id());
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
add_moves_for_packed_drops(tcx, body, body.source.def_id());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
add_moves_for_packed_drops(tcx, body, body.source.def_id());
add_moves_for_packed_drops(tcx, body);

we only use to body source in add_moves_for_packed_drops, don't we?

}
}

6 changes: 3 additions & 3 deletions compiler/rustc_mir/src/transform/add_retag.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
//! of MIR building, and only after this pass we think of the program has having the
//! normal MIR semantics.
use crate::transform::{MirPass, MirSource};
use crate::transform::MirPass;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};

@@ -58,13 +58,13 @@ fn may_be_reference(ty: Ty<'tcx>) -> bool {
}

impl<'tcx> MirPass<'tcx> for AddRetag {
fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if !tcx.sess.opts.debugging_opts.mir_emit_retag {
return;
}

// We need an `AllCallEdges` pass before we can do any work.
super::add_call_guards::AllCallEdges.run_pass(tcx, src, body);
super::add_call_guards::AllCallEdges.run_pass(tcx, body);

let (span, arg_count) = (body.span, body.arg_count);
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
4 changes: 2 additions & 2 deletions compiler/rustc_mir/src/transform/check_const_item_mutation.rs
Original file line number Diff line number Diff line change
@@ -6,12 +6,12 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::CONST_ITEM_MUTATION;
use rustc_span::def_id::DefId;

use crate::transform::{MirPass, MirSource};
use crate::transform::MirPass;

pub struct CheckConstItemMutation;

impl<'tcx> MirPass<'tcx> for CheckConstItemMutation {
fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut checker = ConstMutationChecker { body, tcx, target_local: None };
checker.visit_body(&body);
}
6 changes: 3 additions & 3 deletions compiler/rustc_mir/src/transform/check_packed_ref.rs
Original file line number Diff line number Diff line change
@@ -3,14 +3,14 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::UNALIGNED_REFERENCES;

use crate::transform::{MirPass, MirSource};
use crate::transform::MirPass;
use crate::util;

pub struct CheckPackedRef;

impl<'tcx> MirPass<'tcx> for CheckPackedRef {
fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env(src.instance.def_id());
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env(body.source.def_id());
let source_info = SourceInfo::outermost(body.span);
let mut checker = PackedRefChecker { body, tcx, param_env, source_info };
checker.visit_body(&body);
Loading