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>, def: ty::WithOptConstParam<LocalDefId>,
) -> BodyWithBorrowckFacts<'tcx> { ) -> BodyWithBorrowckFacts<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def); 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 input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.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).1.unwrap()
})
} }

View file

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

View file

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

View file

@ -1025,7 +1025,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
let ty = moved_place.ty(self.body, self.infcx.tcx).ty; let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) { 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( type_known_to_meet_bound_modulo_regions(
&infcx, &infcx,
self.param_env, self.param_env,
@ -1036,7 +1037,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
def_id, def_id,
DUMMY_SP, DUMMY_SP,
) )
}), }
_ => false, _ => false,
}; };
if suggest { 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())); 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 hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let opt_closure_req = tcx let infcx =
.infer_ctxt() tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
.enter(|infcx| {
let input_body: &Body<'_> = &input_body.borrow(); let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.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"); debug!("mir_borrowck done");
tcx.arena.alloc(opt_closure_req) 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` // Only check this for TAIT. RPIT already supports `src/test/ui/impl-trait/nested-return-type2.rs`
// on stable and we'd break that. // 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`. // 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. // 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 param_env = self.tcx.param_env(def_id);
let body_id = self.tcx.local_def_id_to_hir_id(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: // HACK This bubble is required for this tests to pass:
// type-alias-impl-trait/issue-67844-nested-opaque.rs // type-alias-impl-trait/issue-67844-nested-opaque.rs
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter( let infcx =
move |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. // 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 // 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. // hidden type is well formed even without those bounds.
let predicate = let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
.to_predicate(infcx.tcx); .to_predicate(infcx.tcx);
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(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); infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
self.tcx.ty_error() self.tcx.ty_error()
} }
},
)
} else {
definition_ty
}
} }
} }

View file

@ -737,14 +737,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let obligation = let obligation =
Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred); 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); let mut selcx = SelectionContext::new(&infcx);
selcx.select(&obligation) selcx.select(&obligation)
}); };
// do a well-formedness check on the trait method being called. This is because typeck only does a // 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. // "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 mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
let hir_id = tcx let hir_id = tcx
@ -777,7 +779,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if !errors.is_empty() { if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
} }
}); }
match implsrc { match implsrc {
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { 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 // improve diagnostics by showing what failed. Our requirements are stricter this time
// as we are going to error again anyways. // as we are going to error again anyways.
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
if let Err(e) = implsrc { if let Err(e) = implsrc {
infcx.err_ctxt().report_selection_error( infcx.err_ctxt().report_selection_error(
obligation.clone(), obligation.clone(),
@ -844,7 +846,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
false, false,
); );
} }
});
self.check_op(ops::FnCallNonConst { self.check_op(ops::FnCallNonConst {
caller, 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); let mut selcx = SelectionContext::new(&infcx);
selcx.select(&obligation) let implsrc = selcx.select(&obligation);
});
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc { if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
let span = tcx.def_span(data.impl_def_id); 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 mut selcx = SelectionContext::new(&infcx);
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
// If we couldn't select a const destruct candidate, then it's bad // If we couldn't select a const destruct candidate, then it's bad
@ -177,8 +177,7 @@ impl Qualif for NeedsNonConstDrop {
if !matches!( if !matches!(
impl_src, impl_src,
ImplSource::ConstDestruct(_) ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
| ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
) { ) {
// If our const destruct candidate is not ConstDestruct or implied by the param env, // If our const destruct candidate is not ConstDestruct or implied by the param env,
// then it's bad // then it's bad
@ -191,7 +190,6 @@ impl Qualif for NeedsNonConstDrop {
// If we had any errors, then it's bad // 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()).is_empty()
})
} }
fn in_adt_inherently<'tcx>( 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> { struct TypeChecker<'a, 'tcx> {

View file

@ -83,9 +83,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Res::Def(DefKind::TyParam, src_def_id) => { Res::Def(DefKind::TyParam, src_def_id) => {
if let Some(param_local_id) = param.def_id.as_local() { if let Some(param_local_id) = param.def_id.as_local() {
let param_name = tcx.hir().ty_param_name(param_local_id); let param_name = tcx.hir().ty_param_name(param_local_id);
let param_type = tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id)) let param_type =
}); infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id));
if param_type.is_suggestable(tcx, false) { if param_type.is_suggestable(tcx, false) {
err.span_suggestion( err.span_suggestion(
tcx.def_span(src_def_id), 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); let param_env = tcx.param_env(defining_use_anchor);
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor)).enter( let infcx = tcx
move |infcx| { .infer_ctxt()
.with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
.build();
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs); 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. // 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 // 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. // hidden type is well formed even without those bounds.
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())) let predicate =
.to_predicate(tcx); ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate)); ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
// Check that all obligations are satisfied by the implementation's // Check that all obligations are satisfied by the implementation's
@ -776,8 +778,6 @@ fn check_opaque_meets_bounds<'tcx>(
} }
// Clean up after ourselves // Clean up after ourselves
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
},
);
} }
fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) { 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); 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); let ocx = ObligationCtxt::new(infcx);
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); 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 => if trait_m.fn_has_self_parameter =>
{ {
let ty = trait_sig.inputs()[0]; 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::ByValue => "self".to_owned(),
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(), ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => { ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
"&mut self".to_owned()
}
_ => format!("self: {ty}"), _ => format!("self: {ty}"),
}; };
@ -432,7 +429,6 @@ fn compare_predicate_entailment<'tcx>(
); );
Ok(()) Ok(())
})
} }
pub fn collect_trait_impl_trait_tys<'tcx>( 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 = let trait_to_placeholder_substs =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_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 ocx = ObligationCtxt::new(infcx);
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id); let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
@ -481,8 +477,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
.output(), .output(),
); );
let mut collector = let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
let unnormalized_trait_return_ty = tcx let unnormalized_trait_return_ty = tcx
.liberate_late_bound_regions( .liberate_late_bound_regions(
impl_m.def_id, impl_m.def_id,
@ -555,11 +550,8 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
// contains `def_id`'s early-bound regions. // contains `def_id`'s early-bound regions.
let id_substs = InternalSubsts::identity_for_item(tcx, def_id); let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
debug!(?id_substs, ?substs); debug!(?id_substs, ?substs);
let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> = substs let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> =
.iter() substs.iter().enumerate().map(|(index, arg)| (arg, id_substs[index])).collect();
.enumerate()
.map(|(index, arg)| (arg, id_substs[index]))
.collect();
debug!(?map); debug!(?map);
let ty = tcx.fold_regions(ty, |region, _| { 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)) Ok(&*tcx.arena.alloc(collected_tys))
})
} }
struct ImplTraitInTraitCollector<'a, 'tcx> { 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 self_arg_ty = tcx.fn_sig(method.def_id).input(0);
let param_env = ty::ParamEnv::reveal_all(); 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 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(); 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) { 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(), ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
_ => format!("self: {self_arg_ty}"), _ => format!("self: {self_arg_ty}"),
} }
})
}; };
match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) { 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()); 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 param_env = tcx.param_env(impl_const_item_def.to_def_id());
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -1406,10 +1396,8 @@ pub(crate) fn raw_compare_const_impl<'tcx>(
// FIXME return `ErrorReported` if region obligations error? // FIXME return `ErrorReported` if region obligations error?
let outlives_environment = OutlivesEnvironment::new(param_env); let outlives_environment = OutlivesEnvironment::new(param_env);
infcx infcx.check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment);
.check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment);
Ok(()) Ok(())
})
} }
pub(crate) fn compare_ty_impl<'tcx>( pub(crate) fn compare_ty_impl<'tcx>(
@ -1490,7 +1478,7 @@ fn compare_type_predicate_entailment<'tcx>(
hir::Constness::NotConst, hir::Constness::NotConst,
); );
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); 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); let ocx = ObligationCtxt::new(&infcx);
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds()); 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); let mut selcx = traits::SelectionContext::new(&infcx);
assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len()); assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len());
for (span, predicate) in for (span, predicate) in std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
{ {
let cause = ObligationCause::misc(span, impl_ty_hir_id); let cause = ObligationCause::misc(span, impl_ty_hir_id);
let traits::Normalized { value: predicate, obligations } = let traits::Normalized { value: predicate, obligations } =
@ -1535,7 +1522,6 @@ fn compare_type_predicate_entailment<'tcx>(
); );
Ok(()) Ok(())
})
} }
/// Validate that `ProjectionCandidate`s created for this associated type will /// 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 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); 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 ocx = ObligationCtxt::new(&infcx);
let assumed_wf_types = let assumed_wf_types =
@ -1783,7 +1769,6 @@ pub fn check_type_bounds<'tcx>(
} }
Ok(()) Ok(())
})
} }
fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { 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.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
let ty = self.normalize_associated_types_in(expr.span, ty); let ty = self.normalize_associated_types_in(expr.span, ty);
let ty = match self.tcx.asyncness(fn_id.owner) { let ty = match self.tcx.asyncness(fn_id.owner) {
hir::IsAsync::Async => self hir::IsAsync::Async => {
.tcx let infcx = self.tcx.infer_ctxt().build();
.infer_ctxt() infcx
.enter(|infcx| { .get_impl_future_output_ty(ty)
infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| { .unwrap_or_else(|| {
span_bug!( span_bug!(
fn_decl.output.span(), fn_decl.output.span(),
"failed to get output type of async function" "failed to get output type of async function"
) )
}) })
}) .skip_binder()
.skip_binder(), }
hir::IsAsync::NotAsync => ty, hir::IsAsync::NotAsync => ty,
}; };
if self.can_coerce(found, ty) { if self.can_coerce(found, ty) {

View file

@ -129,7 +129,7 @@ impl<'tcx> InheritedBuilder<'tcx> {
F: FnOnce(&Inherited<'tcx>) -> R, F: FnOnce(&Inherited<'tcx>) -> R,
{ {
let def_id = self.def_id; 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> { ) -> MethodAutoderefStepsResult<'tcx> {
debug!("method_autoderef_steps({:?})", goal); 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 ParamEnvAnd { param_env, value: self_ty } = goal;
let mut autoderef = let mut autoderef =
@ -484,10 +484,8 @@ fn method_autoderef_steps<'tcx>(
.by_ref() .by_ref()
.map(|(ty, d)| { .map(|(ty, d)| {
let step = CandidateStep { let step = CandidateStep {
self_ty: infcx.make_query_response_ignoring_pending_obligations( self_ty: infcx
inference_vars.clone(), .make_query_response_ignoring_pending_obligations(inference_vars.clone(), ty),
ty,
),
autoderefs: d, autoderefs: d,
from_unsafe_deref: reached_raw_pointer, from_unsafe_deref: reached_raw_pointer,
unsize: false, unsize: false,
@ -504,8 +502,7 @@ fn method_autoderef_steps<'tcx>(
let opt_bad_ty = match final_ty.kind() { let opt_bad_ty = match final_ty.kind() {
ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy { ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
reached_raw_pointer, reached_raw_pointer,
ty: infcx ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
}), }),
ty::Array(elem_ty, _) => { ty::Array(elem_ty, _) => {
let dereferences = steps.len() - 1; 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)), opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),
reached_recursion_limit: autoderef.reached_recursion_limit(), reached_recursion_limit: autoderef.reached_recursion_limit(),
} }
})
} }
impl<'a, 'tcx> ProbeContext<'a, 'tcx> { 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 param_env = tcx.param_env(body_def_id);
let body_id = tcx.hir().local_def_id_to_hir_id(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 ocx = ObligationCtxt::new(infcx);
let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id); 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); OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment); infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
})
} }
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) { 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 // Unfortunately, we have to use a new `InferCtxt` each call, because
// region constraints get added and solved there and we need to test each // region constraints get added and solved there and we need to test each
// call individually. // call individually.
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let outlives_environment = OutlivesEnvironment::with_bounds( let outlives_environment = OutlivesEnvironment::with_bounds(
param_env, param_env,
Some(&infcx), 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 // 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... // an error, it must be because of the implied or explicit bounds...
errors.is_empty() errors.is_empty()
})
} }
/// TypeVisitor that looks for uses of GATs like /// 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 // 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 // it is not immediately clear why Copy is not implemented for a field, since
// all we point at is the field itself. // 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( for error in traits::fully_solve_bound(
&infcx, &infcx,
traits::ObligationCause::dummy_with_span(field_ty_span), 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 { for ((ty, error_predicate), spans) in errors {
let span: MultiSpan = spans.into(); 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); 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); let cause = ObligationCause::misc(span, impl_hir_id);
use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::sty::TyKind::*;
@ -283,9 +282,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
) )
.emit(); .emit();
} else if coerced_fields.len() > 1 { } else if coerced_fields.len() > 1 {
create_err( create_err("implementing the `DispatchFromDyn` trait requires multiple coercions")
"implementing the `DispatchFromDyn` trait requires multiple coercions",
)
.note( .note(
"the trait `DispatchFromDyn` may only be implemented \ "the trait `DispatchFromDyn` may only be implemented \
for a coercion between structures with a single field \ 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(); .emit();
} }
} }
})
} }
pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedInfo { 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); 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 impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_did);
let cause = ObligationCause::misc(span, impl_hir_id); let cause = ObligationCause::misc(span, impl_hir_id);
let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>, 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)) check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty))
} }
(&ty::RawPtr(mt_a), &ty::RawPtr(mt_b)) => { (&ty::RawPtr(mt_a), &ty::RawPtr(mt_b)) => check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty)),
check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty))
}
(&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b))
if def_a.is_struct() && def_b.is_struct() => 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; return err_info;
} else if diff_fields.len() > 1 { } else if diff_fields.len() > 1 {
let item = tcx.hir().expect_item(impl_did); let item = tcx.hir().expect_item(impl_did);
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) = let span =
item.kind if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) = item.kind {
{
t.path.span t.path.span
} else { } else {
tcx.def_span(impl_did) 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.len(),
diff_fields diff_fields
.iter() .iter()
.map(|&(i, a, b)| { .map(|&(i, a, b)| { format!("`{}` (`{}` to `{}`)", fields[i].name, a, b) })
format!("`{}` (`{}` to `{}`)", fields[i].name, a, b)
})
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .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>`. // Register an obligation for `A: Trait<B>`.
let cause = traits::ObligationCause::misc(span, impl_hir_id); let cause = traits::ObligationCause::misc(span, impl_hir_id);
let predicate = predicate_for_trait_def( let predicate =
tcx, predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]);
param_env,
cause,
trait_def_id,
0,
source,
&[target.into()],
);
let errors = traits::fully_solve_obligation(&infcx, predicate); let errors = traits::fully_solve_obligation(&infcx, predicate);
if !errors.is_empty() { if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); 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); infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
CoerceUnsizedInfo { custom_kind: kind } CoerceUnsizedInfo { custom_kind: kind }
})
} }

View file

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

View file

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

View file

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

View file

@ -602,30 +602,27 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// `V` and a substitution `S`. This substitution `S` maps from /// `V` and a substitution `S`. This substitution `S` maps from
/// the bound values in `C` to their instantiated values in `V` /// the bound values in `C` to their instantiated values in `V`
/// (in other words, `S(C) = V`). /// (in other words, `S(C) = V`).
pub fn enter_with_canonical<T, R>( pub fn build_with_canonical<T>(
&mut self, &mut self,
span: Span, span: Span,
canonical: &Canonical<'tcx, T>, canonical: &Canonical<'tcx, T>,
f: impl FnOnce(InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) -> R, ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
) -> R
where where
T: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>,
{ {
self.enter(|infcx| { let infcx = self.build();
let (value, subst) = let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); (infcx, value, subst)
f(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 { let InferCtxtBuilder {
tcx, tcx,
defining_use_anchor, defining_use_anchor,
considering_regions, considering_regions,
ref normalize_fn_sig_for_diagnostic, ref normalize_fn_sig_for_diagnostic,
} = *self; } = *self;
f(InferCtxt { InferCtxt {
tcx, tcx,
defining_use_anchor, defining_use_anchor,
considering_regions, considering_regions,
@ -643,7 +640,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
.as_ref() .as_ref()
.map(|f| f.clone()), .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()), 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 infcx = cx.tcx.infer_ctxt().build();
let display = is_str let suggest_display = is_str
|| cx.tcx.get_diagnostic_item(sym::Display).map(|t| { || cx.tcx.get_diagnostic_item(sym::Display).map(|t| {
infcx infcx
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
.may_apply() .may_apply()
}) == Some(true); }) == Some(true);
let debug = !display let suggest_debug = !suggest_display
&& cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| {
infcx infcx
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
.may_apply() .may_apply()
}) == Some(true); }) == Some(true);
(display, debug)
});
let suggest_panic_any = !is_str && panic == sym::std_panic_macro; 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>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; }; let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; };
let def_id = item.def_id.def_id.to_def_id(); 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, // For every projection predicate in the opaque type's explicit bounds,
// check that the type that we're assigning actually satisfies the bounds // check that the type that we're assigning actually satisfies the bounds
// of the associated type. // of the associated type.
for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) { for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) {
// Liberate bound regions in the predicate since we // Liberate bound regions in the predicate since we
// don't actually care about lifetimes in this check. // don't actually care about lifetimes in this check.
let predicate = cx.tcx.liberate_late_bound_regions( let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind());
def_id,
pred.kind(),
);
let ty::PredicateKind::Projection(proj) = predicate else { let ty::PredicateKind::Projection(proj) = predicate else {
continue; continue;
}; };
@ -81,9 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
let Some(proj_term) = proj.term.ty() else { continue }; let Some(proj_term) = proj.term.ty() else { continue };
let proj_ty = let proj_ty =
cx cx.tcx.mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs);
.tcx
.mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs);
// For every instance of the projection type in the bounds, // For every instance of the projection type in the bounds,
// replace them with the term we're assigning to the associated // replace them with the term we're assigning to the associated
// type in our opaque type. // 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`, // 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` // e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
// with `impl Send: OtherTrait`. // with `impl Send: OtherTrait`.
for assoc_pred_and_span in cx for assoc_pred_and_span in
.tcx cx.tcx.bound_explicit_item_bounds(proj.projection_ty.item_def_id).transpose_iter()
.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_span = assoc_pred_and_span.0.1;
let assoc_pred = assoc_pred_and_span 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, // If it's a trait bound and an opaque that doesn't satisfy it,
// then we can emit a suggestion to add the bound. // then we can emit a suggestion to add the bound.
let add_bound = let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
match (proj_term.kind(), assoc_pred.kind().skip_binder()) { (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => {
(ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => Some(AddBound { Some(AddBound {
suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(), suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
trait_ref: trait_pred.print_modifiers_and_trait_path(), trait_ref: trait_pred.print_modifiers_and_trait_path(),
}), })
}
_ => None, _ => None,
}; };
cx.emit_spanned_lint( cx.emit_spanned_lint(
OPAQUE_HIDDEN_INFERRED_BOUND, OPAQUE_HIDDEN_INFERRED_BOUND,
pred_span, pred_span,
OpaqueHiddenInferredBoundLint { 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, proj_ty: proj_term,
assoc_pred_span, assoc_pred_span,
add_bound, 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()) (None, fn_sig.output())
}; };
let mut body = tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let mut builder = Builder::new( let mut builder = Builder::new(
thir, thir,
infcx, infcx,
@ -505,11 +505,8 @@ fn construct_fn<'tcx>(
let arg_scope_s = (arg_scope, source_info); let arg_scope_s = (arg_scope, source_info);
// Attribute epilogue to function's closing brace // Attribute epilogue to function's closing brace
let fn_end = span_with_body.shrink_to_hi(); let fn_end = span_with_body.shrink_to_hi();
let return_block = unpack!(builder.in_breakable_scope( let return_block =
None, unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
Place::return_place(),
fn_end,
|builder| {
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
builder.args_and_body( builder.args_and_body(
START_BLOCK, START_BLOCK,
@ -519,16 +516,14 @@ fn construct_fn<'tcx>(
&thir[expr], &thir[expr],
) )
})) }))
} }));
));
let source_info = builder.source_info(fn_end); let source_info = builder.source_info(fn_end);
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return); builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
builder.build_drop_trees(); builder.build_drop_trees();
return_block.unit() return_block.unit()
})); }));
builder.finish() let mut body = builder.finish();
});
body.spread_arg = if abi == Abi::RustCall { body.spread_arg = if abi == Abi::RustCall {
// RustCall pseudo-ABI untuples the last argument. // 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 typeck_results = tcx.typeck_opt_const_arg(def);
let const_ty = typeck_results.node_type(hir_id); 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( let mut builder = Builder::new(
thir, thir,
infcx, infcx,
@ -607,7 +602,6 @@ fn construct_const<'a, 'tcx>(
builder.build_drop_trees(); builder.build_drop_trees();
builder.finish() builder.finish()
})
} }
/// Construct MIR for an item that has had errors in type checking. /// 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, span: Span,
mir_structural_match_violation: bool, mir_structural_match_violation: bool,
) -> Box<Pat<'tcx>> { ) -> 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); let mut convert = ConstToPat::new(self, id, span, infcx);
convert.to_pat(cv, mir_structural_match_violation) 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>, R: Debug + TypeFoldable<'tcx>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
{ {
self.enter_with_canonical( let (ref infcx, key, canonical_inference_vars) =
DUMMY_SP, self.build_with_canonical(DUMMY_SP, canonical_key);
canonical_key,
|ref infcx, key, canonical_inference_vars| {
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
let value = operation(infcx, &mut *fulfill_cx, key)?; let value = operation(infcx, &mut *fulfill_cx, key)?;
infcx.make_canonicalized_query_response( infcx.make_canonicalized_query_response(canonical_inference_vars, value, &mut *fulfill_cx)
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::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitable; 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}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -90,51 +90,26 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let trait_pred = ty::Binder::dummy(trait_ref); 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 mut selcx = SelectionContext::new(&infcx);
let result = selcx.select(&Obligation::new( for f in [
ObligationCause::dummy(), PolyTraitRef::to_poly_trait_predicate,
orig_env, PolyTraitRef::to_poly_trait_predicate_negative_polarity,
trait_pred.to_poly_trait_predicate(), ] {
)); let result =
selcx.select(&Obligation::new(ObligationCause::dummy(), orig_env, f(&trait_pred)));
match result { if let Ok(Some(ImplSource::UserDefined(_))) = result {
Ok(Some(ImplSource::UserDefined(_))) => {
debug!( debug!(
"find_auto_trait_generics({:?}): \ "find_auto_trait_generics({:?}): \
manual impl found, bailing out", manual impl found, bailing out",
trait_ref 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 an explicit impl exists, it always takes priority over an auto impl
if bail_out {
return AutoTraitResult::ExplicitImpl; return AutoTraitResult::ExplicitImpl;
} }
}
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let mut fresh_preds = FxHashSet::default(); let mut fresh_preds = FxHashSet::default();
// Due to the way projections are handled by SelectionContext, we need to run // 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 let (full_env, full_user_env) = self
.evaluate_predicates( .evaluate_predicates(&infcx, trait_did, ty, new_env, user_env, &mut fresh_preds, true)
&infcx,
trait_did,
ty,
new_env,
user_env,
&mut fresh_preds,
true,
)
.unwrap_or_else(|| { .unwrap_or_else(|| {
panic!("Failed to fully process: {:?} {:?} {:?}", ty, trait_did, orig_env) 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); infcx.process_registered_region_obligations(&Default::default(), full_env);
let region_data = infcx let region_data =
.inner infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();
.borrow_mut()
.unwrap_region_constraints()
.region_constraint_data()
.clone();
let vid_to_region = self.map_vid_to_region(&region_data); let vid_to_region = self.map_vid_to_region(&region_data);
let info = AutoTraitInfo { full_user_env, region_data, vid_to_region }; let info = AutoTraitInfo { full_user_env, region_data, vid_to_region };
AutoTraitResult::PositiveImpl(auto_trait_callback(info)) 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 // Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl. // shallow result we are looking for -- that is, what specific impl.
let mut infcx_builder = let infcx = tcx
tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble); .infer_ctxt()
infcx_builder.enter(|infcx| { .ignoring_regions()
.with_opaque_type_inference(DefiningAnchor::Bubble)
.build();
//~^ HACK `Bubble` is required for //~^ HACK `Bubble` is required for
// this test to pass: type-alias-impl-trait/assoc-projection-ice.rs // this test to pass: type-alias-impl-trait/assoc-projection-ice.rs
let mut selcx = SelectionContext::new(&infcx); 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(); let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
Ok(&*tcx.arena.alloc(impl_source)) Ok(&*tcx.arena.alloc(impl_source))
})
} }

View file

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

View file

@ -1930,16 +1930,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} }
let normalize = |candidate| { let normalize = |candidate| {
self.tcx.infer_ctxt().enter(|ref infcx| { let infcx = self.tcx.infer_ctxt().build();
let normalized = infcx infcx
.at(&ObligationCause::dummy(), ty::ParamEnv::empty()) .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
.normalize(candidate) .normalize(candidate)
.ok(); .map_or(candidate, |normalized| normalized.value)
match normalized {
Some(normalized) => normalized.value,
None => candidate,
}
})
}; };
// Sort impl candidates so that ordering is consistent for UI tests. // 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>, parent_cause: ObligationCause<'tcx>,
) -> Result<(), CopyImplementationError<'tcx>> { ) -> Result<(), CopyImplementationError<'tcx>> {
// FIXME: (@jroesch) float this code up // FIXME: (@jroesch) float this code up
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let (adt, substs) = match self_type.kind() { let (adt, substs) = match self_type.kind() {
// These types used to have a builtin impl. // These types used to have a builtin impl.
// Now libcore provides that impl. // Now libcore provides that impl.
@ -83,5 +83,4 @@ pub fn can_type_implement_copy<'tcx>(
} }
Ok(()) Ok(())
})
} }

View file

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

View file

@ -734,10 +734,9 @@ fn receiver_is_dispatchable<'tcx>(
Obligation::new(ObligationCause::dummy(), param_env, predicate) 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 // the receiver is dispatchable iff the obligation holds
infcx.predicate_must_hold_modulo_regions(&obligation) infcx.predicate_must_hold_modulo_regions(&obligation)
})
} }
fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( 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(); let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
// Create an infcx, taking the predicates of impl1 as assumptions: // Create an infcx, taking the predicates of impl1 as assumptions:
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let impl1_trait_ref = match traits::fully_normalize( let impl1_trait_ref =
&infcx, match traits::fully_normalize(&infcx, ObligationCause::dummy(), penv, impl1_trait_ref) {
ObligationCause::dummy(),
penv,
impl1_trait_ref,
) {
Ok(impl1_trait_ref) => impl1_trait_ref, Ok(impl1_trait_ref) => impl1_trait_ref,
Err(_errors) => { Err(_errors) => {
tcx.sess.delay_span_bug( 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. // Attempt to prove that impl2 applies, given all of the above.
fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok() fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok()
})
} }
/// Attempt to fulfill all obligations of `target_impl` after unification with /// 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) { pub fn provide(providers: &mut Providers) {
providers.has_structural_eq_impls = |tcx, ty| { providers.has_structural_eq_impls = |tcx, ty| {
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy();
type_marked_structural(&infcx, ty, cause) 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> { ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> {
debug!("dropck_outlives(goal={:#?})", canonical_goal); debug!("dropck_outlives(goal={:#?})", canonical_goal);
tcx.infer_ctxt().enter_with_canonical( let (ref infcx, goal, canonical_inference_vars) =
DUMMY_SP, tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal);
&canonical_goal,
|ref infcx, goal, canonical_inference_vars| {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let ParamEnvAnd { param_env, value: for_ty } = goal; let ParamEnvAnd { param_env, value: for_ty } = goal;
@ -142,13 +140,7 @@ fn dropck_outlives<'tcx>(
debug!("dropck_outlives: result = {:#?}", result); debug!("dropck_outlives: result = {:#?}", result);
infcx.make_canonicalized_query_response( infcx.make_canonicalized_query_response(canonical_inference_vars, result, &mut *fulfill_cx)
canonical_inference_vars,
result,
&mut *fulfill_cx,
)
},
)
} }
/// Returns a set of constraints that needs to be satisfied in /// 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); debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal);
// HACK This bubble is required for this tests to pass: // HACK This bubble is required for this tests to pass:
// impl-trait/issue99642.rs // impl-trait/issue99642.rs
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter_with_canonical( let (ref infcx, goal, _canonical_inference_vars) = tcx
DUMMY_SP, .infer_ctxt()
&canonical_goal, .with_opaque_type_inference(DefiningAnchor::Bubble)
|ref infcx, goal, _canonical_inference_vars| { .build_with_canonical(DUMMY_SP, &canonical_goal);
debug!("evaluate_obligation: goal={:#?}", goal); debug!("evaluate_obligation: goal={:#?}", goal);
let ParamEnvAnd { param_env, value: predicate } = 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); let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
selcx.evaluate_root_obligation(&obligation) 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>, goal: ParamEnvAnd<'tcx, T>,
) -> Result<T, NoSolution> { ) -> Result<T, NoSolution> {
let ParamEnvAnd { param_env, value } = goal; let ParamEnvAnd { param_env, value } = goal;
tcx.infer_ctxt().enter(|infcx| { let infcx = tcx.infer_ctxt().build();
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy();
match infcx.at(&cause, param_env).normalize(value) { match infcx.at(&cause, param_env).normalize(value) {
Ok(Normalized { value: normalized_value, obligations: normalized_obligations }) => { 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), Err(NoSolution) => Err(NoSolution),
} }
})
} }
fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool { fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {

View file

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

View file

@ -134,8 +134,7 @@ fn resolve_associated_item<'tcx>(
.unwrap_or_else(|| { .unwrap_or_else(|| {
bug!("{:?} not found in {:?}", trait_item_id, impl_data.impl_def_id); bug!("{:?} not found in {:?}", trait_item_id, impl_data.impl_def_id);
}); });
let infcx = tcx.infer_ctxt().build();
let substs = tcx.infer_ctxt().enter(|infcx| {
let param_env = param_env.with_reveal_all_normalized(tcx); 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 = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
let substs = translate_substs( let substs = translate_substs(
@ -145,8 +144,7 @@ fn resolve_associated_item<'tcx>(
substs, substs,
leaf_def.defining_node, 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 // 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`. // 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 // 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); 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!( trace!(
"get_blanket_impls: Considering impl for trait '{:?}' {:?}", "get_blanket_impls: Considering impl for trait '{:?}' {:?}",
trait_def_id, trait_def_id,
impl_def_id impl_def_id
); );
let trait_ref = cx.tcx.bound_impl_trait_ref(impl_def_id).unwrap(); 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(_)); if !matches!(trait_ref.0.self_ty().kind(), ty::Param(_)) {
let may_apply = is_param && cx.tcx.infer_ctxt().enter(|infcx| { continue;
}
let infcx = cx.tcx.infer_ctxt().build();
let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id); 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 param_env = EarlyBinder(param_env).subst(infcx.tcx, substs);
let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); 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 // Require the type the impl is implemented on to match
// our type, and ignore the impl if there was a mismatch. // our type, and ignore the impl if there was a mismatch.
let cause = traits::ObligationCause::dummy(); let cause = traits::ObligationCause::dummy();
let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty); let Ok(eq_result) = infcx.at(&cause, param_env).eq(impl_trait_ref.self_ty(), impl_ty) else {
if let Ok(InferOk { value: (), obligations }) = eq_result { continue
};
let InferOk { value: (), obligations } = eq_result;
// FIXME(eddyb) ignoring `obligations` might cause false positives. // FIXME(eddyb) ignoring `obligations` might cause false positives.
drop(obligations); drop(obligations);
trace!( trace!(
"invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}", "invoking predicate_may_hold: param_env={:?}, impl_trait_ref={:?}, impl_ty={:?}",
param_env, param_env,
trait_ref, impl_trait_ref,
ty impl_ty
); );
let predicates = cx let predicates = cx
.tcx .tcx
@ -64,7 +68,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.predicates .predicates
.into_iter() .into_iter()
.chain(Some( .chain(Some(
ty::Binder::dummy(trait_ref) ty::Binder::dummy(impl_trait_ref)
.to_poly_trait_predicate() .to_poly_trait_predicate()
.map_bound(ty::PredicateKind::Trait) .map_bound(ty::PredicateKind::Trait)
.to_predicate(infcx.tcx), .to_predicate(infcx.tcx),
@ -80,23 +84,13 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
Ok(eval_result) if eval_result.may_apply() => {} Ok(eval_result) if eval_result.may_apply() => {}
Err(traits::OverflowError::Canonical) => {} Err(traits::OverflowError::Canonical) => {}
Err(traits::OverflowError::ErrorReporting) => {} Err(traits::OverflowError::ErrorReporting) => {}
_ => { _ => continue 'blanket_impls,
return false;
} }
} }
}
true
} else {
false
}
});
debug!( debug!(
"get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}", "get_blanket_impls: found applicable impl for trait_ref={:?}, ty={:?}",
may_apply, trait_ref, ty trait_ref, ty
); );
if !may_apply {
continue;
}
cx.generated_synthetics.insert((ty.0, trait_def_id)); 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 // Try to normalize `<X as Y>::T` to a type
let lifted = ty.lift_to_tcx(cx.tcx).unwrap(); let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
let normalized = cx.tcx.infer_ctxt().enter(|infcx| { let infcx = cx.tcx.infer_ctxt().build();
infcx let normalized = infcx
.at(&ObligationCause::dummy(), cx.param_env) .at(&ObligationCause::dummy(), cx.param_env)
.normalize(lifted) .normalize(lifted)
.map(|resolved| infcx.resolve_vars_if_possible(resolved.value)) .map(|resolved| infcx.resolve_vars_if_possible(resolved.value));
});
match normalized { match normalized {
Ok(normalized_value) => { Ok(normalized_value) => {
debug!("normalized {:?} to {:?}", ty, normalized_value); debug!("normalized {:?} to {:?}", ty, normalized_value);

View file

@ -831,11 +831,10 @@ fn walk_parents<'tcx>(
// Trait methods taking `self` // Trait methods taking `self`
arg_ty arg_ty
} && impl_ty.is_ref() } && impl_ty.is_ref()
&& cx.tcx.infer_ctxt().enter(|infcx| && let infcx = cx.tcx.infer_ctxt().build()
infcx && infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env) .type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
)
{ {
return Some(Position::MethodReceiverRefImpl) 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 predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate); let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
cx.tcx let infcx = cx.tcx.infer_ctxt().build();
.infer_ctxt() infcx.predicate_must_hold_modulo_regions(&obligation)
.enter(|infcx| 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); 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); ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
});
for node in v.set { for node in v.set {
span_lint_hir( span_lint_hir(

View file

@ -77,10 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
if is_future { if is_future {
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap(); let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
let span = decl.output.span(); 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); 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() { if !send_errors.is_empty() {
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -88,9 +87,10 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
span, span,
"future cannot be sent between threads safely", "future cannot be sent between threads safely",
|db| { |db| {
cx.tcx.infer_ctxt().enter(|infcx| {
for FulfillmentError { obligation, .. } in send_errors { 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() { if let Trait(trait_pred) = obligation.predicate.kind().skip_binder() {
db.note(&format!( db.note(&format!(
"`{}` doesn't implement `{}`", "`{}` 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_low: None,
span_high: None, span_high: None,
}; };
cx.tcx.infer_ctxt().enter(|infcx| { let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new( ExprUseVisitor::new(
&mut delegate, &mut delegate,
&infcx, &infcx,
@ -74,7 +74,6 @@ fn check_for_mutation<'tcx>(
cx.typeck_results(), cx.typeck_results(),
) )
.walk_expr(body); .walk_expr(body);
});
delegate.mutation_span() 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| { if trait_predicates.any(|predicate| {
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst); let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate); let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx !cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
.infer_ctxt()
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
}) { }) {
return false; return false;
} }

View file

@ -138,10 +138,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
.. ..
} = { } = {
let mut ctx = MovedVariablesCtxt::default(); let mut ctx = MovedVariablesCtxt::default();
cx.tcx.infer_ctxt().enter(|infcx| { let infcx = cx.tcx.infer_ctxt().build();
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()) euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
.consume_body(body);
});
ctx 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()); 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( let mut v = ExprUseVisitor::new(
&mut s, &mut s,
&infcx, &infcx,
@ -132,7 +132,6 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
cx.typeck_results(), cx.typeck_results(),
); );
v.consume_expr(e); v.consume_expr(e);
});
s.0 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()); 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( let mut v = ExprUseVisitor::new(
&mut s, &mut s,
&infcx, &infcx,
@ -165,6 +164,5 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
cx.typeck_results(), cx.typeck_results(),
); );
v.consume_expr(e); v.consume_expr(e);
});
s.0 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); 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()) ExprUseVisitor::new(&mut visitor, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
.consume_body(closure_body); .consume_body(closure_body);
});
if !visitor.suggestion_start.is_empty() { if !visitor.suggestion_start.is_empty() {
return Some(DerefClosure { return Some(DerefClosure {

View file

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

View file

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