Skip to content

Remove DefiningAnchor from InferCtxt #108389

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0d4017c
Don't look at InferCtxt::defining_use_anchor from deep inside the opa…
oli-obk Feb 21, 2023
ff7b19b
Add `DefiningAnchor` to `FnCtxt` in preparation for removing it from …
oli-obk Feb 21, 2023
379c5ac
Prefer a local `DefiningAnchor` over the `InferCtxt` one
oli-obk Feb 21, 2023
d0f6215
Avoid using the old anchor in new_in_snapshot
oli-obk Feb 21, 2023
f928076
Actually set the defining use anchor on ObligationCtxt
oli-obk Feb 22, 2023
b0639e9
Avoid giving an inferctxt a defining use anchor
oli-obk Feb 22, 2023
581c1e0
Stop using `old_defining_use_anchor` except in `select_where_possible`
oli-obk Feb 22, 2023
60ac06e
Bubble `old_defining_use_anchor` upwards from `select_all_or_error`
oli-obk Feb 23, 2023
ace9146
Bubble defining use anchor out of `fully_solve_obligations`
oli-obk Feb 23, 2023
9543b0e
Bubble anchor out of fully_solve_obligation
oli-obk Feb 23, 2023
26f46e8
Replace a use of `old_defining_use_anchor` with `Error` (it was alway…
oli-obk Feb 23, 2023
c7c4f24
Replace another `old_defining_use_anchor` with error
oli-obk Feb 23, 2023
2a39fb2
Replace two uses of `old_defining_use_anchor` with error
oli-obk Feb 23, 2023
6ff727b
Bubble up the defining_use_anchor from `fully_perform`
oli-obk Feb 23, 2023
5fcffb6
Remove another use of `old_defining_use_anchor`
oli-obk Feb 23, 2023
209103f
Remove the final use of `old_defining_use_anchor`
oli-obk Feb 23, 2023
429e107
Remove `DefiningAnchor` from `InferCtxt` entirely
oli-obk Feb 23, 2023
ad0bb9c
Require all ObligationCtxt to have a defining anchor at creation time
oli-obk Feb 23, 2023
f26c91b
Give all trait engines direct access to `DefiningAnchor` instead of p…
oli-obk Feb 23, 2023
a5f9af2
Remove the now-redundant field from Inherited
oli-obk Feb 23, 2023
01aacd4
Require SelectionContext to have a `DefiningAnchor` from the start
oli-obk Feb 23, 2023
e920c5d
Add `at` methods to `FnCtxt` and `Coerce` to simplify the "inherited"…
oli-obk Feb 23, 2023
17f29f4
Require all `.at` calls to provide a defining use anchor
oli-obk Feb 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/consumers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ pub fn get_body_with_borrowck_facts(
def: ty::WithOptConstParam<LocalDefId>,
) -> BodyWithBorrowckFacts<'_> {
let (input_body, promoted) = tcx.mir_promoted(def);
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build();
let infcx = tcx.infer_ctxt().build();
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()
*super::do_mir_borrowck(&infcx, input_body, promoted, true, DefiningAnchor::Bind(def.did))
.1
.unwrap()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_infer::infer::region_constraints::Constraint;
use rustc_infer::infer::region_constraints::RegionConstraintData;
use rustc_infer::infer::DefiningAnchor;
use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
use rustc_infer::traits::ObligationCause;
Expand Down Expand Up @@ -245,7 +246,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new(&infcx, DefiningAnchor::Error);
type_op_prove_predicate_with_cause(&ocx, key, cause);
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
}
Expand Down Expand Up @@ -286,7 +287,7 @@ where
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new(&infcx, DefiningAnchor::Error);

// FIXME(lqd): Unify and de-duplicate the following with the actual
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
Expand Down Expand Up @@ -330,7 +331,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new(&infcx, DefiningAnchor::Error);
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
}
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,17 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor

let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;

let infcx =
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
let infcx = tcx.infer_ctxt().build();
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0;
let opt_closure_req = do_mir_borrowck(
&infcx,
input_body,
promoted,
false,
DefiningAnchor::Bind(hir_owner.def_id),
)
.0;
debug!("mir_borrowck done");

tcx.arena.alloc(opt_closure_req)
Expand All @@ -173,6 +179,7 @@ fn do_mir_borrowck<'tcx>(
input_body: &Body<'tcx>,
input_promoted: &IndexVec<Promoted, Body<'tcx>>,
return_body_with_facts: bool,
defining_use_anchor: DefiningAnchor,
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
let def = input_body.source.with_opt_param().as_local().unwrap();
debug!(?def);
Expand Down Expand Up @@ -275,6 +282,7 @@ fn do_mir_borrowck<'tcx>(
&borrow_set,
&upvars,
use_polonius,
defining_use_anchor,
);

// Dump MIR results into a file, if that is enabled. This let us
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use rustc_data_structures::vec_map::VecMap;
use rustc_hir::def_id::LocalDefId;
use rustc_index::vec::IndexVec;
use rustc_infer::infer::DefiningAnchor;
use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
use rustc_middle::mir::{
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Expand Down Expand Up @@ -167,6 +168,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
borrow_set: &BorrowSet<'tcx>,
upvars: &[Upvar<'tcx>],
use_polonius: bool,
defining_use_anchor: DefiningAnchor,
) -> NllOutput<'tcx> {
let mut all_facts =
(use_polonius || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default());
Expand All @@ -191,6 +193,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
elements,
upvars,
use_polonius,
defining_use_anchor,
);

if let Some(all_facts) = &mut all_facts {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,11 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
// This logic duplicates most of `check_opaque_meets_bounds`.
// FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
let param_env = self.tcx.param_env(def_id);
let infcx = self.tcx.infer_ctxt().build();
// HACK This bubble is required for this tests to pass:
// nested-return-type2-tait2.rs
// nested-return-type2-tait3.rs
let infcx =
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new(&infcx, DefiningAnchor::Bubble);
// Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fmt;

use rustc_infer::infer::DefiningAnchor;
use rustc_infer::infer::{canonical::Canonical, InferOk};
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
Expand Down Expand Up @@ -37,7 +38,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
{
let old_universe = self.infcx.universe();

let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?;
let TypeOpOutput { output, constraints, error_info } =
op.fully_perform(self.infcx, self.defining_use_anchor)?;

debug!(?output, ?constraints);

Expand Down Expand Up @@ -220,7 +222,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let cause = ObligationCause::dummy_with_span(span);
let param_env = self.param_env;
let op = |infcx: &'_ _| {
let ocx = ObligationCtxt::new_in_snapshot(infcx);
let ocx = ObligationCtxt::new_in_snapshot(infcx, DefiningAnchor::Error);
let user_ty = ocx.normalize(&cause, param_env, user_ty);
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
if !ocx.select_all_or_error().is_empty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx)
.fully_perform(self.infcx, rustc_infer::infer::DefiningAnchor::Error)
.unwrap_or_else(|_| {
let guar = self
.infcx
Expand Down Expand Up @@ -349,7 +349,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
let TypeOpOutput { output: bounds, constraints, .. } = self
.param_env
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
.fully_perform(self.infcx)
.fully_perform(self.infcx, rustc_infer::infer::DefiningAnchor::Error)
.unwrap_or_else(|_| bug!("failed to compute implied bounds {:?}", ty));
debug!(?bounds, ?constraints);
self.add_outlives_bounds(bounds);
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,10 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);

let param_env = typeck.param_env;
let TypeOpOutput { output, constraints, .. } =
param_env.and(DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx).unwrap();
let TypeOpOutput { output, constraints, .. } = param_env
.and(DropckOutlives::new(dropped_ty))
.fully_perform(typeck.infcx, typeck.defining_use_anchor)
.unwrap();

DropData { dropck_result: output, region_constraint_data: constraints }
}
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::region_constraints::RegionConstraintData;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
DefiningAnchor, InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime,
NllRegionVariableOrigin,
};
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
Expand Down Expand Up @@ -136,6 +137,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
elements: &Rc<RegionValueElements>,
upvars: &[Upvar<'tcx>],
use_polonius: bool,
defining_use_anchor: DefiningAnchor,
) -> MirTypeckResults<'tcx> {
let implicit_region_bound = infcx.tcx.mk_re_var(universal_regions.fr_fn_body);
let mut constraints = MirTypeckRegionConstraints {
Expand Down Expand Up @@ -182,6 +184,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
&region_bound_pairs,
implicit_region_bound,
&mut borrowck_context,
defining_use_anchor,
);

let errors_reported = {
Expand Down Expand Up @@ -877,6 +880,7 @@ struct TypeChecker<'a, 'tcx> {
implicit_region_bound: ty::Region<'tcx>,
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
defining_use_anchor: DefiningAnchor,
}

struct BorrowCheckContext<'a, 'tcx> {
Expand Down Expand Up @@ -1025,6 +1029,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
defining_use_anchor: DefiningAnchor,
) -> Self {
let mut checker = Self {
infcx,
Expand All @@ -1036,6 +1041,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
implicit_region_bound,
borrowck_context,
reported_errors: Default::default(),
defining_use_anchor,
};
checker.check_user_type_annotations();
checker
Expand Down Expand Up @@ -2714,10 +2720,15 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
/// constraints in our `InferCtxt`
type ErrorInfo = InstantiateOpaqueType<'tcx>;

fn fully_perform(mut self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
Ok(InferOk { value: (), obligations: self.obligations.clone() })
})?;
fn fully_perform(
mut self,
infcx: &InferCtxt<'tcx>,
defining_use_anchor: DefiningAnchor,
) -> Fallible<TypeOpOutput<'tcx, Self>> {
let (mut output, region_constraints) =
scrape_region_constraints(infcx, defining_use_anchor, || {
Ok(InferOk { value: (), obligations: self.obligations.clone() })
})?;
self.region_constraints = Some(region_constraints);
output.error_info = Some(self);
Ok(output)
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_borrowck/src/type_check/relate_tys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
self.locations.span(self.type_checker.body)
}

fn defining_use_anchor(&self) -> rustc_infer::infer::DefiningAnchor {
self.type_checker.defining_use_anchor
}

fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.type_checker.param_env
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_errors::{Diagnostic, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
Expand Down Expand Up @@ -744,15 +744,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

let implsrc = {
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
let mut selcx = SelectionContext::new(&infcx, DefiningAnchor::Error);
selcx.select(&obligation)
};

// do a well-formedness check on the trait method being called. This is because typeck only does a
// "non-const" check. This is required for correctness here.
{
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new(&infcx, DefiningAnchor::Error);

let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
let cause = ObligationCause::new(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_errors::{
};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir;
use rustc_middle::ty::print::with_no_trimmed_paths;
Expand Down Expand Up @@ -149,7 +149,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
);

let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
let mut selcx = SelectionContext::new(&infcx, DefiningAnchor::Error);
let implsrc = selcx.select(&obligation);

if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use rustc_errors::ErrorGuaranteed;
use rustc_hir::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_middle::mir;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
Expand Down Expand Up @@ -162,7 +162,7 @@ impl Qualif for NeedsNonConstDrop {
);

let infcx = cx.tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
let mut selcx = SelectionContext::new(&infcx, DefiningAnchor::Error);
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
// If we couldn't select a const destruct candidate, then it's bad
return true;
Expand All @@ -184,7 +184,12 @@ impl Qualif for NeedsNonConstDrop {
}

// If we had any errors, then it's bad
!traits::fully_solve_obligations(&infcx, impl_src.nested_obligations()).is_empty()
!traits::fully_solve_obligations(
&infcx,
impl_src.nested_obligations(),
rustc_infer::infer::DefiningAnchor::Error,
)
.is_empty()
}

fn in_adt_inherently<'tcx>(
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/util/compare_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ pub fn is_subtype<'tcx>(
return true;
}

let mut builder =
tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble);
let mut builder = tcx.infer_ctxt().ignoring_regions();
let infcx = builder.build();
let ocx = ObligationCtxt::new(&infcx);
let ocx = ObligationCtxt::new(&infcx, DefiningAnchor::Bubble);
let cause = ObligationCause::dummy();
let src = ocx.normalize(&cause, param_env, src);
let dest = ocx.normalize(&cause, param_env, dest);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_generics, Visitor as _};
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::middle::stability::AllowUnstable;
Expand Down Expand Up @@ -2231,7 +2231,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.iter()
.filter_map(|&(impl_, (assoc_item, def_scope))| {
infcx.probe(|_| {
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
let ocx = ObligationCtxt::new_in_snapshot(&infcx, DefiningAnchor::Error);

let impl_ty = tcx.type_of(impl_);
let impl_substs = infcx.fresh_item_substs(impl_);
Expand Down
Loading