Replace (Body, DefId)
with Body
where possible
A `Body` now contains its `MirSource`, which in turn contains the `DefId` of the item associated with the `Body`.
This commit is contained in:
parent
4ccf5f731b
commit
e72e43c730
25 changed files with 159 additions and 232 deletions
|
@ -203,7 +203,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||||
let mdpe = MoveDataParamEnv { move_data, param_env };
|
let mdpe = MoveDataParamEnv { move_data, param_env };
|
||||||
|
|
||||||
let mut flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe)
|
let mut flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe)
|
||||||
.into_engine(tcx, &body, def.did.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.pass_name("borrowck")
|
.pass_name("borrowck")
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(&body);
|
.into_results_cursor(&body);
|
||||||
|
@ -221,7 +221,6 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||||
nll_errors,
|
nll_errors,
|
||||||
} = nll::compute_regions(
|
} = nll::compute_regions(
|
||||||
infcx,
|
infcx,
|
||||||
def.did,
|
|
||||||
free_regions,
|
free_regions,
|
||||||
body,
|
body,
|
||||||
&promoted,
|
&promoted,
|
||||||
|
@ -242,7 +241,6 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||||
nll::dump_annotation(
|
nll::dump_annotation(
|
||||||
infcx,
|
infcx,
|
||||||
&body,
|
&body,
|
||||||
def.did.to_def_id(),
|
|
||||||
®ioncx,
|
®ioncx,
|
||||||
&opt_closure_req,
|
&opt_closure_req,
|
||||||
&opaque_type_values,
|
&opaque_type_values,
|
||||||
|
@ -257,15 +255,15 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||||
let regioncx = Rc::new(regioncx);
|
let regioncx = Rc::new(regioncx);
|
||||||
|
|
||||||
let flow_borrows = Borrows::new(tcx, &body, regioncx.clone(), &borrow_set)
|
let flow_borrows = Borrows::new(tcx, &body, regioncx.clone(), &borrow_set)
|
||||||
.into_engine(tcx, &body, def.did.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.pass_name("borrowck")
|
.pass_name("borrowck")
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
let flow_uninits = MaybeUninitializedPlaces::new(tcx, &body, &mdpe)
|
let flow_uninits = MaybeUninitializedPlaces::new(tcx, &body, &mdpe)
|
||||||
.into_engine(tcx, &body, def.did.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.pass_name("borrowck")
|
.pass_name("borrowck")
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
let flow_ever_inits = EverInitializedPlaces::new(tcx, &body, &mdpe)
|
let flow_ever_inits = EverInitializedPlaces::new(tcx, &body, &mdpe)
|
||||||
.into_engine(tcx, &body, def.did.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.pass_name("borrowck")
|
.pass_name("borrowck")
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,6 @@ fn populate_polonius_move_facts(
|
||||||
/// This may result in errors being reported.
|
/// This may result in errors being reported.
|
||||||
pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
||||||
infcx: &InferCtxt<'cx, 'tcx>,
|
infcx: &InferCtxt<'cx, 'tcx>,
|
||||||
def_id: LocalDefId,
|
|
||||||
universal_regions: UniversalRegions<'tcx>,
|
universal_regions: UniversalRegions<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
promoted: &IndexVec<Promoted, Body<'tcx>>,
|
promoted: &IndexVec<Promoted, Body<'tcx>>,
|
||||||
|
@ -180,7 +179,6 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
||||||
param_env,
|
param_env,
|
||||||
body,
|
body,
|
||||||
promoted,
|
promoted,
|
||||||
def_id,
|
|
||||||
&universal_regions,
|
&universal_regions,
|
||||||
location_table,
|
location_table,
|
||||||
borrow_set,
|
borrow_set,
|
||||||
|
@ -270,10 +268,12 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
||||||
// Generate various additional constraints.
|
// Generate various additional constraints.
|
||||||
invalidation::generate_invalidates(infcx.tcx, &mut all_facts, location_table, body, borrow_set);
|
invalidation::generate_invalidates(infcx.tcx, &mut all_facts, location_table, body, borrow_set);
|
||||||
|
|
||||||
|
let def_id = body.source.def_id();
|
||||||
|
|
||||||
// Dump facts if requested.
|
// Dump facts if requested.
|
||||||
let polonius_output = all_facts.and_then(|all_facts| {
|
let polonius_output = all_facts.and_then(|all_facts| {
|
||||||
if infcx.tcx.sess.opts.debugging_opts.nll_facts {
|
if infcx.tcx.sess.opts.debugging_opts.nll_facts {
|
||||||
let def_path = infcx.tcx.def_path(def_id.to_def_id());
|
let def_path = infcx.tcx.def_path(def_id);
|
||||||
let dir_path =
|
let dir_path =
|
||||||
PathBuf::from("nll-facts").join(def_path.to_filename_friendly_no_crate());
|
PathBuf::from("nll-facts").join(def_path.to_filename_friendly_no_crate());
|
||||||
all_facts.write_to_dir(dir_path, location_table).unwrap();
|
all_facts.write_to_dir(dir_path, location_table).unwrap();
|
||||||
|
@ -293,7 +293,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
||||||
|
|
||||||
// Solve the region constraints.
|
// Solve the region constraints.
|
||||||
let (closure_region_requirements, nll_errors) =
|
let (closure_region_requirements, nll_errors) =
|
||||||
regioncx.solve(infcx, &body, def_id.to_def_id(), polonius_output.clone());
|
regioncx.solve(infcx, &body, def_id, polonius_output.clone());
|
||||||
|
|
||||||
if !nll_errors.is_empty() {
|
if !nll_errors.is_empty() {
|
||||||
// Suppress unhelpful extra errors in `infer_opaque_types`.
|
// Suppress unhelpful extra errors in `infer_opaque_types`.
|
||||||
|
@ -364,14 +364,13 @@ pub(super) fn dump_mir_results<'a, 'tcx>(
|
||||||
pub(super) fn dump_annotation<'a, 'tcx>(
|
pub(super) fn dump_annotation<'a, 'tcx>(
|
||||||
infcx: &InferCtxt<'a, 'tcx>,
|
infcx: &InferCtxt<'a, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
mir_def_id: DefId,
|
|
||||||
regioncx: &RegionInferenceContext<'tcx>,
|
regioncx: &RegionInferenceContext<'tcx>,
|
||||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||||
opaque_type_values: &FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
opaque_type_values: &FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
errors_buffer: &mut Vec<Diagnostic>,
|
errors_buffer: &mut Vec<Diagnostic>,
|
||||||
) {
|
) {
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
let base_def_id = tcx.closure_base_def_id(mir_def_id);
|
let base_def_id = tcx.closure_base_def_id(body.source.def_id());
|
||||||
if !tcx.has_attr(base_def_id, sym::rustc_regions) {
|
if !tcx.has_attr(base_def_id, sym::rustc_regions) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,24 +28,25 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let (&normalized_output_ty, normalized_input_tys) =
|
let (&normalized_output_ty, normalized_input_tys) =
|
||||||
normalized_inputs_and_output.split_last().unwrap();
|
normalized_inputs_and_output.split_last().unwrap();
|
||||||
|
|
||||||
|
let mir_def_id = body.source.def_id().expect_local();
|
||||||
|
|
||||||
// If the user explicitly annotated the input types, extract
|
// If the user explicitly annotated the input types, extract
|
||||||
// those.
|
// those.
|
||||||
//
|
//
|
||||||
// e.g., `|x: FxHashMap<_, &'static u32>| ...`
|
// e.g., `|x: FxHashMap<_, &'static u32>| ...`
|
||||||
let user_provided_sig;
|
let user_provided_sig;
|
||||||
if !self.tcx().is_closure(self.mir_def_id.to_def_id()) {
|
if !self.tcx().is_closure(mir_def_id.to_def_id()) {
|
||||||
user_provided_sig = None;
|
user_provided_sig = None;
|
||||||
} else {
|
} else {
|
||||||
let typeck_results = self.tcx().typeck(self.mir_def_id);
|
let typeck_results = self.tcx().typeck(mir_def_id);
|
||||||
user_provided_sig =
|
user_provided_sig = match typeck_results.user_provided_sigs.get(&mir_def_id.to_def_id())
|
||||||
match typeck_results.user_provided_sigs.get(&self.mir_def_id.to_def_id()) {
|
{
|
||||||
None => None,
|
None => None,
|
||||||
Some(user_provided_poly_sig) => {
|
Some(user_provided_poly_sig) => {
|
||||||
// Instantiate the canonicalized variables from
|
// Instantiate the canonicalized variables from
|
||||||
// user-provided signature (e.g., the `_` in the code
|
// user-provided signature (e.g., the `_` in the code
|
||||||
// above) with fresh variables.
|
// above) with fresh variables.
|
||||||
let (poly_sig, _) =
|
let (poly_sig, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
|
||||||
self.infcx.instantiate_canonical_with_fresh_inference_vars(
|
|
||||||
body.span,
|
body.span,
|
||||||
&user_provided_poly_sig,
|
&user_provided_poly_sig,
|
||||||
);
|
);
|
||||||
|
@ -122,7 +123,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
if let Err(terr) = self.eq_opaque_type_and_type(
|
if let Err(terr) = self.eq_opaque_type_and_type(
|
||||||
mir_output_ty,
|
mir_output_ty,
|
||||||
normalized_output_ty,
|
normalized_output_ty,
|
||||||
self.mir_def_id,
|
mir_def_id,
|
||||||
Locations::All(output_span),
|
Locations::All(output_span),
|
||||||
ConstraintCategory::BoringNoLocation,
|
ConstraintCategory::BoringNoLocation,
|
||||||
) {
|
) {
|
||||||
|
@ -145,7 +146,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
if let Err(err) = self.eq_opaque_type_and_type(
|
if let Err(err) = self.eq_opaque_type_and_type(
|
||||||
mir_output_ty,
|
mir_output_ty,
|
||||||
user_provided_output_ty,
|
user_provided_output_ty,
|
||||||
self.mir_def_id,
|
mir_def_id,
|
||||||
Locations::All(output_span),
|
Locations::All(output_span),
|
||||||
ConstraintCategory::BoringNoLocation,
|
ConstraintCategory::BoringNoLocation,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ macro_rules! span_mirbug {
|
||||||
$context.last_span,
|
$context.last_span,
|
||||||
&format!(
|
&format!(
|
||||||
"broken MIR in {:?} ({:?}): {}",
|
"broken MIR in {:?} ({:?}): {}",
|
||||||
$context.mir_def_id,
|
$context.body.source.def_id(),
|
||||||
$elem,
|
$elem,
|
||||||
format_args!($($message)*),
|
format_args!($($message)*),
|
||||||
),
|
),
|
||||||
|
@ -113,7 +113,6 @@ mod relate_tys;
|
||||||
/// - `param_env` -- parameter environment to use for trait solving
|
/// - `param_env` -- parameter environment to use for trait solving
|
||||||
/// - `body` -- MIR body to type-check
|
/// - `body` -- MIR body to type-check
|
||||||
/// - `promoted` -- map of promoted constants within `body`
|
/// - `promoted` -- map of promoted constants within `body`
|
||||||
/// - `mir_def_id` -- `LocalDefId` from which the MIR is derived
|
|
||||||
/// - `universal_regions` -- the universal regions from `body`s function signature
|
/// - `universal_regions` -- the universal regions from `body`s function signature
|
||||||
/// - `location_table` -- MIR location map of `body`
|
/// - `location_table` -- MIR location map of `body`
|
||||||
/// - `borrow_set` -- information about borrows occurring in `body`
|
/// - `borrow_set` -- information about borrows occurring in `body`
|
||||||
|
@ -126,7 +125,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
promoted: &IndexVec<Promoted, Body<'tcx>>,
|
promoted: &IndexVec<Promoted, Body<'tcx>>,
|
||||||
mir_def_id: LocalDefId,
|
|
||||||
universal_regions: &Rc<UniversalRegions<'tcx>>,
|
universal_regions: &Rc<UniversalRegions<'tcx>>,
|
||||||
location_table: &LocationTable,
|
location_table: &LocationTable,
|
||||||
borrow_set: &BorrowSet<'tcx>,
|
borrow_set: &BorrowSet<'tcx>,
|
||||||
|
@ -170,7 +168,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
|
|
||||||
let opaque_type_values = type_check_internal(
|
let opaque_type_values = type_check_internal(
|
||||||
infcx,
|
infcx,
|
||||||
mir_def_id,
|
|
||||||
param_env,
|
param_env,
|
||||||
body,
|
body,
|
||||||
promoted,
|
promoted,
|
||||||
|
@ -192,7 +189,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
|
|
||||||
fn type_check_internal<'a, 'tcx, R>(
|
fn type_check_internal<'a, 'tcx, R>(
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
mir_def_id: LocalDefId,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
promoted: &'a IndexVec<Promoted, Body<'tcx>>,
|
promoted: &'a IndexVec<Promoted, Body<'tcx>>,
|
||||||
|
@ -205,7 +201,6 @@ fn type_check_internal<'a, 'tcx, R>(
|
||||||
let mut checker = TypeChecker::new(
|
let mut checker = TypeChecker::new(
|
||||||
infcx,
|
infcx,
|
||||||
body,
|
body,
|
||||||
mir_def_id,
|
|
||||||
param_env,
|
param_env,
|
||||||
region_bound_pairs,
|
region_bound_pairs,
|
||||||
implicit_region_bound,
|
implicit_region_bound,
|
||||||
|
@ -272,7 +267,6 @@ struct TypeVerifier<'a, 'b, 'tcx> {
|
||||||
body: &'b Body<'tcx>,
|
body: &'b Body<'tcx>,
|
||||||
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
|
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
|
||||||
last_span: Span,
|
last_span: Span,
|
||||||
mir_def_id: LocalDefId,
|
|
||||||
errors_reported: bool,
|
errors_reported: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,14 +454,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
body: &'b Body<'tcx>,
|
body: &'b Body<'tcx>,
|
||||||
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
|
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
TypeVerifier {
|
TypeVerifier { body, promoted, cx, last_span: body.span, errors_reported: false }
|
||||||
body,
|
|
||||||
promoted,
|
|
||||||
mir_def_id: cx.mir_def_id,
|
|
||||||
cx,
|
|
||||||
last_span: body.span,
|
|
||||||
errors_reported: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
|
@ -816,7 +803,6 @@ struct TypeChecker<'a, 'tcx> {
|
||||||
/// User type annotations are shared between the main MIR and the MIR of
|
/// User type annotations are shared between the main MIR and the MIR of
|
||||||
/// all of the promoted items.
|
/// all of the promoted items.
|
||||||
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
|
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
|
||||||
mir_def_id: LocalDefId,
|
|
||||||
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
||||||
implicit_region_bound: ty::Region<'tcx>,
|
implicit_region_bound: ty::Region<'tcx>,
|
||||||
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
|
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
|
||||||
|
@ -965,7 +951,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
mir_def_id: LocalDefId,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
||||||
implicit_region_bound: ty::Region<'tcx>,
|
implicit_region_bound: ty::Region<'tcx>,
|
||||||
|
@ -975,7 +960,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let mut checker = Self {
|
let mut checker = Self {
|
||||||
infcx,
|
infcx,
|
||||||
last_span: DUMMY_SP,
|
last_span: DUMMY_SP,
|
||||||
mir_def_id,
|
|
||||||
body,
|
body,
|
||||||
user_type_annotations: &body.user_type_annotations,
|
user_type_annotations: &body.user_type_annotations,
|
||||||
param_env,
|
param_env,
|
||||||
|
@ -1145,7 +1129,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
// the resulting inferend values are stored with the
|
// the resulting inferend values are stored with the
|
||||||
// def-id of the base function.
|
// def-id of the base function.
|
||||||
let parent_def_id =
|
let parent_def_id =
|
||||||
self.tcx().closure_base_def_id(self.mir_def_id.to_def_id()).expect_local();
|
self.tcx().closure_base_def_id(self.body.source.def_id()).expect_local();
|
||||||
return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
|
return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
|
||||||
} else {
|
} else {
|
||||||
return Err(terr);
|
return Err(terr);
|
||||||
|
@ -1242,7 +1226,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
|
let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
|
||||||
let mut opaque_type_values = Vec::new();
|
let mut opaque_type_values = Vec::new();
|
||||||
|
|
||||||
debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id);
|
debug!("eq_opaque_type_and_type: mir_def_id={:?}", body.source.def_id());
|
||||||
let opaque_type_map = self.fully_perform_op(
|
let opaque_type_map = self.fully_perform_op(
|
||||||
locations,
|
locations,
|
||||||
category,
|
category,
|
||||||
|
@ -2001,12 +1985,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let span = body.source_info(location).span;
|
let span = body.source_info(location).span;
|
||||||
let ty = operand.ty(body, tcx);
|
let ty = operand.ty(body, tcx);
|
||||||
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
|
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
|
||||||
let ccx = ConstCx::new_with_param_env(
|
let ccx = ConstCx::new_with_param_env(tcx, body, self.param_env);
|
||||||
tcx,
|
|
||||||
self.mir_def_id,
|
|
||||||
body,
|
|
||||||
self.param_env,
|
|
||||||
);
|
|
||||||
// To determine if `const_in_array_repeat_expressions` feature gate should
|
// To determine if `const_in_array_repeat_expressions` feature gate should
|
||||||
// be mentioned, need to check if the rvalue is promotable.
|
// be mentioned, need to check if the rvalue is promotable.
|
||||||
let should_suggest =
|
let should_suggest =
|
||||||
|
@ -2015,11 +1994,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
debug!("check_rvalue: should_suggest={:?}", should_suggest);
|
debug!("check_rvalue: should_suggest={:?}", should_suggest);
|
||||||
|
|
||||||
|
let def_id = body.source.def_id().expect_local();
|
||||||
self.infcx.report_selection_error(
|
self.infcx.report_selection_error(
|
||||||
&traits::Obligation::new(
|
&traits::Obligation::new(
|
||||||
ObligationCause::new(
|
ObligationCause::new(
|
||||||
span,
|
span,
|
||||||
self.tcx().hir().local_def_id_to_hir_id(self.mir_def_id),
|
self.tcx().hir().local_def_id_to_hir_id(def_id),
|
||||||
traits::ObligationCauseCode::RepeatVec(should_suggest),
|
traits::ObligationCauseCode::RepeatVec(should_suggest),
|
||||||
),
|
),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
|
|
@ -81,7 +81,6 @@ where
|
||||||
{
|
{
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a mir::Body<'tcx>,
|
body: &'a mir::Body<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
dead_unwinds: Option<&'a BitSet<BasicBlock>>,
|
dead_unwinds: Option<&'a BitSet<BasicBlock>>,
|
||||||
entry_sets: IndexVec<BasicBlock, A::Domain>,
|
entry_sets: IndexVec<BasicBlock, A::Domain>,
|
||||||
pass_name: Option<&'static str>,
|
pass_name: Option<&'static str>,
|
||||||
|
@ -103,18 +102,13 @@ where
|
||||||
T: Idx,
|
T: Idx,
|
||||||
{
|
{
|
||||||
/// Creates a new `Engine` to solve a gen-kill dataflow problem.
|
/// Creates a new `Engine` to solve a gen-kill dataflow problem.
|
||||||
pub fn new_gen_kill(
|
pub fn new_gen_kill(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, analysis: A) -> Self {
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
body: &'a mir::Body<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
analysis: A,
|
|
||||||
) -> Self {
|
|
||||||
// If there are no back-edges in the control-flow graph, we only ever need to apply the
|
// If there are no back-edges in the control-flow graph, we only ever need to apply the
|
||||||
// transfer function for each block exactly once (assuming that we process blocks in RPO).
|
// transfer function for each block exactly once (assuming that we process blocks in RPO).
|
||||||
//
|
//
|
||||||
// In this case, there's no need to compute the block transfer functions ahead of time.
|
// In this case, there's no need to compute the block transfer functions ahead of time.
|
||||||
if !body.is_cfg_cyclic() {
|
if !body.is_cfg_cyclic() {
|
||||||
return Self::new(tcx, body, def_id, analysis, None);
|
return Self::new(tcx, body, analysis, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, compute and store the cumulative transfer function for each block.
|
// Otherwise, compute and store the cumulative transfer function for each block.
|
||||||
|
@ -131,7 +125,7 @@ where
|
||||||
trans_for_block[bb].apply(state.borrow_mut());
|
trans_for_block[bb].apply(state.borrow_mut());
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new(tcx, body, def_id, analysis, Some(apply_trans as Box<_>))
|
Self::new(tcx, body, analysis, Some(apply_trans as Box<_>))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,19 +139,13 @@ where
|
||||||
///
|
///
|
||||||
/// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for
|
/// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for
|
||||||
/// better performance.
|
/// better performance.
|
||||||
pub fn new_generic(
|
pub fn new_generic(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, analysis: A) -> Self {
|
||||||
tcx: TyCtxt<'tcx>,
|
Self::new(tcx, body, analysis, None)
|
||||||
body: &'a mir::Body<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
analysis: A,
|
|
||||||
) -> Self {
|
|
||||||
Self::new(tcx, body, def_id, analysis, None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(
|
fn new(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a mir::Body<'tcx>,
|
body: &'a mir::Body<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
analysis: A,
|
analysis: A,
|
||||||
apply_trans_for_block: Option<Box<dyn Fn(BasicBlock, &mut A::Domain)>>,
|
apply_trans_for_block: Option<Box<dyn Fn(BasicBlock, &mut A::Domain)>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -173,7 +161,6 @@ where
|
||||||
analysis,
|
analysis,
|
||||||
tcx,
|
tcx,
|
||||||
body,
|
body,
|
||||||
def_id,
|
|
||||||
dead_unwinds: None,
|
dead_unwinds: None,
|
||||||
pass_name: None,
|
pass_name: None,
|
||||||
entry_sets,
|
entry_sets,
|
||||||
|
@ -209,7 +196,6 @@ where
|
||||||
analysis,
|
analysis,
|
||||||
body,
|
body,
|
||||||
dead_unwinds,
|
dead_unwinds,
|
||||||
def_id,
|
|
||||||
mut entry_sets,
|
mut entry_sets,
|
||||||
tcx,
|
tcx,
|
||||||
apply_trans_for_block,
|
apply_trans_for_block,
|
||||||
|
@ -261,7 +247,7 @@ where
|
||||||
|
|
||||||
let results = Results { analysis, entry_sets };
|
let results = Results { analysis, entry_sets };
|
||||||
|
|
||||||
let res = write_graphviz_results(tcx, def_id, &body, &results, pass_name);
|
let res = write_graphviz_results(tcx, &body, &results, pass_name);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
warn!("Failed to write graphviz dataflow results: {}", e);
|
warn!("Failed to write graphviz dataflow results: {}", e);
|
||||||
}
|
}
|
||||||
|
@ -276,7 +262,6 @@ where
|
||||||
/// `rustc_mir` attributes.
|
/// `rustc_mir` attributes.
|
||||||
fn write_graphviz_results<A>(
|
fn write_graphviz_results<A>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
body: &mir::Body<'tcx>,
|
body: &mir::Body<'tcx>,
|
||||||
results: &Results<'tcx, A>,
|
results: &Results<'tcx, A>,
|
||||||
pass_name: Option<&'static str>,
|
pass_name: Option<&'static str>,
|
||||||
|
@ -285,6 +270,7 @@ where
|
||||||
A: Analysis<'tcx>,
|
A: Analysis<'tcx>,
|
||||||
A::Domain: DebugWithContext<A>,
|
A::Domain: DebugWithContext<A>,
|
||||||
{
|
{
|
||||||
|
let def_id = body.source.def_id();
|
||||||
let attrs = match RustcMirAttrs::parse(tcx, def_id) {
|
let attrs = match RustcMirAttrs::parse(tcx, def_id) {
|
||||||
Ok(attrs) => attrs,
|
Ok(attrs) => attrs,
|
||||||
|
|
||||||
|
@ -323,7 +309,7 @@ where
|
||||||
debug!("printing dataflow results for {:?} to {}", def_id, path.display());
|
debug!("printing dataflow results for {:?} to {}", def_id, path.display());
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
let graphviz = graphviz::Formatter::new(body, def_id, results, style);
|
let graphviz = graphviz::Formatter::new(body, results, style);
|
||||||
let mut render_opts =
|
let mut render_opts =
|
||||||
vec![dot::RenderOption::Fontname(tcx.sess.opts.debugging_opts.graphviz_font.clone())];
|
vec![dot::RenderOption::Fontname(tcx.sess.opts.debugging_opts.graphviz_font.clone())];
|
||||||
if tcx.sess.opts.debugging_opts.graphviz_dark_mode {
|
if tcx.sess.opts.debugging_opts.graphviz_dark_mode {
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::{io, ops, str};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustc_graphviz as dot;
|
use rustc_graphviz as dot;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_middle::mir::{self, BasicBlock, Body, Location};
|
use rustc_middle::mir::{self, BasicBlock, Body, Location};
|
||||||
|
|
||||||
use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext};
|
use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext};
|
||||||
|
@ -33,7 +32,6 @@ where
|
||||||
A: Analysis<'tcx>,
|
A: Analysis<'tcx>,
|
||||||
{
|
{
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
results: &'a Results<'tcx, A>,
|
results: &'a Results<'tcx, A>,
|
||||||
style: OutputStyle,
|
style: OutputStyle,
|
||||||
}
|
}
|
||||||
|
@ -42,13 +40,8 @@ impl<A> Formatter<'a, 'tcx, A>
|
||||||
where
|
where
|
||||||
A: Analysis<'tcx>,
|
A: Analysis<'tcx>,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(body: &'a Body<'tcx>, results: &'a Results<'tcx, A>, style: OutputStyle) -> Self {
|
||||||
body: &'a Body<'tcx>,
|
Formatter { body, results, style }
|
||||||
def_id: DefId,
|
|
||||||
results: &'a Results<'tcx, A>,
|
|
||||||
style: OutputStyle,
|
|
||||||
) -> Self {
|
|
||||||
Formatter { body, def_id, results, style }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +70,7 @@ where
|
||||||
type Edge = CfgEdge;
|
type Edge = CfgEdge;
|
||||||
|
|
||||||
fn graph_id(&self) -> dot::Id<'_> {
|
fn graph_id(&self) -> dot::Id<'_> {
|
||||||
let name = graphviz_safe_def_name(self.def_id);
|
let name = graphviz_safe_def_name(self.body.source.def_id());
|
||||||
dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap()
|
dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
//! ```ignore(cross-crate-imports)
|
//! ```ignore(cross-crate-imports)
|
||||||
//! use rustc_mir::dataflow::Analysis; // Makes `into_engine` available.
|
//! use rustc_mir::dataflow::Analysis; // Makes `into_engine` available.
|
||||||
//!
|
//!
|
||||||
//! fn do_my_analysis(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, did: DefId) {
|
//! fn do_my_analysis(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
|
||||||
//! let analysis = MyAnalysis::new()
|
//! let analysis = MyAnalysis::new()
|
||||||
//! .into_engine(tcx, body, did)
|
//! .into_engine(tcx, body)
|
||||||
//! .iterate_to_fixpoint()
|
//! .iterate_to_fixpoint()
|
||||||
//! .into_results_cursor(body);
|
//! .into_results_cursor(body);
|
||||||
//!
|
//!
|
||||||
|
@ -33,7 +33,6 @@
|
||||||
use std::borrow::BorrowMut;
|
use std::borrow::BorrowMut;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_index::bit_set::{BitSet, HybridBitSet};
|
use rustc_index::bit_set::{BitSet, HybridBitSet};
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_middle::mir::{self, BasicBlock, Location};
|
use rustc_middle::mir::{self, BasicBlock, Location};
|
||||||
|
@ -218,16 +217,11 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
|
||||||
/// .iterate_to_fixpoint()
|
/// .iterate_to_fixpoint()
|
||||||
/// .into_results_cursor(body);
|
/// .into_results_cursor(body);
|
||||||
/// ```
|
/// ```
|
||||||
fn into_engine(
|
fn into_engine(self, tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Engine<'mir, 'tcx, Self>
|
||||||
self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
body: &'mir mir::Body<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> Engine<'mir, 'tcx, Self>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Engine::new_generic(tcx, body, def_id, self)
|
Engine::new_generic(tcx, body, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,16 +375,11 @@ where
|
||||||
|
|
||||||
/* Extension methods */
|
/* Extension methods */
|
||||||
|
|
||||||
fn into_engine(
|
fn into_engine(self, tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Engine<'mir, 'tcx, Self>
|
||||||
self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
body: &'mir mir::Body<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> Engine<'mir, 'tcx, Self>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Engine::new_gen_kill(tcx, body, def_id, self)
|
Engine::new_gen_kill(tcx, body, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
|
@ -42,20 +41,17 @@ pub struct AddMovesForPackedDrops;
|
||||||
impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
|
impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
|
||||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
|
debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
|
||||||
add_moves_for_packed_drops(tcx, body, body.source.def_id());
|
add_moves_for_packed_drops(tcx, body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, def_id: DefId) {
|
pub fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
let patch = add_moves_for_packed_drops_patch(tcx, body, def_id);
|
let patch = add_moves_for_packed_drops_patch(tcx, body);
|
||||||
patch.apply(body);
|
patch.apply(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_moves_for_packed_drops_patch<'tcx>(
|
fn add_moves_for_packed_drops_patch<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> MirPatch<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
let def_id = body.source.def_id();
|
||||||
body: &Body<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> MirPatch<'tcx> {
|
|
||||||
let mut patch = MirPatch::new(body);
|
let mut patch = MirPatch::new(body);
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
|
|
||||||
|
|
|
@ -24,25 +24,28 @@ pub mod validation;
|
||||||
pub struct ConstCx<'mir, 'tcx> {
|
pub struct ConstCx<'mir, 'tcx> {
|
||||||
pub body: &'mir mir::Body<'tcx>,
|
pub body: &'mir mir::Body<'tcx>,
|
||||||
pub tcx: TyCtxt<'tcx>,
|
pub tcx: TyCtxt<'tcx>,
|
||||||
pub def_id: LocalDefId,
|
|
||||||
pub param_env: ty::ParamEnv<'tcx>,
|
pub param_env: ty::ParamEnv<'tcx>,
|
||||||
pub const_kind: Option<hir::ConstContext>,
|
pub const_kind: Option<hir::ConstContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstCx<'mir, 'tcx> {
|
impl ConstCx<'mir, 'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'mir mir::Body<'tcx>) -> Self {
|
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
|
||||||
|
let def_id = body.source.def_id().expect_local();
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
Self::new_with_param_env(tcx, def_id, body, param_env)
|
Self::new_with_param_env(tcx, body, param_env)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_param_env(
|
pub fn new_with_param_env(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
|
||||||
body: &'mir mir::Body<'tcx>,
|
body: &'mir mir::Body<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let const_kind = tcx.hir().body_const_context(def_id);
|
let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
|
||||||
ConstCx { body, tcx, def_id: def_id, param_env, const_kind }
|
ConstCx { body, tcx, param_env, const_kind }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn def_id(&self) -> LocalDefId {
|
||||||
|
self.body.source.def_id().expect_local()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the kind of const context this `Item` represents (`const`, `static`, etc.).
|
/// Returns the kind of const context this `Item` represents (`const`, `static`, etc.).
|
||||||
|
@ -55,7 +58,7 @@ impl ConstCx<'mir, 'tcx> {
|
||||||
pub fn is_const_stable_const_fn(&self) -> bool {
|
pub fn is_const_stable_const_fn(&self) -> bool {
|
||||||
self.const_kind == Some(hir::ConstContext::ConstFn)
|
self.const_kind == Some(hir::ConstContext::ConstFn)
|
||||||
&& self.tcx.features().staged_api
|
&& self.tcx.features().staged_api
|
||||||
&& is_const_stable_const_fn(self.tcx, self.def_id.to_def_id())
|
&& is_const_stable_const_fn(self.tcx, self.def_id().to_def_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the function signature of the item being const-checked if it is a `fn` or `const fn`.
|
/// Returns the function signature of the item being const-checked if it is a `fn` or `const fn`.
|
||||||
|
@ -64,7 +67,7 @@ impl ConstCx<'mir, 'tcx> {
|
||||||
//
|
//
|
||||||
// FIXME: Is this still an issue?
|
// FIXME: Is this still an issue?
|
||||||
let hir_map = self.tcx.hir();
|
let hir_map = self.tcx.hir();
|
||||||
let hir_id = hir_map.local_def_id_to_hir_id(self.def_id);
|
let hir_id = hir_map.local_def_id_to_hir_id(self.def_id());
|
||||||
hir_map.fn_sig_by_hir_id(hir_id)
|
hir_map.fn_sig_by_hir_id(hir_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use rustc_hir::def_id::LocalDefId;
|
|
||||||
use rustc_middle::mir::visit::Visitor;
|
use rustc_middle::mir::visit::Visitor;
|
||||||
use rustc_middle::mir::{self, BasicBlock, Location};
|
use rustc_middle::mir::{self, BasicBlock, Location};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
@ -24,13 +23,14 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
|
||||||
///
|
///
|
||||||
/// This is separate from the rest of the const checking logic because it must run after drop
|
/// This is separate from the rest of the const checking logic because it must run after drop
|
||||||
/// elaboration.
|
/// elaboration.
|
||||||
pub fn check_live_drops(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &mir::Body<'tcx>) {
|
pub fn check_live_drops(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
|
||||||
|
let def_id = body.source.def_id().expect_local();
|
||||||
let const_kind = tcx.hir().body_const_context(def_id);
|
let const_kind = tcx.hir().body_const_context(def_id);
|
||||||
if const_kind.is_none() {
|
if const_kind.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ccx = ConstCx { body, tcx, def_id, const_kind, param_env: tcx.param_env(def_id) };
|
let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) };
|
||||||
if !checking_enabled(&ccx) {
|
if !checking_enabled(&ccx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ impl Qualif for CustomEq {
|
||||||
// because that component may be part of an enum variant (e.g.,
|
// because that component may be part of an enum variant (e.g.,
|
||||||
// `Option::<NonStructuralMatchTy>::Some`), in which case some values of this type may be
|
// `Option::<NonStructuralMatchTy>::Some`), in which case some values of this type may be
|
||||||
// structural-match (`Option::None`).
|
// structural-match (`Option::None`).
|
||||||
let id = cx.tcx.hir().local_def_id_to_hir_id(cx.def_id);
|
let id = cx.tcx.hir().local_def_id_to_hir_id(cx.def_id());
|
||||||
traits::search_for_structural_match_violation(id, cx.body.span, cx.tcx, ty).is_some()
|
traits::search_for_structural_match_violation(id, cx.body.span, cx.tcx, ty).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl Qualifs<'mir, 'tcx> {
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let indirectly_mutable = self.indirectly_mutable.get_or_insert_with(|| {
|
let indirectly_mutable = self.indirectly_mutable.get_or_insert_with(|| {
|
||||||
let ConstCx { tcx, body, def_id, param_env, .. } = *ccx;
|
let ConstCx { tcx, body, param_env, .. } = *ccx;
|
||||||
|
|
||||||
// We can use `unsound_ignore_borrow_on_drop` here because custom drop impls are not
|
// We can use `unsound_ignore_borrow_on_drop` here because custom drop impls are not
|
||||||
// allowed in a const.
|
// allowed in a const.
|
||||||
|
@ -59,7 +59,7 @@ impl Qualifs<'mir, 'tcx> {
|
||||||
// without breaking stable code?
|
// without breaking stable code?
|
||||||
MaybeMutBorrowedLocals::mut_borrows_only(tcx, &body, param_env)
|
MaybeMutBorrowedLocals::mut_borrows_only(tcx, &body, param_env)
|
||||||
.unsound_ignore_borrow_on_drop()
|
.unsound_ignore_borrow_on_drop()
|
||||||
.into_engine(tcx, &body, def_id.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.pass_name("const_qualification")
|
.pass_name("const_qualification")
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(&body)
|
.into_results_cursor(&body)
|
||||||
|
@ -84,10 +84,10 @@ impl Qualifs<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let needs_drop = self.needs_drop.get_or_insert_with(|| {
|
let needs_drop = self.needs_drop.get_or_insert_with(|| {
|
||||||
let ConstCx { tcx, body, def_id, .. } = *ccx;
|
let ConstCx { tcx, body, .. } = *ccx;
|
||||||
|
|
||||||
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
|
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
|
||||||
.into_engine(tcx, &body, def_id.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(&body)
|
.into_results_cursor(&body)
|
||||||
});
|
});
|
||||||
|
@ -111,10 +111,10 @@ impl Qualifs<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_mut_interior = self.has_mut_interior.get_or_insert_with(|| {
|
let has_mut_interior = self.has_mut_interior.get_or_insert_with(|| {
|
||||||
let ConstCx { tcx, body, def_id, .. } = *ccx;
|
let ConstCx { tcx, body, .. } = *ccx;
|
||||||
|
|
||||||
FlowSensitiveAnalysis::new(HasMutInterior, ccx)
|
FlowSensitiveAnalysis::new(HasMutInterior, ccx)
|
||||||
.into_engine(tcx, &body, def_id.to_def_id())
|
.into_engine(tcx, &body)
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(&body)
|
.into_results_cursor(&body)
|
||||||
});
|
});
|
||||||
|
@ -157,7 +157,7 @@ impl Qualifs<'mir, 'tcx> {
|
||||||
|
|
||||||
hir::ConstContext::Const | hir::ConstContext::Static(_) => {
|
hir::ConstContext::Const | hir::ConstContext::Static(_) => {
|
||||||
let mut cursor = FlowSensitiveAnalysis::new(CustomEq, ccx)
|
let mut cursor = FlowSensitiveAnalysis::new(CustomEq, ccx)
|
||||||
.into_engine(ccx.tcx, &ccx.body, ccx.def_id.to_def_id())
|
.into_engine(ccx.tcx, &ccx.body)
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(&ccx.body);
|
.into_results_cursor(&ccx.body);
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ impl Validator<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_body(&mut self) {
|
pub fn check_body(&mut self) {
|
||||||
let ConstCx { tcx, body, def_id, .. } = *self.ccx;
|
let ConstCx { tcx, body, .. } = *self.ccx;
|
||||||
|
let def_id = self.ccx.def_id();
|
||||||
|
|
||||||
// `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
|
// `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
|
||||||
// no need to emit duplicate errors here.
|
// no need to emit duplicate errors here.
|
||||||
|
@ -219,7 +220,7 @@ impl Validator<'mir, 'tcx> {
|
||||||
// Prevent const trait methods from being annotated as `stable`.
|
// Prevent const trait methods from being annotated as `stable`.
|
||||||
// FIXME: Do this as part of stability checking.
|
// FIXME: Do this as part of stability checking.
|
||||||
if self.is_const_stable_const_fn() {
|
if self.is_const_stable_const_fn() {
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(self.def_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
if crate::const_eval::is_parent_const_impl_raw(tcx, hir_id) {
|
if crate::const_eval::is_parent_const_impl_raw(tcx, hir_id) {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
self.ccx.tcx.sess,
|
self.ccx.tcx.sess,
|
||||||
|
@ -291,7 +292,7 @@ impl Validator<'mir, 'tcx> {
|
||||||
|
|
||||||
Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
|
Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
|
||||||
let unstable_in_stable = self.ccx.is_const_stable_const_fn()
|
let unstable_in_stable = self.ccx.is_const_stable_const_fn()
|
||||||
&& !super::allow_internal_unstable(self.tcx, self.def_id.to_def_id(), gate);
|
&& !super::allow_internal_unstable(self.tcx, self.def_id().to_def_id(), gate);
|
||||||
if unstable_in_stable {
|
if unstable_in_stable {
|
||||||
emit_unstable_in_stable_error(self.ccx, span, gate);
|
emit_unstable_in_stable_error(self.ccx, span, gate);
|
||||||
}
|
}
|
||||||
|
@ -367,9 +368,9 @@ impl Validator<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item_predicates(&mut self) {
|
fn check_item_predicates(&mut self) {
|
||||||
let ConstCx { tcx, def_id, .. } = *self.ccx;
|
let ConstCx { tcx, .. } = *self.ccx;
|
||||||
|
|
||||||
let mut current = def_id.to_def_id();
|
let mut current = self.def_id().to_def_id();
|
||||||
loop {
|
loop {
|
||||||
let predicates = tcx.predicates_of(current);
|
let predicates = tcx.predicates_of(current);
|
||||||
for (predicate, _) in predicates.predicates {
|
for (predicate, _) in predicates.predicates {
|
||||||
|
@ -734,8 +735,8 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||||
|
|
||||||
match &terminator.kind {
|
match &terminator.kind {
|
||||||
TerminatorKind::Call { func, .. } => {
|
TerminatorKind::Call { func, .. } => {
|
||||||
let ConstCx { tcx, body, def_id: caller, param_env, .. } = *self.ccx;
|
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
|
||||||
let caller = caller.to_def_id();
|
let caller = self.def_id().to_def_id();
|
||||||
|
|
||||||
let fn_ty = func.ty(body, tcx);
|
let fn_ty = func.ty(body, tcx);
|
||||||
|
|
||||||
|
|
|
@ -408,15 +408,12 @@ impl Conflicts<'a> {
|
||||||
body.local_decls.len(),
|
body.local_decls.len(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let def_id = body.source.def_id();
|
|
||||||
let mut init = MaybeInitializedLocals
|
let mut init = MaybeInitializedLocals
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.iterate_to_fixpoint()
|
|
||||||
.into_results_cursor(body);
|
|
||||||
let mut live = MaybeLiveLocals
|
|
||||||
.into_engine(tcx, body, def_id)
|
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(body);
|
.into_results_cursor(body);
|
||||||
|
let mut live =
|
||||||
|
MaybeLiveLocals.into_engine(tcx, body).iterate_to_fixpoint().into_results_cursor(body);
|
||||||
|
|
||||||
let mut reachable = None;
|
let mut reachable = None;
|
||||||
dump_mir(tcx, None, "DestinationPropagation-dataflow", &"", body, |pass_where, w| {
|
dump_mir(tcx, None, "DestinationPropagation-dataflow", &"", body, |pass_where, w| {
|
||||||
|
|
|
@ -10,7 +10,6 @@ use crate::util::elaborate_drops::{elaborate_drop, DropFlagState, Unwind};
|
||||||
use crate::util::elaborate_drops::{DropElaborator, DropFlagMode, DropStyle};
|
use crate::util::elaborate_drops::{DropElaborator, DropFlagMode, DropStyle};
|
||||||
use crate::util::patch::MirPatch;
|
use crate::util::patch::MirPatch;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
@ -39,10 +38,10 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||||
let elaborate_patch = {
|
let elaborate_patch = {
|
||||||
let body = &*body;
|
let body = &*body;
|
||||||
let env = MoveDataParamEnv { move_data, param_env };
|
let env = MoveDataParamEnv { move_data, param_env };
|
||||||
let dead_unwinds = find_dead_unwinds(tcx, body, def_id, &env);
|
let dead_unwinds = find_dead_unwinds(tcx, body, &env);
|
||||||
|
|
||||||
let inits = MaybeInitializedPlaces::new(tcx, body, &env)
|
let inits = MaybeInitializedPlaces::new(tcx, body, &env)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.dead_unwinds(&dead_unwinds)
|
.dead_unwinds(&dead_unwinds)
|
||||||
.pass_name("elaborate_drops")
|
.pass_name("elaborate_drops")
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
|
@ -50,7 +49,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||||
|
|
||||||
let uninits = MaybeUninitializedPlaces::new(tcx, body, &env)
|
let uninits = MaybeUninitializedPlaces::new(tcx, body, &env)
|
||||||
.mark_inactive_variants_as_uninit()
|
.mark_inactive_variants_as_uninit()
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.dead_unwinds(&dead_unwinds)
|
.dead_unwinds(&dead_unwinds)
|
||||||
.pass_name("elaborate_drops")
|
.pass_name("elaborate_drops")
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
|
@ -76,7 +75,6 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||||
fn find_dead_unwinds<'tcx>(
|
fn find_dead_unwinds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
def_id: hir::def_id::DefId,
|
|
||||||
env: &MoveDataParamEnv<'tcx>,
|
env: &MoveDataParamEnv<'tcx>,
|
||||||
) -> BitSet<BasicBlock> {
|
) -> BitSet<BasicBlock> {
|
||||||
debug!("find_dead_unwinds({:?})", body.span);
|
debug!("find_dead_unwinds({:?})", body.span);
|
||||||
|
@ -84,7 +82,7 @@ fn find_dead_unwinds<'tcx>(
|
||||||
// reach cleanup blocks, which can't have unwind edges themselves.
|
// reach cleanup blocks, which can't have unwind edges themselves.
|
||||||
let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
|
let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
|
||||||
let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env)
|
let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.pass_name("find_dead_unwinds")
|
.pass_name("find_dead_unwinds")
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(body);
|
.into_results_cursor(body);
|
||||||
|
|
|
@ -61,7 +61,6 @@ use crate::util::expand_aggregate;
|
||||||
use crate::util::storage;
|
use crate::util::storage;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::bit_set::{BitMatrix, BitSet};
|
use rustc_index::bit_set::{BitMatrix, BitSet};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
|
@ -454,20 +453,19 @@ fn locals_live_across_suspend_points(
|
||||||
always_live_locals: &storage::AlwaysLiveLocals,
|
always_live_locals: &storage::AlwaysLiveLocals,
|
||||||
movable: bool,
|
movable: bool,
|
||||||
) -> LivenessInfo {
|
) -> LivenessInfo {
|
||||||
let def_id = body.source.def_id();
|
|
||||||
let body_ref: &Body<'_> = &body;
|
let body_ref: &Body<'_> = &body;
|
||||||
|
|
||||||
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
||||||
// lifetimes.
|
// lifetimes.
|
||||||
let mut storage_live = MaybeStorageLive::new(always_live_locals.clone())
|
let mut storage_live = MaybeStorageLive::new(always_live_locals.clone())
|
||||||
.into_engine(tcx, body_ref, def_id)
|
.into_engine(tcx, body_ref)
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(body_ref);
|
.into_results_cursor(body_ref);
|
||||||
|
|
||||||
// Calculate the MIR locals which have been previously
|
// Calculate the MIR locals which have been previously
|
||||||
// borrowed (even if they are still active).
|
// borrowed (even if they are still active).
|
||||||
let borrowed_locals_results = MaybeBorrowedLocals::all_borrows()
|
let borrowed_locals_results = MaybeBorrowedLocals::all_borrows()
|
||||||
.into_engine(tcx, body_ref, def_id)
|
.into_engine(tcx, body_ref)
|
||||||
.pass_name("generator")
|
.pass_name("generator")
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
|
|
||||||
|
@ -477,14 +475,14 @@ fn locals_live_across_suspend_points(
|
||||||
// Calculate the MIR locals that we actually need to keep storage around
|
// Calculate the MIR locals that we actually need to keep storage around
|
||||||
// for.
|
// for.
|
||||||
let requires_storage_results = MaybeRequiresStorage::new(body, &borrowed_locals_results)
|
let requires_storage_results = MaybeRequiresStorage::new(body, &borrowed_locals_results)
|
||||||
.into_engine(tcx, body_ref, def_id)
|
.into_engine(tcx, body_ref)
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
let mut requires_storage_cursor =
|
let mut requires_storage_cursor =
|
||||||
dataflow::ResultsCursor::new(body_ref, &requires_storage_results);
|
dataflow::ResultsCursor::new(body_ref, &requires_storage_results);
|
||||||
|
|
||||||
// Calculate the liveness of MIR locals ignoring borrows.
|
// Calculate the liveness of MIR locals ignoring borrows.
|
||||||
let mut liveness = MaybeLiveLocals
|
let mut liveness = MaybeLiveLocals
|
||||||
.into_engine(tcx, body_ref, def_id)
|
.into_engine(tcx, body_ref)
|
||||||
.pass_name("generator")
|
.pass_name("generator")
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(body_ref);
|
.into_results_cursor(body_ref);
|
||||||
|
@ -722,11 +720,11 @@ impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> {
|
||||||
fn sanitize_witness<'tcx>(
|
fn sanitize_witness<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
did: DefId,
|
|
||||||
witness: Ty<'tcx>,
|
witness: Ty<'tcx>,
|
||||||
upvars: &Vec<Ty<'tcx>>,
|
upvars: &Vec<Ty<'tcx>>,
|
||||||
saved_locals: &GeneratorSavedLocals,
|
saved_locals: &GeneratorSavedLocals,
|
||||||
) {
|
) {
|
||||||
|
let did = body.source.def_id();
|
||||||
let allowed_upvars = tcx.erase_regions(upvars);
|
let allowed_upvars = tcx.erase_regions(upvars);
|
||||||
let allowed = match witness.kind() {
|
let allowed = match witness.kind() {
|
||||||
ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s),
|
ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s),
|
||||||
|
@ -865,7 +863,7 @@ fn insert_switch<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut Body<'tcx>) {
|
fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
use crate::shim::DropShimElaborator;
|
use crate::shim::DropShimElaborator;
|
||||||
use crate::util::elaborate_drops::{elaborate_drop, Unwind};
|
use crate::util::elaborate_drops::{elaborate_drop, Unwind};
|
||||||
use crate::util::patch::MirPatch;
|
use crate::util::patch::MirPatch;
|
||||||
|
@ -874,6 +872,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut
|
||||||
// this is ok because `open_drop` can only be reached within that own
|
// this is ok because `open_drop` can only be reached within that own
|
||||||
// generator's resume function.
|
// generator's resume function.
|
||||||
|
|
||||||
|
let def_id = body.source.def_id();
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
|
|
||||||
let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env };
|
let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env };
|
||||||
|
@ -1246,8 +1245,6 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||||
|
|
||||||
assert!(body.generator_drop.is_none());
|
assert!(body.generator_drop.is_none());
|
||||||
|
|
||||||
let def_id = body.source.def_id();
|
|
||||||
|
|
||||||
// The first argument is the generator type passed by value
|
// The first argument is the generator type passed by value
|
||||||
let gen_ty = body.local_decls.raw[1].ty;
|
let gen_ty = body.local_decls.raw[1].ty;
|
||||||
|
|
||||||
|
@ -1306,7 +1303,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||||
let liveness_info =
|
let liveness_info =
|
||||||
locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
|
locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
|
||||||
|
|
||||||
sanitize_witness(tcx, body, def_id, interior, &upvars, &liveness_info.saved_locals);
|
sanitize_witness(tcx, body, interior, &upvars, &liveness_info.saved_locals);
|
||||||
|
|
||||||
if tcx.sess.opts.debugging_opts.validate_mir {
|
if tcx.sess.opts.debugging_opts.validate_mir {
|
||||||
let mut vis = EnsureGeneratorFieldAssignmentsNeverAlias {
|
let mut vis = EnsureGeneratorFieldAssignmentsNeverAlias {
|
||||||
|
@ -1358,7 +1355,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||||
// Expand `drop(generator_struct)` to a drop ladder which destroys upvars.
|
// Expand `drop(generator_struct)` to a drop ladder which destroys upvars.
|
||||||
// If any upvars are moved out of, drop elaboration will handle upvar destruction.
|
// If any upvars are moved out of, drop elaboration will handle upvar destruction.
|
||||||
// However we need to also elaborate the code generated by `insert_clean_drop`.
|
// However we need to also elaborate the code generated by `insert_clean_drop`.
|
||||||
elaborate_generator_drops(tcx, def_id, body);
|
elaborate_generator_drops(tcx, body);
|
||||||
|
|
||||||
dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(()));
|
dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(()));
|
||||||
|
|
||||||
|
|
|
@ -229,13 +229,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) ->
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
let ccx = check_consts::ConstCx {
|
let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def.did) };
|
||||||
body,
|
|
||||||
tcx,
|
|
||||||
def_id: def.did,
|
|
||||||
const_kind,
|
|
||||||
param_env: tcx.param_env(def.did),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut validator = check_consts::validation::Validator::new(&ccx);
|
let mut validator = check_consts::validation::Validator::new(&ccx);
|
||||||
validator.check_body();
|
validator.check_body();
|
||||||
|
@ -346,7 +340,7 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
|
||||||
let mut body = body.steal();
|
let mut body = body.steal();
|
||||||
|
|
||||||
run_post_borrowck_cleanup_passes(tcx, &mut body);
|
run_post_borrowck_cleanup_passes(tcx, &mut body);
|
||||||
check_consts::post_drop_elaboration::check_live_drops(tcx, def.did, &body);
|
check_consts::post_drop_elaboration::check_live_drops(tcx, &body);
|
||||||
tcx.alloc_steal_mir(body)
|
tcx.alloc_steal_mir(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
|
||||||
let def = body.source.with_opt_param().expect_local();
|
let def = body.source.with_opt_param().expect_local();
|
||||||
|
|
||||||
let mut rpo = traversal::reverse_postorder(body);
|
let mut rpo = traversal::reverse_postorder(body);
|
||||||
let ccx = ConstCx::new(tcx, def.did, body);
|
let ccx = ConstCx::new(tcx, body);
|
||||||
let (temps, all_candidates) = collect_temps_and_candidates(&ccx, &mut rpo);
|
let (temps, all_candidates) = collect_temps_and_candidates(&ccx, &mut rpo);
|
||||||
|
|
||||||
let promotable_candidates = validate_candidates(&ccx, &temps, &all_candidates);
|
let promotable_candidates = validate_candidates(&ccx, &temps, &all_candidates);
|
||||||
|
@ -758,7 +758,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
||||||
ty::FnDef(def_id, _) => {
|
ty::FnDef(def_id, _) => {
|
||||||
is_const_fn(self.tcx, def_id)
|
is_const_fn(self.tcx, def_id)
|
||||||
|| is_unstable_const_fn(self.tcx, def_id).is_some()
|
|| is_unstable_const_fn(self.tcx, def_id).is_some()
|
||||||
|| is_lang_panic_fn(self.tcx, self.def_id.to_def_id())
|
|| is_lang_panic_fn(self.tcx, def_id)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
@ -1250,7 +1250,9 @@ crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>(
|
||||||
debug!(
|
debug!(
|
||||||
"should_suggest_const_in_array_repeat_expressions_flag: def_id={:?} \
|
"should_suggest_const_in_array_repeat_expressions_flag: def_id={:?} \
|
||||||
should_promote={:?} feature_flag={:?}",
|
should_promote={:?} feature_flag={:?}",
|
||||||
validator.ccx.def_id, should_promote, feature_flag
|
validator.ccx.def_id(),
|
||||||
|
should_promote,
|
||||||
|
feature_flag
|
||||||
);
|
);
|
||||||
should_promote && !feature_flag
|
should_promote && !feature_flag
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
//! This pass replaces a drop of a type that does not need dropping, with a goto
|
//! This pass replaces a drop of a type that does not need dropping, with a goto
|
||||||
|
|
||||||
use crate::transform::MirPass;
|
use crate::transform::MirPass;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
|
||||||
use rustc_middle::mir::visit::Visitor;
|
use rustc_middle::mir::visit::Visitor;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::{ParamEnv, TyCtxt};
|
||||||
|
|
||||||
use super::simplify::simplify_cfg;
|
use super::simplify::simplify_cfg;
|
||||||
|
|
||||||
|
@ -16,8 +15,8 @@ impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
|
||||||
let mut opt_finder = RemoveUnneededDropsOptimizationFinder {
|
let mut opt_finder = RemoveUnneededDropsOptimizationFinder {
|
||||||
tcx,
|
tcx,
|
||||||
body,
|
body,
|
||||||
|
param_env: tcx.param_env(body.source.def_id()),
|
||||||
optimizations: vec![],
|
optimizations: vec![],
|
||||||
def_id: body.source.def_id().expect_local(),
|
|
||||||
};
|
};
|
||||||
opt_finder.visit_body(body);
|
opt_finder.visit_body(body);
|
||||||
let should_simplify = !opt_finder.optimizations.is_empty();
|
let should_simplify = !opt_finder.optimizations.is_empty();
|
||||||
|
@ -40,7 +39,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RemoveUnneededDropsOptimizationFinder<'a, 'tcx>
|
||||||
match terminator.kind {
|
match terminator.kind {
|
||||||
TerminatorKind::Drop { place, target, .. } => {
|
TerminatorKind::Drop { place, target, .. } => {
|
||||||
let ty = place.ty(self.body, self.tcx);
|
let ty = place.ty(self.body, self.tcx);
|
||||||
let needs_drop = ty.ty.needs_drop(self.tcx, self.tcx.param_env(self.def_id));
|
let needs_drop = ty.ty.needs_drop(self.tcx, self.param_env);
|
||||||
if !needs_drop {
|
if !needs_drop {
|
||||||
self.optimizations.push((location, target));
|
self.optimizations.push((location, target));
|
||||||
}
|
}
|
||||||
|
@ -54,5 +53,5 @@ pub struct RemoveUnneededDropsOptimizationFinder<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
optimizations: Vec<(Location, BasicBlock)>,
|
optimizations: Vec<(Location, BasicBlock)>,
|
||||||
def_id: LocalDefId,
|
param_env: ParamEnv<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_span::Span;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use crate::transform::MirPass;
|
use crate::transform::MirPass;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_middle::mir::{self, Body, Local, Location};
|
use rustc_middle::mir::{self, Body, Local, Location};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
@ -41,41 +40,40 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
|
||||||
|
|
||||||
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_maybe_init).is_some() {
|
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_maybe_init).is_some() {
|
||||||
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
|
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
|
|
||||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_inits);
|
sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_inits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_maybe_uninit).is_some() {
|
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_maybe_uninit).is_some() {
|
||||||
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &mdpe)
|
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &mdpe)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
|
|
||||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_uninits);
|
sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_uninits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_definite_init).is_some() {
|
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_definite_init).is_some() {
|
||||||
let flow_def_inits = DefinitelyInitializedPlaces::new(tcx, body, &mdpe)
|
let flow_def_inits = DefinitelyInitializedPlaces::new(tcx, body, &mdpe)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
|
|
||||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits);
|
sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_def_inits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_indirectly_mutable).is_some() {
|
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_indirectly_mutable).is_some() {
|
||||||
let flow_mut_borrowed = MaybeMutBorrowedLocals::mut_borrows_only(tcx, body, param_env)
|
let flow_mut_borrowed = MaybeMutBorrowedLocals::mut_borrows_only(tcx, body, param_env)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.iterate_to_fixpoint();
|
.iterate_to_fixpoint();
|
||||||
|
|
||||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_mut_borrowed);
|
sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_mut_borrowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_liveness).is_some() {
|
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_liveness).is_some() {
|
||||||
let flow_liveness =
|
let flow_liveness = MaybeLiveLocals.into_engine(tcx, body).iterate_to_fixpoint();
|
||||||
MaybeLiveLocals.into_engine(tcx, body, def_id).iterate_to_fixpoint();
|
|
||||||
|
|
||||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_liveness);
|
sanity_check_via_rustc_peek(tcx, body, &attributes, &flow_liveness);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_rustc_mir_with(sess, &attributes, sym::stop_after_dataflow).is_some() {
|
if has_rustc_mir_with(sess, &attributes, sym::stop_after_dataflow).is_some() {
|
||||||
|
@ -103,12 +101,12 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
|
||||||
pub fn sanity_check_via_rustc_peek<'tcx, A>(
|
pub fn sanity_check_via_rustc_peek<'tcx, A>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
_attributes: &[ast::Attribute],
|
_attributes: &[ast::Attribute],
|
||||||
results: &Results<'tcx, A>,
|
results: &Results<'tcx, A>,
|
||||||
) where
|
) where
|
||||||
A: RustcPeekAt<'tcx>,
|
A: RustcPeekAt<'tcx>,
|
||||||
{
|
{
|
||||||
|
let def_id = body.source.def_id();
|
||||||
debug!("sanity_check_via_rustc_peek def_id: {:?}", def_id);
|
debug!("sanity_check_via_rustc_peek def_id: {:?}", def_id);
|
||||||
|
|
||||||
let mut cursor = ResultsCursor::new(body, results);
|
let mut cursor = ResultsCursor::new(body, results);
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
|
||||||
|
|
||||||
let always_live_locals = AlwaysLiveLocals::new(body);
|
let always_live_locals = AlwaysLiveLocals::new(body);
|
||||||
let storage_liveness = MaybeStorageLive::new(always_live_locals)
|
let storage_liveness = MaybeStorageLive::new(always_live_locals)
|
||||||
.into_engine(tcx, body, def_id)
|
.into_engine(tcx, body)
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(body);
|
.into_results_cursor(body);
|
||||||
|
|
||||||
|
|
|
@ -72,16 +72,16 @@ where
|
||||||
writeln!(w, r#" edge [{}];"#, content_attrs_str)?;
|
writeln!(w, r#" edge [{}];"#, content_attrs_str)?;
|
||||||
|
|
||||||
// Graph label
|
// Graph label
|
||||||
write_graph_label(tcx, def_id, body, w)?;
|
write_graph_label(tcx, body, w)?;
|
||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
for (block, _) in body.basic_blocks().iter_enumerated() {
|
for (block, _) in body.basic_blocks().iter_enumerated() {
|
||||||
write_node(def_id, block, body, dark_mode, w)?;
|
write_node(block, body, dark_mode, w)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edges
|
// Edges
|
||||||
for (source, _) in body.basic_blocks().iter_enumerated() {
|
for (source, _) in body.basic_blocks().iter_enumerated() {
|
||||||
write_edges(def_id, source, body, w)?;
|
write_edges(source, body, w)?;
|
||||||
}
|
}
|
||||||
writeln!(w, "}}")
|
writeln!(w, "}}")
|
||||||
}
|
}
|
||||||
|
@ -145,12 +145,12 @@ where
|
||||||
|
|
||||||
/// Write a graphviz DOT node for the given basic block.
|
/// Write a graphviz DOT node for the given basic block.
|
||||||
fn write_node<W: Write>(
|
fn write_node<W: Write>(
|
||||||
def_id: DefId,
|
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
body: &Body<'_>,
|
body: &Body<'_>,
|
||||||
dark_mode: bool,
|
dark_mode: bool,
|
||||||
w: &mut W,
|
w: &mut W,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
let def_id = body.source.def_id();
|
||||||
// Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
|
// Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
|
||||||
write!(w, r#" {} [shape="none", label=<"#, node(def_id, block))?;
|
write!(w, r#" {} [shape="none", label=<"#, node(def_id, block))?;
|
||||||
write_node_label(block, body, dark_mode, w, 1, |_| Ok(()), |_| Ok(()))?;
|
write_node_label(block, body, dark_mode, w, 1, |_| Ok(()), |_| Ok(()))?;
|
||||||
|
@ -159,12 +159,8 @@ fn write_node<W: Write>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
|
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
|
||||||
fn write_edges<W: Write>(
|
fn write_edges<W: Write>(source: BasicBlock, body: &Body<'_>, w: &mut W) -> io::Result<()> {
|
||||||
def_id: DefId,
|
let def_id = body.source.def_id();
|
||||||
source: BasicBlock,
|
|
||||||
body: &Body<'_>,
|
|
||||||
w: &mut W,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let terminator = body[source].terminator();
|
let terminator = body[source].terminator();
|
||||||
let labels = terminator.kind.fmt_successor_labels();
|
let labels = terminator.kind.fmt_successor_labels();
|
||||||
|
|
||||||
|
@ -182,10 +178,11 @@ fn write_edges<W: Write>(
|
||||||
/// all the variables and temporaries.
|
/// all the variables and temporaries.
|
||||||
fn write_graph_label<'tcx, W: Write>(
|
fn write_graph_label<'tcx, W: Write>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
body: &Body<'_>,
|
body: &Body<'_>,
|
||||||
w: &mut W,
|
w: &mut W,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
let def_id = body.source.def_id();
|
||||||
|
|
||||||
write!(w, " label=<fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))?;
|
write!(w, " label=<fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))?;
|
||||||
|
|
||||||
// fn argument types.
|
// fn argument types.
|
||||||
|
|
|
@ -153,7 +153,7 @@ fn dump_matched_mir_node<'tcx, F>(
|
||||||
let mut file =
|
let mut file =
|
||||||
create_dump_file(tcx, "html", pass_num, pass_name, disambiguator, body.source)?;
|
create_dump_file(tcx, "html", pass_num, pass_name, disambiguator, body.source)?;
|
||||||
if body.source.def_id().is_local() {
|
if body.source.def_id().is_local() {
|
||||||
write_mir_fn_spanview(tcx, body.source.def_id(), body, spanview, &mut file)?;
|
write_mir_fn_spanview(tcx, body, spanview, &mut file)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,6 @@ pub struct SpanViewable {
|
||||||
/// Write a spanview HTML+CSS file to analyze MIR element spans.
|
/// Write a spanview HTML+CSS file to analyze MIR element spans.
|
||||||
pub fn write_mir_fn_spanview<'tcx, W>(
|
pub fn write_mir_fn_spanview<'tcx, W>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
spanview: MirSpanview,
|
spanview: MirSpanview,
|
||||||
w: &mut W,
|
w: &mut W,
|
||||||
|
@ -98,6 +97,7 @@ pub fn write_mir_fn_spanview<'tcx, W>(
|
||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
{
|
{
|
||||||
|
let def_id = body.source.def_id();
|
||||||
let body_span = hir_body(tcx, def_id).value.span;
|
let body_span = hir_body(tcx, def_id).value.span;
|
||||||
let mut span_viewables = Vec::new();
|
let mut span_viewables = Vec::new();
|
||||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||||
|
|
|
@ -205,7 +205,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||||
build::construct_const(cx, body_id, return_ty, return_ty_span)
|
build::construct_const(cx, body_id, return_ty, return_ty_span)
|
||||||
};
|
};
|
||||||
|
|
||||||
lints::check(tcx, &body, def.did);
|
lints::check(tcx, &body);
|
||||||
|
|
||||||
// The borrow checker will replace all the regions here with its own
|
// The borrow checker will replace all the regions here with its own
|
||||||
// inference variables. There's no point having non-erased regions here.
|
// inference variables. There's no point having non-erased regions here.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use rustc_data_structures::graph::iterate::{
|
use rustc_data_structures::graph::iterate::{
|
||||||
ControlFlow, NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
|
ControlFlow, NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
|
||||||
};
|
};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_middle::hir::map::blocks::FnLikeNode;
|
use rustc_middle::hir::map::blocks::FnLikeNode;
|
||||||
use rustc_middle::mir::{BasicBlock, Body, Operand, TerminatorKind};
|
use rustc_middle::mir::{BasicBlock, Body, Operand, TerminatorKind};
|
||||||
|
@ -10,7 +9,8 @@ use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
|
||||||
use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
|
use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: LocalDefId) {
|
crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||||
|
let def_id = body.source.def_id().expect_local();
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
|
||||||
if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
|
if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
|
||||||
|
@ -30,7 +30,7 @@ crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: LocalDefId) {
|
||||||
_ => &[],
|
_ => &[],
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut vis = Search { tcx, body, def_id, reachable_recursive_calls: vec![], trait_substs };
|
let mut vis = Search { tcx, body, reachable_recursive_calls: vec![], trait_substs };
|
||||||
if let Some(NonRecursive) = TriColorDepthFirstSearch::new(&body).run_from_start(&mut vis) {
|
if let Some(NonRecursive) = TriColorDepthFirstSearch::new(&body).run_from_start(&mut vis) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ struct NonRecursive;
|
||||||
struct Search<'mir, 'tcx> {
|
struct Search<'mir, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'mir Body<'tcx>,
|
body: &'mir Body<'tcx>,
|
||||||
def_id: LocalDefId,
|
|
||||||
trait_substs: &'tcx [GenericArg<'tcx>],
|
trait_substs: &'tcx [GenericArg<'tcx>],
|
||||||
|
|
||||||
reachable_recursive_calls: Vec<Span>,
|
reachable_recursive_calls: Vec<Span>,
|
||||||
|
@ -66,16 +65,17 @@ struct Search<'mir, 'tcx> {
|
||||||
impl<'mir, 'tcx> Search<'mir, 'tcx> {
|
impl<'mir, 'tcx> Search<'mir, 'tcx> {
|
||||||
/// Returns `true` if `func` refers to the function we are searching in.
|
/// Returns `true` if `func` refers to the function we are searching in.
|
||||||
fn is_recursive_call(&self, func: &Operand<'tcx>) -> bool {
|
fn is_recursive_call(&self, func: &Operand<'tcx>) -> bool {
|
||||||
let Search { tcx, body, def_id, trait_substs, .. } = *self;
|
let Search { tcx, body, trait_substs, .. } = *self;
|
||||||
let param_env = tcx.param_env(def_id);
|
let caller = body.source.def_id();
|
||||||
|
let param_env = tcx.param_env(caller);
|
||||||
|
|
||||||
let func_ty = func.ty(body, tcx);
|
let func_ty = func.ty(body, tcx);
|
||||||
if let ty::FnDef(fn_def_id, substs) = *func_ty.kind() {
|
if let ty::FnDef(callee, substs) = *func_ty.kind() {
|
||||||
let (call_fn_id, call_substs) =
|
let (callee, call_substs) =
|
||||||
if let Ok(Some(instance)) = Instance::resolve(tcx, param_env, fn_def_id, substs) {
|
if let Ok(Some(instance)) = Instance::resolve(tcx, param_env, callee, substs) {
|
||||||
(instance.def_id(), instance.substs)
|
(instance.def_id(), instance.substs)
|
||||||
} else {
|
} else {
|
||||||
(fn_def_id, substs)
|
(callee, substs)
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(#57965): Make this work across function boundaries
|
// FIXME(#57965): Make this work across function boundaries
|
||||||
|
@ -84,8 +84,7 @@ impl<'mir, 'tcx> Search<'mir, 'tcx> {
|
||||||
// calling into an entirely different method (for example, a call from the default
|
// calling into an entirely different method (for example, a call from the default
|
||||||
// method in the trait to `<A as Trait<B>>::method`, where `A` and/or `B` are
|
// method in the trait to `<A as Trait<B>>::method`, where `A` and/or `B` are
|
||||||
// specific types).
|
// specific types).
|
||||||
return call_fn_id == def_id.to_def_id()
|
return callee == caller && &call_substs[..trait_substs.len()] == trait_substs;
|
||||||
&& &call_substs[..trait_substs.len()] == trait_substs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue