Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ConstKind::Expr #99798

Merged
merged 16 commits into from
Nov 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => {
throw_inval!(TooGeneric)
}
// FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated
ty::ConstKind::Expr(_) => throw_inval!(TooGeneric),
ty::ConstKind::Error(reported) => {
throw_inval!(AlreadyReported(reported))
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
ty::ConstKind::Param(_)
| ty::ConstKind::Value(_)
| ty::ConstKind::Unevaluated(..)
| ty::ConstKind::Expr(..)
| ty::ConstKind::Error(_) => ct.super_fold_with(self),
}
}
Expand Down
58 changes: 15 additions & 43 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::traits::select;
use rustc_middle::ty::abstract_const::{AbstractConst, FailureKind};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BoundVarReplacerDelegate;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
Expand Down Expand Up @@ -713,32 +712,6 @@ impl<'tcx> InferCtxt<'tcx> {
TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false }
}

/// calls `tcx.try_unify_abstract_consts` after
/// canonicalizing the consts.
#[instrument(skip(self), level = "debug")]
pub fn try_unify_abstract_consts(
&self,
a: ty::UnevaluatedConst<'tcx>,
b: ty::UnevaluatedConst<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
// Reject any attempt to unify two unevaluated constants that contain inference
// variables, since inference variables in queries lead to ICEs.
if a.substs.has_non_region_infer()
|| b.substs.has_non_region_infer()
|| param_env.has_non_region_infer()
{
debug!("a or b or param_env contain infer vars in its substs -> cannot unify");
return false;
}

let param_env_and = param_env.and((a, b));
let erased = self.tcx.erase_regions(param_env_and);
debug!("after erase_regions: {:?}", erased);

self.tcx.try_unify_abstract_consts(erased)
}

pub fn is_in_snapshot(&self) -> bool {
self.in_snapshot.get()
}
Expand Down Expand Up @@ -1646,34 +1619,33 @@ impl<'tcx> InferCtxt<'tcx> {

// Postpone the evaluation of constants whose substs depend on inference
// variables
let tcx = self.tcx;
if substs.has_non_region_infer() {
let ac = AbstractConst::new(self.tcx, unevaluated);
match ac {
Ok(None) => {
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
param_env = self.tcx.param_env(unevaluated.def.did);
}
Ok(Some(ct)) => {
if ct.unify_failure_kind(self.tcx) == FailureKind::Concrete {
substs = replace_param_and_infer_substs_with_placeholder(self.tcx, substs);
} else {
return Err(ErrorHandled::TooGeneric);
}
if let Some(ct) = tcx.bound_abstract_const(unevaluated.def)? {
let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs));
if let Err(e) = ct.error_reported() {
return Err(ErrorHandled::Reported(e));
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
return Err(ErrorHandled::TooGeneric);
} else {
substs = replace_param_and_infer_substs_with_placeholder(tcx, substs);
}
Err(guar) => return Err(ErrorHandled::Reported(guar)),
} else {
substs = InternalSubsts::identity_for_item(tcx, unevaluated.def.did);
param_env = tcx.param_env(unevaluated.def.did);
}
}

let param_env_erased = self.tcx.erase_regions(param_env);
let substs_erased = self.tcx.erase_regions(substs);
let param_env_erased = tcx.erase_regions(param_env);
let substs_erased = tcx.erase_regions(substs);
debug!(?param_env_erased);
debug!(?substs_erased);

let unevaluated = ty::UnevaluatedConst { def: unevaluated.def, substs: substs_erased };

// The return value is the evaluated value which doesn't contain any reference to inference
// variables, thus we don't need to substitute back the original values.
self.tcx.const_eval_resolve_for_typeck(param_env_erased, unevaluated, span)
tcx.const_eval_resolve_for_typeck(param_env_erased, unevaluated, span)
}

/// `ty_or_const_infer_var_changed` is equivalent to one of these two:
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,12 +644,6 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol {
}
}

impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [ty::abstract_const::Node<'tcx>] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
}

impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ define_tables! {
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
// FIXME(compiler-errors): Why isn't this a LazyArray?
thir_abstract_const: Table<DefIndex, LazyValue<&'static [ty::abstract_const::Node<'static>]>>,
thir_abstract_const: Table<DefIndex, LazyValue<ty::Const<'static>>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
constness: Table<DefIndex, hir::Constness>,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
// These variants shouldn't exist in the MIR.
ty::ConstKind::Placeholder(_)
| ty::ConstKind::Infer(_)
| ty::ConstKind::Expr(_)
| ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal),
},
ConstantKind::Unevaluated(uv, _) => {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1185,15 +1185,17 @@ pub enum NullOp {
AlignOf,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
pub enum UnOp {
/// The `!` operator for logical inversion
Not,
/// The `-` operator for negation
Neg,
}

#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub enum BinOp {
/// The `+` operator (addition)
Add,
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/mir/type_foldable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ TrivialTypeTraversalAndLiftImpls! {
UserTypeAnnotationIndex,
BorrowKind,
CastKind,
BinOp,
NullOp,
UnOp,
hir::Movability,
BasicBlock,
SwitchTargets,
Expand Down
13 changes: 2 additions & 11 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ rustc_queries! {
/// Try to build an abstract representation of the given constant.
query thir_abstract_const(
key: DefId
) -> Result<Option<&'tcx [ty::abstract_const::Node<'tcx>]>, ErrorGuaranteed> {
) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> {
desc {
|tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
}
Expand All @@ -409,23 +409,14 @@ rustc_queries! {
/// Try to build an abstract representation of the given constant.
query thir_abstract_const_of_const_arg(
key: (LocalDefId, DefId)
) -> Result<Option<&'tcx [ty::abstract_const::Node<'tcx>]>, ErrorGuaranteed> {
) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> {
desc {
|tcx|
"building an abstract representation for the const argument `{}`",
tcx.def_path_str(key.0.to_def_id()),
}
}

query try_unify_abstract_consts(key:
ty::ParamEnvAnd<'tcx, (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>
)>) -> bool {
desc {
|tcx| "trying to unify the generic constants `{}` and `{}`",
tcx.def_path_str(key.value.0.def.did), tcx.def_path_str(key.value.1.def.did)
}
}

query mir_drops_elaborated_and_const_checked(
key: ty::WithOptConstParam<LocalDefId>
) -> &'tcx Steal<mir::Body<'tcx>> {
Expand Down
Loading