Make expand_abstract_consts infallible

This commit is contained in:
Boxy 2022-11-24 11:09:15 +00:00 committed by kadmin
parent 4085e94ece
commit 2ac5d91d63
8 changed files with 52 additions and 105 deletions

View file

@ -8,6 +8,7 @@
//! In this case we try to build an abstract representation of this constant using
//! `thir_abstract_const` which can then be checked for structural equality with other
//! generic constants mentioned in the `caller_bounds` of the current environment.
use rustc_hir::def::DefKind;
use rustc_infer::infer::InferCtxt;
use rustc_middle::mir::interpret::ErrorHandled;
@ -42,7 +43,15 @@ pub fn is_const_evaluatable<'tcx>(
};
if tcx.features().generic_const_exprs {
if let Some(ct) = tcx.expand_abstract_consts(ct)? {
let ct = tcx.expand_abstract_consts(ct);
let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
tcx.def_kind(uv.def.did) == DefKind::AnonConst
} else {
false
};
if !is_anon_ct {
if satisfied_from_param_env(tcx, infcx, ct, param_env)? {
return Ok(());
}
@ -52,6 +61,7 @@ pub fn is_const_evaluatable<'tcx>(
return Err(NotConstEvaluatable::MentionsParam);
}
}
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
match concrete {
Err(ErrorHandled::TooGeneric) => Err(NotConstEvaluatable::Error(
@ -78,8 +88,7 @@ pub fn is_const_evaluatable<'tcx>(
// the current crate does not enable `feature(generic_const_exprs)`, abort
// compilation with a useful error.
Err(_) if tcx.sess.is_nightly_build()
&& let Ok(Some(ac)) = tcx.expand_abstract_consts(ct)
&& let ty::ConstKind::Expr(_) = ac.kind() =>
&& let ty::ConstKind::Expr(_) = tcx.expand_abstract_consts(ct).kind() =>
{
tcx.sess
.struct_span_fatal(
@ -164,8 +173,7 @@ fn satisfied_from_param_env<'tcx>(
for pred in param_env.caller_bounds() {
match pred.kind().skip_binder() {
ty::PredicateKind::ConstEvaluatable(ce) => {
let b_ct = tcx.expand_abstract_consts(ce)?.unwrap_or(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);

View file

@ -462,10 +462,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
//
// Let's just see where this breaks :shrug:
{
let c1 =
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1) { a } else { c1 };
let c2 =
if let Ok(Some(b)) = tcx.expand_abstract_consts(c2) { b } else { c2 };
let c1 = tcx.expand_abstract_consts(c1);
let c2 = tcx.expand_abstract_consts(c2);
debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
use rustc_hir::def::DefKind;

View file

@ -837,24 +837,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
}
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// Constants can only influence object safety if they reference `Self`.
// Constants can only influence object safety if they are generic and reference `Self`.
// This is only possible for unevaluated constants, so we walk these here.
//
// If `AbstractConst::from_const` returned an error we already failed compilation
// so we don't have to emit an additional error here.
//
// We currently recurse into abstract consts here but do not recurse in
// `is_const_evaluatable`. This means that the object safety check is more
// liberal than the const eval check.
//
// This shouldn't really matter though as we can't really use any
// constants which are not considered const evaluatable.
if let ty::ConstKind::Unevaluated(_uv) = ct.kind() &&
let Ok(Some(ct)) = self.tcx.expand_abstract_consts(ct){
self.visit_const(ct)
} else {
ct.super_visit_with(self)
}
self.tcx.expand_abstract_consts(ct).super_visit_with(self)
}
}

View file

@ -664,10 +664,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);
{
let c1 =
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1) { a } else { c1 };
let c2 =
if let Ok(Some(b)) = tcx.expand_abstract_consts(c2) { b } else { c2 };
let c1 = tcx.expand_abstract_consts(c1);
let c2 = tcx.expand_abstract_consts(c2);
debug!(
"evalaute_predicate_recursively: equating consts:\nc1= {:?}\nc2= {:?}",
c1, c2