// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
- ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
+ ty::Opaque(ty::OpaqueTy { def_id, substs }) if !substs.has_escaping_bound_vars() => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self),
Reveal::All => {
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
- let obligation = Obligation::with_depth(
- self.tcx(),
- self.cause.clone(),
- recursion_limit.0,
- self.param_env,
- ty,
+ self.selcx.infcx.err_ctxt().report_overflow_error(
+ &ty,
+ self.cause.span,
+ true,
+ |_| {},
);
- self.selcx.infcx.err_ctxt().report_overflow_error(&obligation, true);
}
let substs = substs.fold_with(self);
// If so, extract what we know from the trait and try to come up with a good answer.
let bounds = match *obligation.predicate.self_ty().kind() {
ty::Projection(ref data) => tcx.bound_item_bounds(data.item_def_id).subst(tcx, data.substs),
- ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs),
+ ty::Opaque(ty::OpaqueTy { def_id, substs }) => {
+ tcx.bound_item_bounds(def_id).subst(tcx, substs)
+ }
ty::Infer(ty::TyVar(_)) => {
// If the self-type is an inference variable, then it MAY wind up
// being a projected type, so induce an ambiguity.
nested: &mut Vec<PredicateObligation<'tcx>>,
) {
let tcx = selcx.tcx();
- for predicate in tcx
+ let own = tcx
.predicates_of(obligation.predicate.item_def_id)
- .instantiate_own(tcx, obligation.predicate.substs)
- .predicates
- {
+ .instantiate_own(tcx, obligation.predicate.substs);
+ for (predicate, span) in std::iter::zip(own.predicates, own.spans) {
let normalized = normalize_with_depth_to(
selcx,
obligation.param_env,
predicate,
nested,
);
+
+ let nested_cause = if matches!(
+ obligation.cause.code(),
+ super::CompareImplItemObligation { .. }
+ | super::CheckAssociatedTypeBounds { .. }
+ | super::AscribeUserTypeProvePredicate(..)
+ ) {
+ obligation.cause.clone()
+ } else if span.is_dummy() {
+ ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ super::ItemObligation(obligation.predicate.item_def_id),
+ )
+ } else {
+ ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ super::BindingObligation(obligation.predicate.item_def_id, span),
+ )
+ };
nested.push(Obligation::with_depth(
tcx,
- obligation.cause.clone(),
+ nested_cause,
obligation.recursion_depth + 1,
obligation.param_env,
normalized,