Rollup merge of #105292 - JulianKnodt:no_eager_commit, r=BoxyUwU
Change a commit_if_ok call to probe Removes an over-eager `commit_if_ok` which makes inference worse. I'm not entirely sure whether it's ok to remove the check that types are the same, because casting seems to cause equality checks with incorrect types? Fixes #105037 r? ```@BoxyUwU```
This commit is contained in:
commit
b7587f1867
10 changed files with 221 additions and 16 deletions
|
@ -168,24 +168,27 @@ fn satisfied_from_param_env<'tcx>(
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
||||
infcx: &'a InferCtxt<'tcx>,
|
||||
single_match: Option<Result<ty::Const<'tcx>, ()>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeVisitor<'tcx> for Visitor<'a, 'tcx> {
|
||||
type BreakTy = ();
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
debug!("is_const_evaluatable: candidate={:?}", c);
|
||||
if let Ok(()) = self.infcx.commit_if_ok(|_| {
|
||||
if self.infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
|
||||
if let Ok(()) = ocx.eq(&ObligationCause::dummy(), self.param_env, c.ty(), self.ct.ty())
|
||||
&& let Ok(()) = ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct)
|
||||
ocx.eq(&ObligationCause::dummy(), self.param_env, c.ty(), self.ct.ty()).is_ok()
|
||||
&& ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok()
|
||||
&& ocx.select_all_or_error().is_empty()
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}) {
|
||||
ControlFlow::BREAK
|
||||
} else if let ty::ConstKind::Expr(e) = c.kind() {
|
||||
self.single_match = match self.single_match {
|
||||
None => Some(Ok(c)),
|
||||
Some(Ok(o)) if o == c => Some(Ok(c)),
|
||||
Some(_) => Some(Err(())),
|
||||
};
|
||||
}
|
||||
|
||||
if let ty::ConstKind::Expr(e) = c.kind() {
|
||||
e.visit_with(self)
|
||||
} else {
|
||||
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s substs.
|
||||
|
@ -200,22 +203,29 @@ fn satisfied_from_param_env<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let mut single_match: Option<Result<ty::Const<'tcx>, ()>> = None;
|
||||
|
||||
for pred in param_env.caller_bounds() {
|
||||
match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::ConstEvaluatable(ce) => {
|
||||
let b_ct = tcx.expand_abstract_consts(ce);
|
||||
let mut v = Visitor { ct, infcx, param_env };
|
||||
let result = b_ct.visit_with(&mut v);
|
||||
let mut v = Visitor { ct, infcx, param_env, single_match };
|
||||
let _ = b_ct.visit_with(&mut v);
|
||||
|
||||
if let ControlFlow::Break(()) = result {
|
||||
debug!("is_const_evaluatable: yes");
|
||||
return true;
|
||||
}
|
||||
single_match = v.single_match;
|
||||
}
|
||||
_ => {} // don't care
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Ok(c)) = single_match {
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok());
|
||||
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
|
||||
assert!(ocx.select_all_or_error().is_empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
debug!("is_const_evaluatable: no");
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue