Avoid fetching the opaque type origin when only "is this in the defining scope" is actually needed
This commit is contained in:
parent
ba5f0418af
commit
7cfa521931
5 changed files with 16 additions and 27 deletions
|
@ -244,7 +244,7 @@ pub struct InferCtxt<'tcx> {
|
|||
pub tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// The `DefIds` of the opaque types that may have their hidden types constrained.
|
||||
pub defining_opaque_types: &'tcx ty::List<LocalDefId>,
|
||||
defining_opaque_types: &'tcx ty::List<LocalDefId>,
|
||||
|
||||
/// Whether this inference context should care about region obligations in
|
||||
/// the root universe. Most notably, this is used during hir typeck as region
|
||||
|
@ -1232,6 +1232,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
self.inner.borrow().opaque_type_storage.opaque_types.clone()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
|
||||
let Some(id) = id.into().as_local() else { return false };
|
||||
self.defining_opaque_types.contains(&id)
|
||||
}
|
||||
|
||||
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
|
||||
self.resolve_vars_if_possible(t).to_string()
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::errors::OpaqueHiddenTypeDiag;
|
|||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::{self, PredicateObligation};
|
||||
use hir::def_id::{DefId, LocalDefId};
|
||||
use hir::OpaqueTyOrigin;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
|
@ -54,16 +53,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
|
||||
let mut obligations = vec![];
|
||||
let replace_opaque_type = |def_id: DefId| {
|
||||
def_id.as_local().is_some_and(|def_id| self.opaque_type_origin(def_id).is_some())
|
||||
};
|
||||
let value = value.fold_with(&mut BottomUpFolder {
|
||||
tcx: self.tcx,
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
ty_op: |ty| match *ty.kind() {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })
|
||||
if replace_opaque_type(def_id) && !ty.has_escaping_bound_vars() =>
|
||||
if self.can_define_opaque_ty(def_id) && !ty.has_escaping_bound_vars() =>
|
||||
{
|
||||
let def_span = self.tcx.def_span(def_id);
|
||||
let span = if span.contains(def_span) { def_span } else { span };
|
||||
|
@ -140,7 +136,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||
// }
|
||||
// ```
|
||||
if self.opaque_type_origin(def_id).is_none() {
|
||||
if !self.can_define_opaque_ty(def_id) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -150,8 +146,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// no one encounters it in practice.
|
||||
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
|
||||
// where it is of no concern, so we only check for TAITs.
|
||||
if let Some(OpaqueTyOrigin::TyAlias { .. }) =
|
||||
b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id))
|
||||
if self.can_define_opaque_ty(b_def_id)
|
||||
&& self.tcx.is_type_alias_impl_trait(b_def_id)
|
||||
{
|
||||
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
|
||||
span: cause.span,
|
||||
|
@ -363,15 +359,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
op: |r| self.member_constraint(opaque_type_key, span, concrete_ty, r, &choice_regions),
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns the origin of the opaque type `def_id` if we're currently
|
||||
/// in its defining scope.
|
||||
#[instrument(skip(self), level = "trace", ret)]
|
||||
pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
|
||||
let origin = self.tcx.opaque_type_origin(def_id);
|
||||
|
||||
self.defining_opaque_types.contains(&def_id).then_some(origin)
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor that requires that (almost) all regions in the type visited outlive
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue