1
Fork 0

Change InferCtxtBuilder from enter to build

This commit is contained in:
Cameron Steffen 2022-09-19 22:03:59 -05:00
parent 91269fa5b8
commit 283abbf0e7
53 changed files with 1966 additions and 2182 deletions

View file

@ -31,9 +31,8 @@ pub fn get_body_with_borrowck_facts<'tcx>(
def: ty::WithOptConstParam<LocalDefId>,
) -> BodyWithBorrowckFacts<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def);
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).enter(|infcx| {
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build();
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()
})
}

View file

@ -238,20 +238,11 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
cause.span,
&self.canonical_query,
|ref infcx, key, _| {
let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
try_extract_error_from_fulfill_cx(
fulfill_cx,
infcx,
placeholder_region,
error_region,
)
},
)
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
}
}
@ -288,10 +279,8 @@ where
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
cause.span,
&self.canonical_query,
|ref infcx, key, _| {
let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
let mut selcx = SelectionContext::new(infcx);
@ -303,22 +292,11 @@ where
// to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check
// after #85499 lands to see if its fixes have erased this difference.
let (param_env, value) = key.into_parts();
let Normalized { value: _, obligations } = rustc_trait_selection::traits::normalize(
&mut selcx,
param_env,
cause,
value.value,
);
let Normalized { value: _, obligations } =
rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value);
fulfill_cx.register_predicate_obligations(infcx, obligations);
try_extract_error_from_fulfill_cx(
fulfill_cx,
infcx,
placeholder_region,
error_region,
)
},
)
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
}
}
@ -349,21 +327,11 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
cause.span,
&self.canonical_query,
|ref infcx, key, _| {
let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span))
.ok()?;
try_extract_error_from_fulfill_cx(
fulfill_cx,
infcx,
placeholder_region,
error_region,
)
},
)
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
}
}

View file

@ -492,11 +492,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
return false;
};
tcx.infer_ctxt().enter(|infcx| {
infcx
tcx.infer_ctxt()
.build()
.type_implements_trait(default_trait, ty, ty::List::empty(), param_env)
.may_apply()
})
};
let assign_value = match ty.kind() {
@ -606,7 +605,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.and_then(|def_id| tcx.hir().get_generics(def_id))
else { return; };
// Try to find predicates on *generic params* that would allow copying `ty`
let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut fulfill_cx = <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
@ -627,7 +626,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let errors = fulfill_cx.select_all_or_error(&infcx);
// Only emit suggestion if all required predicates are on generic
errors
let predicates: Result<Vec<_>, _> = errors
.into_iter()
.map(|err| match err.obligation.predicate.kind().skip_binder() {
PredicateKind::Trait(predicate) => match predicate.self_ty().kind() {
@ -639,8 +638,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
},
_ => Err(()),
})
.collect()
});
.collect();
if let Ok(predicates) = predicates {
suggest_constraining_type_params(

View file

@ -1025,7 +1025,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
Some(def_id) => {
let infcx = self.infcx.tcx.infer_ctxt().build();
type_known_to_meet_bound_modulo_regions(
&infcx,
self.param_env,
@ -1036,7 +1037,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
def_id,
DUMMY_SP,
)
}),
}
_ => false,
};
if suggest {

View file

@ -131,14 +131,11 @@ fn mir_borrowck<'tcx>(
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let opt_closure_req = tcx
.infer_ctxt()
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
.enter(|infcx| {
let infcx =
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
do_mir_borrowck(&infcx, input_body, promoted, false).0
});
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0;
debug!("mir_borrowck done");
tcx.arena.alloc(opt_closure_req)

View file

@ -266,20 +266,21 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
// Only check this for TAIT. RPIT already supports `src/test/ui/impl-trait/nested-return-type2.rs`
// on stable and we'd break that.
if let OpaqueTyOrigin::TyAlias = origin {
let OpaqueTyOrigin::TyAlias = origin else {
return definition_ty;
};
// 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 body_id = self.tcx.local_def_id_to_hir_id(def_id);
// HACK This bubble is required for this tests to pass:
// type-alias-impl-trait/issue-67844-nested-opaque.rs
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(
move |infcx| {
let infcx =
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
// 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.
let predicate =
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
.to_predicate(infcx.tcx);
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
@ -329,11 +330,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
self.tcx.ty_error()
}
},
)
} else {
definition_ty
}
}
}

View file

@ -737,14 +737,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let obligation =
Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred);
let implsrc = tcx.infer_ctxt().enter(|infcx| {
let implsrc = {
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
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.
tcx.infer_ctxt().enter(|infcx| {
{
let infcx = tcx.infer_ctxt().build();
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
let hir_id = tcx
@ -777,7 +779,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
}
});
}
match implsrc {
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
@ -835,7 +837,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// improve diagnostics by showing what failed. Our requirements are stricter this time
// as we are going to error again anyways.
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
if let Err(e) = implsrc {
infcx.err_ctxt().report_selection_error(
obligation.clone(),
@ -844,7 +846,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
false,
);
}
});
self.check_op(ops::FnCallNonConst {
caller,

View file

@ -156,10 +156,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}),
);
let implsrc = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
selcx.select(&obligation)
});
let implsrc = selcx.select(&obligation);
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
let span = tcx.def_span(data.impl_def_id);

View file

@ -168,7 +168,7 @@ impl Qualif for NeedsNonConstDrop {
}),
);
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
// If we couldn't select a const destruct candidate, then it's bad
@ -177,8 +177,7 @@ impl Qualif for NeedsNonConstDrop {
if !matches!(
impl_src,
ImplSource::ConstDestruct(_)
| ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
) {
// If our const destruct candidate is not ConstDestruct or implied by the param env,
// then it's bad
@ -191,7 +190,6 @@ impl Qualif for NeedsNonConstDrop {
// If we had any errors, then it's bad
!traits::fully_solve_obligations(&infcx, impl_src.nested_obligations()).is_empty()
})
}
fn in_adt_inherently<'tcx>(

View file

@ -105,7 +105,7 @@ pub fn equal_up_to_regions<'tcx>(
},
)
};
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
tcx.infer_ctxt().build().can_eq(param_env, normalize(src), normalize(dest)).is_ok()
}
struct TypeChecker<'a, 'tcx> {

View file

@ -83,9 +83,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Res::Def(DefKind::TyParam, src_def_id) => {
if let Some(param_local_id) = param.def_id.as_local() {
let param_name = tcx.hir().ty_param_name(param_local_id);
let param_type = tcx.infer_ctxt().enter(|infcx| {
infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id))
});
let infcx = tcx.infer_ctxt().build();
let param_type =
infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id));
if param_type.is_suggestable(tcx, false) {
err.span_suggestion(
tcx.def_span(src_def_id),

View file

@ -732,8 +732,10 @@ fn check_opaque_meets_bounds<'tcx>(
};
let param_env = tcx.param_env(defining_use_anchor);
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor)).enter(
move |infcx| {
let infcx = tcx
.infer_ctxt()
.with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
.build();
let ocx = ObligationCtxt::new(&infcx);
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
@ -752,8 +754,8 @@ fn check_opaque_meets_bounds<'tcx>(
// Additionally 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.
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into()))
.to_predicate(tcx);
let predicate =
ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
// Check that all obligations are satisfied by the implementation's
@ -776,8 +778,6 @@ fn check_opaque_meets_bounds<'tcx>(
}
// Clean up after ourselves
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
},
);
}
fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {

View file

@ -215,7 +215,7 @@ fn compare_predicate_entailment<'tcx>(
);
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
@ -329,13 +329,10 @@ fn compare_predicate_entailment<'tcx>(
if trait_m.fn_has_self_parameter =>
{
let ty = trait_sig.inputs()[0];
let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty())
{
let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty()) {
ExplicitSelf::ByValue => "self".to_owned(),
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => {
"&mut self".to_owned()
}
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
_ => format!("self: {ty}"),
};
@ -432,7 +429,6 @@ fn compare_predicate_entailment<'tcx>(
);
Ok(())
})
}
pub fn collect_trait_impl_trait_tys<'tcx>(
@ -465,7 +461,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
let trait_to_placeholder_substs =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
@ -481,8 +477,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
.output(),
);
let mut collector =
ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
let unnormalized_trait_return_ty = tcx
.liberate_late_bound_regions(
impl_m.def_id,
@ -555,11 +550,8 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
// contains `def_id`'s early-bound regions.
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
debug!(?id_substs, ?substs);
let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> = substs
.iter()
.enumerate()
.map(|(index, arg)| (arg, id_substs[index]))
.collect();
let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> =
substs.iter().enumerate().map(|(index, arg)| (arg, id_substs[index])).collect();
debug!(?map);
let ty = tcx.fold_regions(ty, |region, _| {
@ -583,7 +575,6 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
}
Ok(&*tcx.arena.alloc(collected_tys))
})
}
struct ImplTraitInTraitCollector<'a, 'tcx> {
@ -768,7 +759,7 @@ fn compare_self_type<'tcx>(
let self_arg_ty = tcx.fn_sig(method.def_id).input(0);
let param_env = ty::ParamEnv::reveal_all();
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
@ -777,7 +768,6 @@ fn compare_self_type<'tcx>(
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
_ => format!("self: {self_arg_ty}"),
}
})
};
match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
@ -1312,7 +1302,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>(
let impl_c_span = tcx.def_span(impl_const_item_def.to_def_id());
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let param_env = tcx.param_env(impl_const_item_def.to_def_id());
let ocx = ObligationCtxt::new(&infcx);
@ -1406,10 +1396,8 @@ pub(crate) fn raw_compare_const_impl<'tcx>(
// FIXME return `ErrorReported` if region obligations error?
let outlives_environment = OutlivesEnvironment::new(param_env);
infcx
.check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment);
infcx.check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment);
Ok(())
})
}
pub(crate) fn compare_ty_impl<'tcx>(
@ -1490,7 +1478,7 @@ fn compare_type_predicate_entailment<'tcx>(
hir::Constness::NotConst,
);
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
@ -1498,8 +1486,7 @@ fn compare_type_predicate_entailment<'tcx>(
let mut selcx = traits::SelectionContext::new(&infcx);
assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len());
for (span, predicate) in
std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
for (span, predicate) in std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
{
let cause = ObligationCause::misc(span, impl_ty_hir_id);
let traits::Normalized { value: predicate, obligations } =
@ -1535,7 +1522,6 @@ fn compare_type_predicate_entailment<'tcx>(
);
Ok(())
})
}
/// Validate that `ProjectionCandidate`s created for this associated type will
@ -1695,7 +1681,7 @@ pub fn check_type_bounds<'tcx>(
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
tcx.infer_ctxt().enter(move |infcx| {
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let assumed_wf_types =
@ -1783,7 +1769,6 @@ pub fn check_type_bounds<'tcx>(
}
Ok(())
})
}
fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {

View file

@ -876,18 +876,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
let ty = self.normalize_associated_types_in(expr.span, ty);
let ty = match self.tcx.asyncness(fn_id.owner) {
hir::IsAsync::Async => self
.tcx
.infer_ctxt()
.enter(|infcx| {
infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| {
hir::IsAsync::Async => {
let infcx = self.tcx.infer_ctxt().build();
infcx
.get_impl_future_output_ty(ty)
.unwrap_or_else(|| {
span_bug!(
fn_decl.output.span(),
"failed to get output type of async function"
)
})
})
.skip_binder(),
.skip_binder()
}
hir::IsAsync::NotAsync => ty,
};
if self.can_coerce(found, ty) {

View file

@ -129,7 +129,7 @@ impl<'tcx> InheritedBuilder<'tcx> {
F: FnOnce(&Inherited<'tcx>) -> R,
{
let def_id = self.def_id;
self.infcx.enter(|infcx| f(&Inherited::new(infcx, def_id, self.typeck_results)))
f(&Inherited::new(self.infcx.build(), def_id, self.typeck_results))
}
}

View file

@ -472,7 +472,7 @@ fn method_autoderef_steps<'tcx>(
) -> MethodAutoderefStepsResult<'tcx> {
debug!("method_autoderef_steps({:?})", goal);
tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &goal, |ref infcx, goal, inference_vars| {
let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal);
let ParamEnvAnd { param_env, value: self_ty } = goal;
let mut autoderef =
@ -484,10 +484,8 @@ fn method_autoderef_steps<'tcx>(
.by_ref()
.map(|(ty, d)| {
let step = CandidateStep {
self_ty: infcx.make_query_response_ignoring_pending_obligations(
inference_vars.clone(),
ty,
),
self_ty: infcx
.make_query_response_ignoring_pending_obligations(inference_vars.clone(), ty),
autoderefs: d,
from_unsafe_deref: reached_raw_pointer,
unsize: false,
@ -504,8 +502,7 @@ fn method_autoderef_steps<'tcx>(
let opt_bad_ty = match final_ty.kind() {
ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
reached_raw_pointer,
ty: infcx
.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
}),
ty::Array(elem_ty, _) => {
let dereferences = steps.len() - 1;
@ -534,7 +531,6 @@ fn method_autoderef_steps<'tcx>(
opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),
reached_recursion_limit: autoderef.reached_recursion_limit(),
}
})
}
impl<'a, 'tcx> ProbeContext<'a, 'tcx> {

View file

@ -91,7 +91,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
{
let param_env = tcx.param_env(body_def_id);
let body_id = tcx.hir().local_def_id_to_hir_id(body_def_id);
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id);
@ -113,7 +113,6 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
})
}
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {
@ -704,7 +703,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
// Unfortunately, we have to use a new `InferCtxt` each call, because
// region constraints get added and solved there and we need to test each
// call individually.
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let outlives_environment = OutlivesEnvironment::with_bounds(
param_env,
Some(&infcx),
@ -721,7 +720,6 @@ fn resolve_regions_with_wf_tys<'tcx>(
// If we were able to prove that the type outlives the region without
// an error, it must be because of the implied or explicit bounds...
errors.is_empty()
})
}
/// TypeVisitor that looks for uses of GATs like

View file

@ -108,7 +108,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
// why this field does not implement Copy. This is useful because sometimes
// it is not immediately clear why Copy is not implemented for a field, since
// all we point at is the field itself.
tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
let infcx = tcx.infer_ctxt().ignoring_regions().build();
for error in traits::fully_solve_bound(
&infcx,
traits::ObligationCause::dummy_with_span(field_ty_span),
@ -144,7 +144,6 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
}
}
}
});
}
for ((ty, error_predicate), spans) in errors {
let span: MultiSpan = spans.into();
@ -205,7 +204,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
let create_err = |msg: &str| struct_span_err!(tcx.sess, span, E0378, "{}", msg);
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let cause = ObligationCause::misc(span, impl_hir_id);
use rustc_type_ir::sty::TyKind::*;
@ -283,9 +282,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
)
.emit();
} else if coerced_fields.len() > 1 {
create_err(
"implementing the `DispatchFromDyn` trait requires multiple coercions",
)
create_err("implementing the `DispatchFromDyn` trait requires multiple coercions")
.note(
"the trait `DispatchFromDyn` may only be implemented \
for a coercion between structures with a single field \
@ -340,7 +337,6 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
.emit();
}
}
})
}
pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedInfo {
@ -369,7 +365,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)", source, target);
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_did);
let cause = ObligationCause::misc(span, impl_hir_id);
let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
@ -401,9 +397,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty))
}
(&ty::RawPtr(mt_a), &ty::RawPtr(mt_b)) => {
check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty))
}
(&ty::RawPtr(mt_a), &ty::RawPtr(mt_b)) => check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty)),
(&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b))
if def_a.is_struct() && def_b.is_struct() =>
@ -510,9 +504,8 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
return err_info;
} else if diff_fields.len() > 1 {
let item = tcx.hir().expect_item(impl_did);
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) =
item.kind
{
let span =
if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) = item.kind {
t.path.span
} else {
tcx.def_span(impl_did)
@ -535,9 +528,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
diff_fields.len(),
diff_fields
.iter()
.map(|&(i, a, b)| {
format!("`{}` (`{}` to `{}`)", fields[i].name, a, b)
})
.map(|&(i, a, b)| { format!("`{}` (`{}` to `{}`)", fields[i].name, a, b) })
.collect::<Vec<_>>()
.join(", ")
))
@ -566,15 +557,8 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
// Register an obligation for `A: Trait<B>`.
let cause = traits::ObligationCause::misc(span, impl_hir_id);
let predicate = predicate_for_trait_def(
tcx,
param_env,
cause,
trait_def_id,
0,
source,
&[target.into()],
);
let predicate =
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]);
let errors = traits::fully_solve_obligation(&infcx, predicate);
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
@ -585,5 +569,4 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
CoerceUnsizedInfo { custom_kind: kind }
})
}

View file

@ -64,9 +64,8 @@ fn diagnostic_hir_wf_check<'tcx>(
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
self.tcx.infer_ctxt().enter(|infcx| {
let tcx_ty =
self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let infcx = self.tcx.infer_ctxt().build();
let tcx_ty = self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let cause = traits::ObligationCause::new(
ty.span,
self.hir_id,
@ -95,7 +94,6 @@ fn diagnostic_hir_wf_check<'tcx>(
}
}
}
});
self.depth += 1;
intravisit::walk_ty(self, ty);
self.depth -= 1;

View file

@ -139,7 +139,7 @@ fn get_impl_substs<'tcx>(
impl1_def_id: LocalDefId,
impl2_node: Node,
) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let param_env = tcx.param_env(impl1_def_id);
let impl1_hir_id = tcx.hir().local_def_id_to_hir_id(impl1_def_id);
@ -166,7 +166,6 @@ fn get_impl_substs<'tcx>(
return None;
};
Some((impl1_substs, impl2_substs))
})
}
/// Returns a list of all of the unconstrained subst of the given impl.
@ -344,7 +343,7 @@ fn check_predicates<'tcx>(
// Include the well-formed predicates of the type parameters of the impl.
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs {
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &tcx.infer_ctxt().build();
let obligations = wf::obligations(
infcx,
tcx.param_env(impl1_def_id),
@ -357,10 +356,8 @@ fn check_predicates<'tcx>(
assert!(!obligations.needs_infer());
impl2_predicates.extend(
traits::elaborate_obligations(tcx, obligations)
.map(|obligation| obligation.predicate),
traits::elaborate_obligations(tcx, obligations).map(|obligation| obligation.predicate),
)
})
}
impl2_predicates.extend(
traits::elaborate_predicates_with_span(tcx, always_applicable_traits)

View file

@ -141,7 +141,7 @@ fn require_same_types<'tcx>(
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> bool {
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &tcx.infer_ctxt().build();
let param_env = ty::ParamEnv::empty();
let errors = match infcx.at(cause, param_env).eq(expected, actual) {
Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
@ -158,7 +158,6 @@ fn require_same_types<'tcx>(
false
}
}
})
}
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
@ -305,7 +304,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
error = true;
}
let return_ty = return_ty.skip_binder();
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
// Main should have no WC, so empty param env is OK here.
let param_env = ty::ParamEnv::empty();
let cause = traits::ObligationCause::new(
@ -321,7 +320,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
error = true;
}
});
// now we can take the return type of the given main function
expected_return_type = main_fnsig.output();
} else {

View file

@ -602,30 +602,27 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// `V` and a substitution `S`. This substitution `S` maps from
/// the bound values in `C` to their instantiated values in `V`
/// (in other words, `S(C) = V`).
pub fn enter_with_canonical<T, R>(
pub fn build_with_canonical<T>(
&mut self,
span: Span,
canonical: &Canonical<'tcx, T>,
f: impl FnOnce(InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) -> R,
) -> R
) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
where
T: TypeFoldable<'tcx>,
{
self.enter(|infcx| {
let (value, subst) =
infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
f(infcx, value, subst)
})
let infcx = self.build();
let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
(infcx, value, subst)
}
pub fn enter<R>(&mut self, f: impl FnOnce(InferCtxt<'tcx>) -> R) -> R {
pub fn build(&mut self) -> InferCtxt<'tcx> {
let InferCtxtBuilder {
tcx,
defining_use_anchor,
considering_regions,
ref normalize_fn_sig_for_diagnostic,
} = *self;
f(InferCtxt {
InferCtxt {
tcx,
defining_use_anchor,
considering_regions,
@ -643,7 +640,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
.as_ref()
.map(|f| f.clone()),
})
}
}
}

View file

@ -151,21 +151,19 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did()),
);
let (suggest_display, suggest_debug) = cx.tcx.infer_ctxt().enter(|infcx| {
let display = is_str
let infcx = cx.tcx.infer_ctxt().build();
let suggest_display = is_str
|| cx.tcx.get_diagnostic_item(sym::Display).map(|t| {
infcx
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
.may_apply()
}) == Some(true);
let debug = !display
let suggest_debug = !suggest_display
&& cx.tcx.get_diagnostic_item(sym::Debug).map(|t| {
infcx
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
.may_apply()
}) == Some(true);
(display, debug)
});
let suggest_panic_any = !is_str && panic == sym::std_panic_macro;

View file

@ -62,17 +62,14 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; };
let def_id = item.def_id.def_id.to_def_id();
cx.tcx.infer_ctxt().enter(|ref infcx| {
let infcx = &cx.tcx.infer_ctxt().build();
// For every projection predicate in the opaque type's explicit bounds,
// check that the type that we're assigning actually satisfies the bounds
// of the associated type.
for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) {
// Liberate bound regions in the predicate since we
// don't actually care about lifetimes in this check.
let predicate = cx.tcx.liberate_late_bound_regions(
def_id,
pred.kind(),
);
let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind());
let ty::PredicateKind::Projection(proj) = predicate else {
continue;
};
@ -81,9 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
let Some(proj_term) = proj.term.ty() else { continue };
let proj_ty =
cx
.tcx
.mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs);
cx.tcx.mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs);
// For every instance of the projection type in the bounds,
// replace them with the term we're assigning to the associated
// type in our opaque type.
@ -96,10 +91,8 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
// e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
// with `impl Send: OtherTrait`.
for assoc_pred_and_span in cx
.tcx
.bound_explicit_item_bounds(proj.projection_ty.item_def_id)
.transpose_iter()
for assoc_pred_and_span in
cx.tcx.bound_explicit_item_bounds(proj.projection_ty.item_def_id).transpose_iter()
{
let assoc_pred_span = assoc_pred_and_span.0.1;
let assoc_pred = assoc_pred_and_span
@ -119,19 +112,23 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
)) {
// If it's a trait bound and an opaque that doesn't satisfy it,
// then we can emit a suggestion to add the bound.
let add_bound =
match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
(ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => Some(AddBound {
let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
(ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => {
Some(AddBound {
suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
trait_ref: trait_pred.print_modifiers_and_trait_path(),
}),
})
}
_ => None,
};
cx.emit_spanned_lint(
OPAQUE_HIDDEN_INFERRED_BOUND,
pred_span,
OpaqueHiddenInferredBoundLint {
ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)),
ty: cx.tcx.mk_opaque(
def_id,
ty::InternalSubsts::identity_for_item(cx.tcx, def_id),
),
proj_ty: proj_term,
assoc_pred_span,
add_bound,
@ -140,7 +137,6 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
}
}
}
});
}
}

View file

@ -481,7 +481,7 @@ fn construct_fn<'tcx>(
(None, fn_sig.output())
};
let mut body = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut builder = Builder::new(
thir,
infcx,
@ -505,11 +505,8 @@ fn construct_fn<'tcx>(
let arg_scope_s = (arg_scope, source_info);
// Attribute epilogue to function's closing brace
let fn_end = span_with_body.shrink_to_hi();
let return_block = unpack!(builder.in_breakable_scope(
None,
Place::return_place(),
fn_end,
|builder| {
let return_block =
unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
builder.args_and_body(
START_BLOCK,
@ -519,16 +516,14 @@ fn construct_fn<'tcx>(
&thir[expr],
)
}))
}
));
}));
let source_info = builder.source_info(fn_end);
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
builder.build_drop_trees();
return_block.unit()
}));
builder.finish()
});
let mut body = builder.finish();
body.spread_arg = if abi == Abi::RustCall {
// RustCall pseudo-ABI untuples the last argument.
@ -584,7 +579,7 @@ fn construct_const<'a, 'tcx>(
let typeck_results = tcx.typeck_opt_const_arg(def);
let const_ty = typeck_results.node_type(hir_id);
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut builder = Builder::new(
thir,
infcx,
@ -607,7 +602,6 @@ fn construct_const<'a, 'tcx>(
builder.build_drop_trees();
builder.finish()
})
}
/// Construct MIR for an item that has had errors in type checking.

View file

@ -28,10 +28,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
span: Span,
mir_structural_match_violation: bool,
) -> Box<Pat<'tcx>> {
self.tcx.infer_ctxt().enter(|infcx| {
let infcx = self.tcx.infer_ctxt().build();
let mut convert = ConstToPat::new(self, id, span, infcx);
convert.to_pat(cv, mir_structural_match_violation)
})
}
}

View file

@ -177,18 +177,10 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
R: Debug + TypeFoldable<'tcx>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
{
self.enter_with_canonical(
DUMMY_SP,
canonical_key,
|ref infcx, key, canonical_inference_vars| {
let (ref infcx, key, canonical_inference_vars) =
self.build_with_canonical(DUMMY_SP, canonical_key);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
let value = operation(infcx, &mut *fulfill_cx, key)?;
infcx.make_canonicalized_query_response(
canonical_inference_vars,
value,
&mut *fulfill_cx,
)
},
)
infcx.make_canonicalized_query_response(canonical_inference_vars, value, &mut *fulfill_cx)
}
}

View file

@ -10,7 +10,7 @@ use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{Region, RegionVid};
use rustc_middle::ty::{PolyTraitRef, Region, RegionVid};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -90,51 +90,26 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let trait_pred = ty::Binder::dummy(trait_ref);
let bail_out = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
let result = selcx.select(&Obligation::new(
ObligationCause::dummy(),
orig_env,
trait_pred.to_poly_trait_predicate(),
));
match result {
Ok(Some(ImplSource::UserDefined(_))) => {
for f in [
PolyTraitRef::to_poly_trait_predicate,
PolyTraitRef::to_poly_trait_predicate_negative_polarity,
] {
let result =
selcx.select(&Obligation::new(ObligationCause::dummy(), orig_env, f(&trait_pred)));
if let Ok(Some(ImplSource::UserDefined(_))) = result {
debug!(
"find_auto_trait_generics({:?}): \
manual impl found, bailing out",
trait_ref
);
return true;
}
_ => {}
}
let result = selcx.select(&Obligation::new(
ObligationCause::dummy(),
orig_env,
trait_pred.to_poly_trait_predicate_negative_polarity(),
));
match result {
Ok(Some(ImplSource::UserDefined(_))) => {
debug!(
"find_auto_trait_generics({:?}): \
manual impl found, bailing out",
trait_ref
);
true
}
_ => false,
}
});
// If an explicit impl exists, it always takes priority over an auto impl
if bail_out {
return AutoTraitResult::ExplicitImpl;
}
}
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut fresh_preds = FxHashSet::default();
// Due to the way projections are handled by SelectionContext, we need to run
@ -183,15 +158,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
};
let (full_env, full_user_env) = self
.evaluate_predicates(
&infcx,
trait_did,
ty,
new_env,
user_env,
&mut fresh_preds,
true,
)
.evaluate_predicates(&infcx, trait_did, ty, new_env, user_env, &mut fresh_preds, true)
.unwrap_or_else(|| {
panic!("Failed to fully process: {:?} {:?} {:?}", ty, trait_did, orig_env)
});
@ -214,19 +181,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
infcx.process_registered_region_obligations(&Default::default(), full_env);
let region_data = infcx
.inner
.borrow_mut()
.unwrap_region_constraints()
.region_constraint_data()
.clone();
let region_data =
infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();
let vid_to_region = self.map_vid_to_region(&region_data);
let info = AutoTraitInfo { full_user_env, region_data, vid_to_region };
AutoTraitResult::PositiveImpl(auto_trait_callback(info))
})
}
}

View file

@ -29,9 +29,11 @@ pub fn codegen_select_candidate<'tcx>(
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
let mut infcx_builder =
tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble);
infcx_builder.enter(|infcx| {
let infcx = tcx
.infer_ctxt()
.ignoring_regions()
.with_opaque_type_inference(DefiningAnchor::Bubble)
.build();
//~^ HACK `Bubble` is required for
// this test to pass: type-alias-impl-trait/assoc-projection-ice.rs
let mut selcx = SelectionContext::new(&infcx);
@ -84,5 +86,4 @@ pub fn codegen_select_candidate<'tcx>(
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
Ok(&*tcx.arena.alloc(impl_source))
})
}

View file

@ -100,11 +100,10 @@ where
return no_overlap();
}
let overlaps = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let selcx = &mut SelectionContext::intercrate(&infcx);
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some()
});
let overlaps =
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
if !overlaps {
return no_overlap();
}
@ -112,13 +111,10 @@ where
// In the case where we detect an error, run the check again, but
// this time tracking intercrate ambiguity causes for better
// diagnostics. (These take time and can lead to false errors.)
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let selcx = &mut SelectionContext::intercrate(&infcx);
selcx.enable_tracking_intercrate_ambiguity_causes();
on_overlap(
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap(),
)
})
on_overlap(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
}
fn with_fresh_ty_vars<'cx, 'tcx>(
@ -298,7 +294,7 @@ fn negative_impl<'cx, 'tcx>(
let tcx = selcx.infcx().tcx;
// Create an infcx, taking the predicates of impl1 as assumptions:
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
// create a parameter environment corresponding to a (placeholder) instantiation of impl1
let impl_env = tcx.param_env(impl1_def_id);
let subject1 = match traits::fully_normalize(
@ -324,7 +320,6 @@ fn negative_impl<'cx, 'tcx>(
impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs);
!equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id)
})
}
fn equate<'tcx>(

View file

@ -1930,16 +1930,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
let normalize = |candidate| {
self.tcx.infer_ctxt().enter(|ref infcx| {
let normalized = infcx
let infcx = self.tcx.infer_ctxt().build();
infcx
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
.normalize(candidate)
.ok();
match normalized {
Some(normalized) => normalized.value,
None => candidate,
}
})
.map_or(candidate, |normalized| normalized.value)
};
// Sort impl candidates so that ordering is consistent for UI tests.

View file

@ -23,7 +23,7 @@ pub fn can_type_implement_copy<'tcx>(
parent_cause: ObligationCause<'tcx>,
) -> Result<(), CopyImplementationError<'tcx>> {
// FIXME: (@jroesch) float this code up
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let (adt, substs) = match self_type.kind() {
// These types used to have a builtin impl.
// Now libcore provides that impl.
@ -83,5 +83,4 @@ pub fn can_type_implement_copy<'tcx>(
}
Ok(())
})
}

View file

@ -234,7 +234,7 @@ fn do_normalize_predicates<'tcx>(
// by wfcheck anyway, so I'm not sure we have to check
// them here too, and we will remove this function when
// we move over to lazy normalization *anyway*.
tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
let infcx = tcx.infer_ctxt().ignoring_regions().build();
let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
Ok(predicates) => predicates,
Err(errors) => {
@ -256,9 +256,7 @@ fn do_normalize_predicates<'tcx>(
if !errors.is_empty() {
tcx.sess.delay_span_bug(
span,
format!(
"failed region resolution while normalizing {elaborated_env:?}: {errors:?}"
),
format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"),
);
}
@ -281,7 +279,6 @@ fn do_normalize_predicates<'tcx>(
);
}
}
})
}
// FIXME: this is gonna need to be removed ...
@ -473,7 +470,7 @@ pub fn impossible_predicates<'tcx>(
) -> bool {
debug!("impossible_predicates(predicates={:?})", predicates);
let result = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let param_env = ty::ParamEnv::reveal_all();
let ocx = ObligationCtxt::new(&infcx);
let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates);
@ -486,8 +483,7 @@ pub fn impossible_predicates<'tcx>(
// Clean up after ourselves
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
!errors.is_empty()
});
let result = !errors.is_empty();
debug!("impossible_predicates = {:?}", result);
result
}
@ -578,7 +574,7 @@ fn is_impossible_method<'tcx>(
}
});
tcx.infer_ctxt().ignoring_regions().enter(|ref infcx| {
let infcx = tcx.infer_ctxt().ignoring_regions().build();
for obligation in predicates_for_trait {
// Ignore overflow error, to be conservative.
if let Ok(result) = infcx.evaluate_obligation(&obligation)
@ -587,9 +583,7 @@ fn is_impossible_method<'tcx>(
return true;
}
}
false
})
}
#[derive(Clone, Debug)]
@ -952,10 +946,9 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
}),
);
let implsrc = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
selcx.select(&obligation).unwrap()
});
let implsrc = selcx.select(&obligation).unwrap();
let Some(ImplSource::TraitUpcasting(implsrc_traitcasting)) = implsrc else {
bug!();

View file

@ -734,10 +734,9 @@ fn receiver_is_dispatchable<'tcx>(
Obligation::new(ObligationCause::dummy(), param_env, predicate)
};
tcx.infer_ctxt().enter(|ref infcx| {
let infcx = tcx.infer_ctxt().build();
// the receiver is dispatchable iff the obligation holds
infcx.predicate_must_hold_modulo_regions(&obligation)
})
}
fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(

View file

@ -149,13 +149,9 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
// Create an infcx, taking the predicates of impl1 as assumptions:
tcx.infer_ctxt().enter(|infcx| {
let impl1_trait_ref = match traits::fully_normalize(
&infcx,
ObligationCause::dummy(),
penv,
impl1_trait_ref,
) {
let infcx = tcx.infer_ctxt().build();
let impl1_trait_ref =
match traits::fully_normalize(&infcx, ObligationCause::dummy(), penv, impl1_trait_ref) {
Ok(impl1_trait_ref) => impl1_trait_ref,
Err(_errors) => {
tcx.sess.delay_span_bug(
@ -168,7 +164,6 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
// Attempt to prove that impl2 applies, given all of the above.
fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok()
})
}
/// Attempt to fulfill all obligations of `target_impl` after unification with

View file

@ -265,9 +265,8 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
pub fn provide(providers: &mut Providers) {
providers.has_structural_eq_impls = |tcx, ty| {
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let cause = ObligationCause::dummy();
type_marked_structural(&infcx, ty, cause)
})
};
}

View file

@ -27,10 +27,8 @@ fn dropck_outlives<'tcx>(
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> {
debug!("dropck_outlives(goal={:#?})", canonical_goal);
tcx.infer_ctxt().enter_with_canonical(
DUMMY_SP,
&canonical_goal,
|ref infcx, goal, canonical_inference_vars| {
let (ref infcx, goal, canonical_inference_vars) =
tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal);
let tcx = infcx.tcx;
let ParamEnvAnd { param_env, value: for_ty } = goal;
@ -142,13 +140,7 @@ fn dropck_outlives<'tcx>(
debug!("dropck_outlives: result = {:#?}", result);
infcx.make_canonicalized_query_response(
canonical_inference_vars,
result,
&mut *fulfill_cx,
)
},
)
infcx.make_canonicalized_query_response(canonical_inference_vars, result, &mut *fulfill_cx)
}
/// Returns a set of constraints that needs to be satisfied in

View file

@ -18,10 +18,10 @@ fn evaluate_obligation<'tcx>(
debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal);
// HACK This bubble is required for this tests to pass:
// impl-trait/issue99642.rs
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter_with_canonical(
DUMMY_SP,
&canonical_goal,
|ref infcx, goal, _canonical_inference_vars| {
let (ref infcx, goal, _canonical_inference_vars) = tcx
.infer_ctxt()
.with_opaque_type_inference(DefiningAnchor::Bubble)
.build_with_canonical(DUMMY_SP, &canonical_goal);
debug!("evaluate_obligation: goal={:#?}", goal);
let ParamEnvAnd { param_env, value: predicate } = goal;
@ -29,6 +29,4 @@ fn evaluate_obligation<'tcx>(
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
selcx.evaluate_root_obligation(&obligation)
},
)
}

View file

@ -30,7 +30,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
goal: ParamEnvAnd<'tcx, T>,
) -> Result<T, NoSolution> {
let ParamEnvAnd { param_env, value } = goal;
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let cause = ObligationCause::dummy();
match infcx.at(&cause, param_env).normalize(value) {
Ok(Normalized { value: normalized_value, obligations: normalized_obligations }) => {
@ -53,7 +53,6 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
}
Err(NoSolution) => Err(NoSolution),
}
})
}
fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {

View file

@ -29,15 +29,8 @@ fn is_item_raw<'tcx>(
) -> bool {
let (param_env, ty) = query.into_parts();
let trait_def_id = tcx.require_lang_item(item, None);
tcx.infer_ctxt().enter(|infcx| {
traits::type_known_to_meet_bound_modulo_regions(
&infcx,
param_env,
ty,
trait_def_id,
DUMMY_SP,
)
})
let infcx = tcx.infer_ctxt().build();
traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, ty, trait_def_id, DUMMY_SP)
}
pub(crate) fn provide(providers: &mut ty::query::Providers) {

View file

@ -134,8 +134,7 @@ fn resolve_associated_item<'tcx>(
.unwrap_or_else(|| {
bug!("{:?} not found in {:?}", trait_item_id, impl_data.impl_def_id);
});
let substs = tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
let param_env = param_env.with_reveal_all_normalized(tcx);
let substs = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
let substs = translate_substs(
@ -145,8 +144,7 @@ fn resolve_associated_item<'tcx>(
substs,
leaf_def.defining_node,
);
infcx.tcx.erase_regions(substs)
});
let substs = infcx.tcx.erase_regions(substs);
// Since this is a trait item, we need to see if the item is either a trait default item
// or a specialization because we can't resolve those unless we can `Reveal::All`.

View file

@ -27,35 +27,39 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
}
// NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
let trait_impls = cx.tcx.trait_impls_of(trait_def_id);
for &impl_def_id in trait_impls.blanket_impls() {
'blanket_impls: for &impl_def_id in trait_impls.blanket_impls() {
trace!(
"get_blanket_impls: Considering impl for trait '{:?}' {:?}",
trait_def_id,
impl_def_id
);
let trait_ref = cx.tcx.bound_impl_trait_ref(impl_def_id).unwrap();
let is_param = matches!(trait_ref.0.self_ty().kind(), ty::Param(_));
let may_apply = is_param && cx.tcx.infer_ctxt().enter(|infcx| {
if !matches!(trait_ref.0.self_ty().kind(), ty::Param(_)) {
continue;
}
let infcx = cx.tcx.infer_ctxt().build();
let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
let ty = ty.subst(infcx.tcx, substs);
let impl_ty = ty.subst(infcx.tcx, substs);
let param_env = EarlyBinder(param_env).subst(infcx.tcx, substs);
let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
let impl_trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
// Require the type the impl is implemented on to match
// our type, and ignore the impl if there was a mismatch.
let cause = traits::ObligationCause::dummy();
let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty);
if let Ok(InferOk { value: (), obligations }) = eq_result {
let Ok(eq_result) = infcx.at(&cause, param_env).eq(impl_trait_ref.self_ty(), impl_ty) else {
continue
};
let InferOk { value: (), obligations } = eq_result;
// FIXME(eddyb) ignoring `obligations` might cause false positives.
drop(obligations);
trace!(
"invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
"invoking predicate_may_hold: param_env={:?}, impl_trait_ref={:?}, impl_ty={:?}",
param_env,
trait_ref,
ty
impl_trait_ref,
impl_ty
);
let predicates = cx
.tcx
@ -64,7 +68,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.predicates
.into_iter()
.chain(Some(
ty::Binder::dummy(trait_ref)
ty::Binder::dummy(impl_trait_ref)
.to_poly_trait_predicate()
.map_bound(ty::PredicateKind::Trait)
.to_predicate(infcx.tcx),
@ -80,23 +84,13 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
Ok(eval_result) if eval_result.may_apply() => {}
Err(traits::OverflowError::Canonical) => {}
Err(traits::OverflowError::ErrorReporting) => {}
_ => {
return false;
_ => continue 'blanket_impls,
}
}
}
true
} else {
false
}
});
debug!(
"get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}",
may_apply, trait_ref, ty
"get_blanket_impls: found applicable impl for trait_ref={:?}, ty={:?}",
trait_ref, ty
);
if !may_apply {
continue;
}
cx.generated_synthetics.insert((ty.0, trait_def_id));

View file

@ -1564,12 +1564,11 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
// Try to normalize `<X as Y>::T` to a type
let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
let normalized = cx.tcx.infer_ctxt().enter(|infcx| {
infcx
let infcx = cx.tcx.infer_ctxt().build();
let normalized = infcx
.at(&ObligationCause::dummy(), cx.param_env)
.normalize(lifted)
.map(|resolved| infcx.resolve_vars_if_possible(resolved.value))
});
.map(|resolved| infcx.resolve_vars_if_possible(resolved.value));
match normalized {
Ok(normalized_value) => {
debug!("normalized {:?} to {:?}", ty, normalized_value);

View file

@ -831,11 +831,10 @@ fn walk_parents<'tcx>(
// Trait methods taking `self`
arg_ty
} && impl_ty.is_ref()
&& cx.tcx.infer_ctxt().enter(|infcx|
infcx
&& let infcx = cx.tcx.infer_ctxt().build()
&& infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
.must_apply_modulo_regions()
)
{
return Some(Position::MethodReceiverRefImpl)
}
@ -1119,9 +1118,8 @@ fn needless_borrow_impl_arg_position<'tcx>(
let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
cx.tcx
.infer_ctxt()
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
let infcx = cx.tcx.infer_ctxt().build();
infcx.predicate_must_hold_modulo_regions(&obligation)
})
};

View file

@ -106,9 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
};
let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
});
for node in v.set {
span_lint_hir(

View file

@ -77,10 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
if is_future {
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
let span = decl.output.span();
let send_errors = cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
let cause = traits::ObligationCause::misc(span, hir_id);
traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait)
});
let send_errors = traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait);
if !send_errors.is_empty() {
span_lint_and_then(
cx,
@ -88,9 +87,10 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
span,
"future cannot be sent between threads safely",
|db| {
cx.tcx.infer_ctxt().enter(|infcx| {
for FulfillmentError { obligation, .. } in send_errors {
infcx.err_ctxt().maybe_note_obligation_cause_for_async_await(db, &obligation);
infcx
.err_ctxt()
.maybe_note_obligation_cause_for_async_await(db, &obligation);
if let Trait(trait_pred) = obligation.predicate.kind().skip_binder() {
db.note(&format!(
"`{}` doesn't implement `{}`",
@ -99,7 +99,6 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
));
}
}
});
},
);
}

View file

@ -65,7 +65,7 @@ fn check_for_mutation<'tcx>(
span_low: None,
span_high: None,
};
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(
&mut delegate,
&infcx,
@ -74,7 +74,6 @@ fn check_for_mutation<'tcx>(
cx.typeck_results(),
)
.walk_expr(body);
});
delegate.mutation_span()
}

View file

@ -420,9 +420,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
if trait_predicates.any(|predicate| {
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx
.infer_ctxt()
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
}) {
return false;
}

View file

@ -138,10 +138,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
..
} = {
let mut ctx = MovedVariablesCtxt::default();
cx.tcx.infer_ctxt().enter(|infcx| {
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
.consume_body(body);
});
let infcx = cx.tcx.infer_ctxt().build();
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
ctx
};

View file

@ -123,7 +123,7 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
}
let mut s = S(hir::HirIdSet::default());
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
let mut v = ExprUseVisitor::new(
&mut s,
&infcx,
@ -132,7 +132,6 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
cx.typeck_results(),
);
v.consume_expr(e);
});
s.0
}
@ -156,7 +155,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
}
let mut s = S(hir::HirIdSet::default());
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
let mut v = ExprUseVisitor::new(
&mut s,
&infcx,
@ -165,6 +164,5 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
cx.typeck_results(),
);
v.consume_expr(e);
});
s.0
}

View file

@ -821,10 +821,9 @@ pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'
};
let fn_def_id = cx.tcx.hir().local_def_id(closure.hir_id);
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(&mut visitor, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
.consume_body(closure_body);
});
if !visitor.suggestion_start.is_empty() {
return Some(DerefClosure {

View file

@ -172,11 +172,10 @@ pub fn implements_trait_with_env<'tcx>(
return false;
}
let ty_params = tcx.mk_substs(ty_params.iter());
tcx.infer_ctxt().enter(|infcx| {
let infcx = tcx.infer_ctxt().build();
infcx
.type_implements_trait(trait_id, ty, ty_params, param_env)
.must_apply_modulo_regions()
})
}
/// Checks whether this type implements `Drop`.
@ -242,9 +241,9 @@ fn is_normalizable_helper<'tcx>(
}
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow
cache.insert(ty, false);
let result = cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
let cause = rustc_middle::traits::ObligationCause::dummy();
if infcx.at(&cause, param_env).normalize(ty).is_ok() {
let result = if infcx.at(&cause, param_env).normalize(ty).is_ok() {
match ty.kind() {
ty::Adt(def, substs) => def.variants().iter().all(|variant| {
variant
@ -261,8 +260,7 @@ fn is_normalizable_helper<'tcx>(
}
} else {
false
}
});
};
cache.insert(ty, result);
result
}

View file

@ -18,7 +18,7 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) ->
used_mutably: HirIdSet::default(),
skip: false,
};
cx.tcx.infer_ctxt().enter(|infcx| {
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(
&mut delegate,
&infcx,
@ -27,7 +27,6 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) ->
cx.typeck_results(),
)
.walk_expr(expr);
});
if delegate.skip {
return None;