Auto merge of #88149 - Mark-Simulacrum:prep-never-type, r=jackh726
Refactor fallback code to prepare for never type This PR contains cherry-picks of some of `@nikomatsakis's` work from #79366, and shouldn't (AFAICT) represent any change in behavior. However, the refactoring is good regardless of the never type work being landed, and will reduce the size of those eventual PR(s) (and rebase pain). I am not personally an expert on this code, and the commits are essentially 100% `@nikomatsakis's,` but they do seem reasonable to me by my understanding. Happy to edit with review, of course. Commits are best reviewed in sequence rather than all together. r? `@jackh726` perhaps?
This commit is contained in:
commit
797095a686
32 changed files with 470 additions and 210 deletions
|
@ -1119,6 +1119,7 @@ crate fn required_region_bounds(
|
|||
ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::Trait(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
|
|
|
@ -565,6 +565,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Coerce(predicate) => {
|
||||
// Errors for Coerce predicates show up as
|
||||
// `FulfillmentErrorCode::CodeSubtypeError`,
|
||||
// not selection error.
|
||||
span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)
|
||||
}
|
||||
|
||||
ty::PredicateKind::RegionOutlives(predicate) => {
|
||||
let predicate = bound_predicate.rebind(predicate);
|
||||
let predicate = self.resolve_vars_if_possible(predicate);
|
||||
|
|
|
@ -402,6 +402,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
| ty::PredicateKind::ObjectSafe(_)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::Subtype(_)
|
||||
| ty::PredicateKind::Coerce(_)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..) => {
|
||||
let pred = infcx.replace_bound_vars_with_placeholders(binder);
|
||||
|
@ -517,6 +518,31 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Coerce(coerce) => {
|
||||
match self.selcx.infcx().coerce_predicate(
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
Binder::dummy(coerce),
|
||||
) {
|
||||
None => {
|
||||
// None means that both are unresolved.
|
||||
pending_obligation.stalled_on = vec![
|
||||
TyOrConstInferVar::maybe_from_ty(coerce.a).unwrap(),
|
||||
TyOrConstInferVar::maybe_from_ty(coerce.b).unwrap(),
|
||||
];
|
||||
ProcessResult::Unchanged
|
||||
}
|
||||
Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
|
||||
Some(Err(err)) => {
|
||||
let expected_found = ExpectedFound::new(false, coerce.a, coerce.b);
|
||||
ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
|
||||
expected_found,
|
||||
err,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||
match const_evaluatable::is_const_evaluatable(
|
||||
self.selcx.infcx(),
|
||||
|
|
|
@ -308,6 +308,7 @@ fn predicate_references_self(
|
|||
| ty::PredicateKind::RegionOutlives(..)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||
|
@ -336,6 +337,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||
}
|
||||
ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::RegionOutlives(..)
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
|
|
|
@ -512,6 +512,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Coerce(p) => {
|
||||
let p = bound_predicate.rebind(p);
|
||||
// Does this code ever run?
|
||||
match self.infcx.coerce_predicate(&obligation.cause, obligation.param_env, p) {
|
||||
Some(Ok(InferOk { mut obligations, .. })) => {
|
||||
self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
|
||||
self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
obligations.into_iter(),
|
||||
)
|
||||
}
|
||||
Some(Err(_)) => Ok(EvaluatedToErr),
|
||||
None => Ok(EvaluatedToAmbig),
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::WellFormed(arg) => match wf::obligations(
|
||||
self.infcx,
|
||||
obligation.param_env,
|
||||
|
|
|
@ -128,6 +128,10 @@ pub fn predicate_obligations<'a, 'tcx>(
|
|||
wf.compute(a.into());
|
||||
wf.compute(b.into());
|
||||
}
|
||||
ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
|
||||
wf.compute(a.into());
|
||||
wf.compute(b.into());
|
||||
}
|
||||
ty::PredicateKind::ConstEvaluatable(def, substs) => {
|
||||
let obligations = wf.nominal_obligations(def.did, substs);
|
||||
wf.out.extend(obligations);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue