Skip to content

Commit

Permalink
Auto merge of rust-lang#99798 - JulianKnodt:ac1, r=BoxyUwU
Browse files Browse the repository at this point in the history
Add `ConstKind::Expr`

Starting to implement `ty::ConstKind::Abstract`, most of the match cases are stubbed out, some I was unsure what to add, others I didn't want to add until a more complete implementation was ready.

r? `@lcnr`
  • Loading branch information
bors committed Nov 25, 2022
2 parents 8681d4c + d0209db commit aff003b
Show file tree
Hide file tree
Showing 40 changed files with 802 additions and 812 deletions.
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

0 comments on commit aff003b

Please sign in to comment.