Change InferCtxtBuilder from enter to build
This commit is contained in:
parent
91269fa5b8
commit
283abbf0e7
53 changed files with 1966 additions and 2182 deletions
|
@ -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()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(®ion_data);
|
let vid_to_region = self.map_vid_to_region(®ion_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))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!();
|
||||||
|
|
|
@ -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>>(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
})
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue