support calls on opaque types :<
This commit is contained in:
@@ -204,7 +204,7 @@ where
|
||||
//
|
||||
// Only goals proven via the trait solver should be region dependent.
|
||||
Certainty::Yes => {}
|
||||
Certainty::Maybe(_) => {
|
||||
Certainty::Maybe { .. } => {
|
||||
self.obligations.register(obligation, None);
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,7 @@ where
|
||||
infcx.push_hir_typeck_potentially_region_dependent_goal(obligation);
|
||||
}
|
||||
}
|
||||
Certainty::Maybe(_) => self.obligations.register(obligation, stalled_on),
|
||||
Certainty::Maybe { .. } => self.obligations.register(obligation, stalled_on),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,15 +95,17 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
|
||||
root_obligation.cause.span,
|
||||
None,
|
||||
) {
|
||||
Ok(GoalEvaluation { certainty: Certainty::Maybe(MaybeCause::Ambiguity), .. }) => {
|
||||
(FulfillmentErrorCode::Ambiguity { overflow: None }, true)
|
||||
}
|
||||
Ok(GoalEvaluation {
|
||||
certainty: Certainty::Maybe { cause: MaybeCause::Ambiguity, .. },
|
||||
..
|
||||
}) => (FulfillmentErrorCode::Ambiguity { overflow: None }, true),
|
||||
Ok(GoalEvaluation {
|
||||
certainty:
|
||||
Certainty::Maybe(MaybeCause::Overflow {
|
||||
suggest_increasing_limit,
|
||||
keep_constraints: _,
|
||||
}),
|
||||
Certainty::Maybe {
|
||||
cause:
|
||||
MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
|
||||
..
|
||||
},
|
||||
..
|
||||
}) => (
|
||||
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
|
||||
@@ -266,7 +268,8 @@ impl<'tcx> BestObligation<'tcx> {
|
||||
);
|
||||
// Skip nested goals that aren't the *reason* for our goal's failure.
|
||||
match (self.consider_ambiguities, nested_goal.result()) {
|
||||
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
|
||||
(true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. }))
|
||||
| (false, Err(_)) => {}
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
@@ -407,7 +410,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
||||
let tcx = goal.infcx().tcx;
|
||||
// Skip goals that aren't the *reason* for our goal's failure.
|
||||
match (self.consider_ambiguities, goal.result()) {
|
||||
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
|
||||
(true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })) | (false, Err(_)) => {
|
||||
}
|
||||
_ => return ControlFlow::Continue(()),
|
||||
}
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
|
||||
assert_matches!(
|
||||
shallow_certainty.replace(c),
|
||||
None | Some(Certainty::Maybe(MaybeCause::Ambiguity))
|
||||
None | Some(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })
|
||||
);
|
||||
}
|
||||
inspect::ProbeStep::NestedProbe(ref probe) => {
|
||||
|
||||
@@ -62,7 +62,7 @@ impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select {
|
||||
|
||||
// Don't winnow until `Certainty::Yes` -- we don't need to winnow until
|
||||
// codegen, and only on the good path.
|
||||
if matches!(goal.result().unwrap(), Certainty::Maybe(..)) {
|
||||
if matches!(goal.result().unwrap(), Certainty::Maybe { .. }) {
|
||||
return ControlFlow::Break(Ok(None));
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
|
||||
) -> bool {
|
||||
// Don't winnow until `Certainty::Yes` -- we don't need to winnow until
|
||||
// codegen, and only on the good path.
|
||||
if matches!(other.result().unwrap(), Certainty::Maybe(..)) {
|
||||
if matches!(other.result().unwrap(), Certainty::Maybe { .. }) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -143,13 +143,13 @@ fn to_selection<'tcx>(
|
||||
span: Span,
|
||||
cand: inspect::InspectCandidate<'_, 'tcx>,
|
||||
) -> Option<Selection<'tcx>> {
|
||||
if let Certainty::Maybe(..) = cand.shallow_certainty() {
|
||||
if let Certainty::Maybe { .. } = cand.shallow_certainty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let nested = match cand.result().expect("expected positive result") {
|
||||
Certainty::Yes => thin_vec![],
|
||||
Certainty::Maybe(_) => cand
|
||||
Certainty::Maybe { .. } => cand
|
||||
.instantiate_nested_goals(span)
|
||||
.into_iter()
|
||||
.map(|nested| {
|
||||
|
||||
@@ -682,7 +682,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
|
||||
// was irrelevant.
|
||||
match goal.result() {
|
||||
Ok(Certainty::Yes) | Err(NoSolution) => return,
|
||||
Ok(Certainty::Maybe(_)) => {}
|
||||
Ok(Certainty::Maybe { .. }) => {}
|
||||
}
|
||||
|
||||
// For bound predicates we simply call `infcx.enter_forall`
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use rustc_infer::traits::solve::Goal;
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
|
||||
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::infer::canonical::OriginalQueryValues;
|
||||
use crate::solve::SolverDelegate;
|
||||
use crate::traits::{
|
||||
EvaluationResult, ObligationCtxt, OverflowError, PredicateObligation, SelectionContext,
|
||||
};
|
||||
@@ -15,6 +18,20 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
self.evaluate_obligation_no_overflow(obligation).may_apply()
|
||||
}
|
||||
|
||||
/// See the comment on [OpaqueTypesJank](crate::solve::OpaqueTypesJank)
|
||||
/// for more details.
|
||||
fn predicate_may_hold_opaque_types_jank(&self, obligation: &PredicateObligation<'tcx>) -> bool {
|
||||
if self.next_trait_solver() {
|
||||
<&SolverDelegate<'tcx>>::from(self).root_goal_may_hold_opaque_types_jank(Goal::new(
|
||||
self.tcx,
|
||||
obligation.param_env,
|
||||
obligation.predicate,
|
||||
))
|
||||
} else {
|
||||
self.predicate_may_hold(obligation)
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluates whether the predicate can be satisfied in the given
|
||||
/// `ParamEnv`, and returns `false` if not certain. However, this is
|
||||
/// not entirely accurate if inference variables are involved.
|
||||
|
||||
Reference in New Issue
Block a user