Coalesce branches
Move a bunch of branches together into one if block, for easier reading. Resolve comments Attempt to make some branches unreachable [tmp] Revert unreachable branches
This commit is contained in:
parent
edae6edd32
commit
ee8efc5c4a
2 changed files with 135 additions and 139 deletions
|
@ -21,6 +21,7 @@
|
||||||
#![feature(label_break_value)]
|
#![feature(label_break_value)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
|
#![feature(if_let_guard)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![recursion_limit = "512"] // For rustdoc
|
#![recursion_limit = "512"] // For rustdoc
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
|
|
||||||
if tcx.features().generic_const_exprs {
|
if tcx.features().generic_const_exprs {
|
||||||
match AbstractConst::new(tcx, uv)? {
|
if let Some(ct) = AbstractConst::new(tcx, uv)? {
|
||||||
// We are looking at a generic abstract constant.
|
|
||||||
Some(ct) => {
|
|
||||||
if satisfied_from_param_env(tcx, ct, param_env)? {
|
if satisfied_from_param_env(tcx, ct, param_env)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -93,37 +91,32 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
FailureKind::MentionsParam => {
|
FailureKind::MentionsParam => {
|
||||||
return Err(NotConstEvaluatable::MentionsParam);
|
return Err(NotConstEvaluatable::MentionsParam);
|
||||||
}
|
}
|
||||||
FailureKind::Concrete => {
|
// returned below
|
||||||
// Dealt with below by the same code which handles this
|
FailureKind::Concrete => {}
|
||||||
// without the feature gate.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
||||||
|
match concrete {
|
||||||
|
Err(ErrorHandled::TooGeneric) => Err(if !uv.has_infer_types_or_consts() {
|
||||||
|
infcx
|
||||||
|
.tcx
|
||||||
|
.sess
|
||||||
|
.delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv));
|
||||||
|
NotConstEvaluatable::MentionsParam
|
||||||
|
} else {
|
||||||
|
NotConstEvaluatable::MentionsInfer
|
||||||
|
}),
|
||||||
|
Err(ErrorHandled::Linted) => {
|
||||||
|
let reported = infcx
|
||||||
|
.tcx
|
||||||
|
.sess
|
||||||
|
.delay_span_bug(span, "constant in type had error reported as lint");
|
||||||
|
Err(NotConstEvaluatable::Error(reported))
|
||||||
}
|
}
|
||||||
None => {
|
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
|
||||||
// If we are dealing with a concrete constant, we can
|
Ok(_) => Ok(()),
|
||||||
// reuse the old code path and try to evaluate
|
|
||||||
// the constant.
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
let future_compat_lint = || {
|
|
||||||
if tcx.features().generic_const_exprs {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if let Some(local_def_id) = uv.def.did.as_local() {
|
|
||||||
infcx.tcx.struct_span_lint_hir(
|
|
||||||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
|
||||||
infcx.tcx.hir().local_def_id_to_hir_id(local_def_id),
|
|
||||||
span,
|
|
||||||
|err| {
|
|
||||||
err.build("cannot use constants which depend on generic parameters in types")
|
|
||||||
.emit();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME: We should only try to evaluate a given constant here if it is fully concrete
|
// FIXME: We should only try to evaluate a given constant here if it is fully concrete
|
||||||
// as we don't want to allow things like `[u8; std::mem::size_of::<*mut T>()]`.
|
// as we don't want to allow things like `[u8; std::mem::size_of::<*mut T>()]`.
|
||||||
//
|
//
|
||||||
|
@ -134,29 +127,13 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
// See #74595 for more details about this.
|
// See #74595 for more details about this.
|
||||||
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
||||||
|
|
||||||
if concrete.is_ok() && uv.substs.has_param_types_or_consts() {
|
match concrete {
|
||||||
match infcx.tcx.def_kind(uv.def.did) {
|
|
||||||
DefKind::AnonConst | DefKind::InlineConst => {
|
|
||||||
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
|
|
||||||
|
|
||||||
if mir_body.is_polymorphic {
|
|
||||||
future_compat_lint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => future_compat_lint(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're evaluating a foreign constant, under a nightly compiler without generic
|
// If we're evaluating a foreign constant, under a nightly compiler without generic
|
||||||
// const exprs, AND it would've passed if that expression had been evaluated with
|
// const exprs, AND it would've passed if that expression had been evaluated with
|
||||||
// generic const exprs, then suggest using generic const exprs.
|
// generic const exprs, then suggest using generic const exprs.
|
||||||
if concrete.is_err()
|
Err(_) if tcx.sess.is_nightly_build()
|
||||||
&& tcx.sess.is_nightly_build()
|
|
||||||
&& !uv.def.did.is_local()
|
|
||||||
&& !tcx.features().generic_const_exprs
|
|
||||||
&& let Ok(Some(ct)) = AbstractConst::new(tcx, uv)
|
&& let Ok(Some(ct)) = AbstractConst::new(tcx, uv)
|
||||||
&& satisfied_from_param_env(tcx, ct, param_env) == Ok(true)
|
&& satisfied_from_param_env(tcx, ct, param_env) == Ok(true) => {
|
||||||
{
|
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.struct_span_fatal(
|
.struct_span_fatal(
|
||||||
// Slightly better span than just using `span` alone
|
// Slightly better span than just using `span` alone
|
||||||
|
@ -173,11 +150,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
.emit()
|
.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(?concrete, "is_const_evaluatable");
|
Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
|
||||||
match concrete {
|
NotConstEvaluatable::MentionsInfer
|
||||||
Err(ErrorHandled::TooGeneric) => Err(match uv.has_infer_types_or_consts() {
|
} else {
|
||||||
true => NotConstEvaluatable::MentionsInfer,
|
NotConstEvaluatable::MentionsParam
|
||||||
false => NotConstEvaluatable::MentionsParam,
|
|
||||||
}),
|
}),
|
||||||
Err(ErrorHandled::Linted) => {
|
Err(ErrorHandled::Linted) => {
|
||||||
let reported =
|
let reported =
|
||||||
|
@ -185,7 +161,26 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
Err(NotConstEvaluatable::Error(reported))
|
Err(NotConstEvaluatable::Error(reported))
|
||||||
}
|
}
|
||||||
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
|
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => {
|
||||||
|
if uv.substs.has_param_types_or_consts() {
|
||||||
|
assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
|
||||||
|
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
|
||||||
|
|
||||||
|
if mir_body.is_polymorphic {
|
||||||
|
let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
|
||||||
|
tcx.struct_span_lint_hir(
|
||||||
|
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||||
|
tcx.hir().local_def_id_to_hir_id(local_def_id),
|
||||||
|
span,
|
||||||
|
|err| {
|
||||||
|
err.build("cannot use constants which depend on generic parameters in types").emit();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue