Some perf optimizations and logging
This commit is contained in:
parent
32c447e179
commit
d954a8ee8e
@ -418,6 +418,7 @@ fn insert_into_error_cache(&mut self, index: usize) {
|
|||||||
/// be called in a loop until `outcome.stalled` is false.
|
/// be called in a loop until `outcome.stalled` is false.
|
||||||
///
|
///
|
||||||
/// This _cannot_ be unrolled (presently, at least).
|
/// This _cannot_ be unrolled (presently, at least).
|
||||||
|
#[inline(never)]
|
||||||
pub fn process_obligations<P, OUT>(&mut self, processor: &mut P) -> OUT
|
pub fn process_obligations<P, OUT>(&mut self, processor: &mut P) -> OUT
|
||||||
where
|
where
|
||||||
P: ObligationProcessor<Obligation = O>,
|
P: ObligationProcessor<Obligation = O>,
|
||||||
@ -671,6 +672,7 @@ fn compress(&mut self, mut outcome_cb: impl FnMut(&O)) {
|
|||||||
self.reused_node_vec = node_rewrites;
|
self.reused_node_vec = node_rewrites;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn apply_rewrites(&mut self, node_rewrites: &[usize]) {
|
fn apply_rewrites(&mut self, node_rewrites: &[usize]) {
|
||||||
let orig_nodes_len = node_rewrites.len();
|
let orig_nodes_len = node_rewrites.len();
|
||||||
|
|
||||||
|
@ -400,6 +400,7 @@ fn from(vid: ty::TyVid) -> Self {
|
|||||||
|
|
||||||
impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> {
|
impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> {
|
||||||
type Value = TypeVariableValue<'tcx>;
|
type Value = TypeVariableValue<'tcx>;
|
||||||
|
#[inline(always)]
|
||||||
fn index(&self) -> u32 {
|
fn index(&self) -> u32 {
|
||||||
self.vid.index
|
self.vid.index
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||||||
/// `SomeTrait` or a where-clause that lets us unify `$0` with
|
/// `SomeTrait` or a where-clause that lets us unify `$0` with
|
||||||
/// something concrete. If this fails, we'll unify `$0` with
|
/// something concrete. If this fails, we'll unify `$0` with
|
||||||
/// `projection_ty` again.
|
/// `projection_ty` again.
|
||||||
|
#[tracing::instrument(level = "debug", skip(self, infcx, param_env, cause))]
|
||||||
fn normalize_projection_type(
|
fn normalize_projection_type(
|
||||||
&mut self,
|
&mut self,
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
@ -174,8 +175,6 @@ fn normalize_projection_type(
|
|||||||
projection_ty: ty::ProjectionTy<'tcx>,
|
projection_ty: ty::ProjectionTy<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
debug!(?projection_ty, "normalize_projection_type");
|
|
||||||
|
|
||||||
debug_assert!(!projection_ty.has_escaping_bound_vars());
|
debug_assert!(!projection_ty.has_escaping_bound_vars());
|
||||||
|
|
||||||
// FIXME(#20304) -- cache
|
// FIXME(#20304) -- cache
|
||||||
|
@ -273,7 +273,7 @@ pub fn normalize_with_depth<'a, 'b, 'tcx, T>(
|
|||||||
Normalized { value, obligations }
|
Normalized { value, obligations }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
|
#[instrument(level = "info", skip(selcx, param_env, cause, obligations))]
|
||||||
pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>(
|
pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>(
|
||||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
@ -285,6 +285,7 @@ pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>(
|
|||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
|
debug!(obligations.len = obligations.len());
|
||||||
let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations);
|
let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations);
|
||||||
let result = ensure_sufficient_stack(|| normalizer.fold(value));
|
let result = ensure_sufficient_stack(|| normalizer.fold(value));
|
||||||
debug!(?result, obligations.len = normalizer.obligations.len());
|
debug!(?result, obligations.len = normalizer.obligations.len());
|
||||||
@ -314,6 +315,7 @@ fn new(
|
|||||||
|
|
||||||
fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
||||||
let value = self.selcx.infcx().resolve_vars_if_possible(value);
|
let value = self.selcx.infcx().resolve_vars_if_possible(value);
|
||||||
|
debug!(?value);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
!value.has_escaping_bound_vars(),
|
!value.has_escaping_bound_vars(),
|
||||||
@ -825,7 +827,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
|||||||
|
|
||||||
let cache_result = infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
|
let cache_result = infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
|
||||||
match cache_result {
|
match cache_result {
|
||||||
Ok(()) => {}
|
Ok(()) => debug!("no cache"),
|
||||||
Err(ProjectionCacheEntry::Ambiguous) => {
|
Err(ProjectionCacheEntry::Ambiguous) => {
|
||||||
// If we found ambiguity the last time, that means we will continue
|
// If we found ambiguity the last time, that means we will continue
|
||||||
// to do so until some type in the key changes (and we know it
|
// to do so until some type in the key changes (and we know it
|
||||||
@ -852,6 +854,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
|||||||
return Err(InProgress);
|
return Err(InProgress);
|
||||||
}
|
}
|
||||||
Err(ProjectionCacheEntry::Recur) => {
|
Err(ProjectionCacheEntry::Recur) => {
|
||||||
|
debug!("recur cache");
|
||||||
return Err(InProgress);
|
return Err(InProgress);
|
||||||
}
|
}
|
||||||
Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
|
Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
|
||||||
@ -1058,12 +1061,11 @@ fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx
|
|||||||
///
|
///
|
||||||
/// IMPORTANT:
|
/// IMPORTANT:
|
||||||
/// - `obligation` must be fully normalized
|
/// - `obligation` must be fully normalized
|
||||||
|
#[tracing::instrument(level = "info", skip(selcx))]
|
||||||
fn project_type<'cx, 'tcx>(
|
fn project_type<'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
) -> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>> {
|
) -> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>> {
|
||||||
debug!(?obligation, "project_type");
|
|
||||||
|
|
||||||
if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
|
if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
|
||||||
debug!("project: overflow!");
|
debug!("project: overflow!");
|
||||||
// This should really be an immediate error, but some existing code
|
// This should really be an immediate error, but some existing code
|
||||||
|
@ -65,7 +65,7 @@ fn normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
|
|||||||
};
|
};
|
||||||
|
|
||||||
let result = value.fold_with(&mut normalizer);
|
let result = value.fold_with(&mut normalizer);
|
||||||
debug!(
|
info!(
|
||||||
"normalize::<{}>: result={:?} with {} obligations",
|
"normalize::<{}>: result={:?} with {} obligations",
|
||||||
std::any::type_name::<T>(),
|
std::any::type_name::<T>(),
|
||||||
result,
|
result,
|
||||||
|
@ -1865,12 +1865,12 @@ fn rematch_impl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
fn match_impl(
|
fn match_impl(
|
||||||
&mut self,
|
&mut self,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
|
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
|
||||||
debug!(?impl_def_id, ?obligation, "match_impl");
|
|
||||||
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
|
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
|
||||||
|
|
||||||
// Before we create the substitutions and everything, first
|
// Before we create the substitutions and everything, first
|
||||||
@ -1888,6 +1888,8 @@ fn match_impl(
|
|||||||
|
|
||||||
let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
|
let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
|
||||||
|
|
||||||
|
debug!(?impl_trait_ref);
|
||||||
|
|
||||||
let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
|
let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
|
||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
project::normalize_with_depth(
|
project::normalize_with_depth(
|
||||||
@ -1915,7 +1917,7 @@ fn match_impl(
|
|||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(?impl_substs, "match_impl: success");
|
debug!(?impl_substs, ?nested_obligations, "match_impl: success");
|
||||||
Ok(Normalized { value: impl_substs, obligations: nested_obligations })
|
Ok(Normalized { value: impl_substs, obligations: nested_obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2068,6 +2070,7 @@ fn generator_trait_ref_unnormalized(
|
|||||||
/// impl or trait. The obligations are substituted and fully
|
/// impl or trait. The obligations are substituted and fully
|
||||||
/// normalized. This is used when confirming an impl or default
|
/// normalized. This is used when confirming an impl or default
|
||||||
/// impl.
|
/// impl.
|
||||||
|
#[tracing::instrument(level = "debug", skip(self, cause, param_env))]
|
||||||
fn impl_or_trait_obligations(
|
fn impl_or_trait_obligations(
|
||||||
&mut self,
|
&mut self,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
@ -2076,7 +2079,6 @@ fn impl_or_trait_obligations(
|
|||||||
def_id: DefId, // of impl or trait
|
def_id: DefId, // of impl or trait
|
||||||
substs: SubstsRef<'tcx>, // for impl or trait
|
substs: SubstsRef<'tcx>, // for impl or trait
|
||||||
) -> Vec<PredicateObligation<'tcx>> {
|
) -> Vec<PredicateObligation<'tcx>> {
|
||||||
debug!(?def_id, "impl_or_trait_obligations");
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
// To allow for one-pass evaluation of the nested obligation,
|
// To allow for one-pass evaluation of the nested obligation,
|
||||||
@ -2094,9 +2096,11 @@ fn impl_or_trait_obligations(
|
|||||||
// `$1: Copy`, so we must ensure the obligations are emitted in
|
// `$1: Copy`, so we must ensure the obligations are emitted in
|
||||||
// that order.
|
// that order.
|
||||||
let predicates = tcx.predicates_of(def_id);
|
let predicates = tcx.predicates_of(def_id);
|
||||||
|
debug!(?predicates);
|
||||||
assert_eq!(predicates.parent, None);
|
assert_eq!(predicates.parent, None);
|
||||||
let mut obligations = Vec::with_capacity(predicates.predicates.len());
|
let mut obligations = Vec::with_capacity(predicates.predicates.len());
|
||||||
for (predicate, _) in predicates.predicates {
|
for (predicate, _) in predicates.predicates {
|
||||||
|
debug!(?predicate);
|
||||||
let predicate = normalize_with_depth_to(
|
let predicate = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
param_env,
|
param_env,
|
||||||
|
@ -85,6 +85,7 @@ pub fn trait_obligations<'a, 'tcx>(
|
|||||||
let mut wf =
|
let mut wf =
|
||||||
WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item };
|
WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item };
|
||||||
wf.compute_trait_ref(trait_ref, Elaborate::All);
|
wf.compute_trait_ref(trait_ref, Elaborate::All);
|
||||||
|
debug!(obligations = ?wf.out);
|
||||||
wf.normalize()
|
wf.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1578,6 +1578,7 @@ fn inferred_kind(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add all the obligations that are required, substituting and normalized appropriately.
|
/// Add all the obligations that are required, substituting and normalized appropriately.
|
||||||
|
#[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
|
||||||
fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
|
fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
|
||||||
let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
|
let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
|
||||||
|
|
||||||
|
@ -179,6 +179,7 @@ pub(super) fn normalize_associated_types_in_with_cause<T>(
|
|||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let ok = self.partially_normalize_associated_types_in(cause, param_env, value);
|
let ok = self.partially_normalize_associated_types_in(cause, param_env, value);
|
||||||
|
debug!(?ok);
|
||||||
self.register_infer_ok_obligations(ok)
|
self.register_infer_ok_obligations(ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,14 +379,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(tcx, span, sig_if_method))]
|
||||||
fn check_associated_item(
|
fn check_associated_item(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
item_id: hir::HirId,
|
item_id: hir::HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
sig_if_method: Option<&hir::FnSig<'_>>,
|
sig_if_method: Option<&hir::FnSig<'_>>,
|
||||||
) {
|
) {
|
||||||
debug!("check_associated_item: {:?}", item_id);
|
|
||||||
|
|
||||||
let code = ObligationCauseCode::WellFormed(Some(item_id));
|
let code = ObligationCauseCode::WellFormed(Some(item_id));
|
||||||
for_id(tcx, item_id, span).with_fcx(|fcx| {
|
for_id(tcx, item_id, span).with_fcx(|fcx| {
|
||||||
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
|
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
|
||||||
@ -650,14 +649,13 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
|
||||||
fn check_impl<'tcx>(
|
fn check_impl<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
item: &'tcx hir::Item<'tcx>,
|
item: &'tcx hir::Item<'tcx>,
|
||||||
ast_self_ty: &hir::Ty<'_>,
|
ast_self_ty: &hir::Ty<'_>,
|
||||||
ast_trait_ref: &Option<hir::TraitRef<'_>>,
|
ast_trait_ref: &Option<hir::TraitRef<'_>>,
|
||||||
) {
|
) {
|
||||||
debug!("check_impl: {:?}", item);
|
|
||||||
|
|
||||||
for_item(tcx, item).with_fcx(|fcx| {
|
for_item(tcx, item).with_fcx(|fcx| {
|
||||||
match *ast_trait_ref {
|
match *ast_trait_ref {
|
||||||
Some(ref ast_trait_ref) => {
|
Some(ref ast_trait_ref) => {
|
||||||
@ -675,6 +673,7 @@ fn check_impl<'tcx>(
|
|||||||
ast_trait_ref.path.span,
|
ast_trait_ref.path.span,
|
||||||
Some(item),
|
Some(item),
|
||||||
);
|
);
|
||||||
|
debug!(?obligations);
|
||||||
for obligation in obligations {
|
for obligation in obligations {
|
||||||
fcx.register_predicate(obligation);
|
fcx.register_predicate(obligation);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user