Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/consteval_nextsolver.rs')
-rw-r--r--crates/hir-ty/src/consteval_nextsolver.rs256
1 files changed, 0 insertions, 256 deletions
diff --git a/crates/hir-ty/src/consteval_nextsolver.rs b/crates/hir-ty/src/consteval_nextsolver.rs
deleted file mode 100644
index 6e07d3afe5..0000000000
--- a/crates/hir-ty/src/consteval_nextsolver.rs
+++ /dev/null
@@ -1,256 +0,0 @@
-//! Constant evaluation details
-// FIXME(next-solver): this should get removed as things get moved to rustc_type_ir from chalk_ir
-#![allow(unused)]
-
-use base_db::Crate;
-use hir_def::{
- EnumVariantId, GeneralConstId,
- expr_store::{Body, HygieneId, path::Path},
- hir::{Expr, ExprId},
- resolver::{Resolver, ValueNs},
- type_ref::LiteralConstRef,
-};
-use hir_expand::Lookup;
-use rustc_type_ir::{
- UnevaluatedConst,
- inherent::{IntoKind, SliceLike},
-};
-use stdx::never;
-use triomphe::Arc;
-
-use crate::{
- ConstScalar, Interner, MemoryMap, Substitution, TraitEnvironment,
- consteval::ConstEvalError,
- db::HirDatabase,
- generics::Generics,
- infer::InferenceContext,
- next_solver::{
- Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs,
- ParamConst, SolverDefId, Ty, ValueConst,
- mapping::{ChalkToNextSolver, NextSolverToChalk, convert_binder_to_early_binder},
- },
-};
-
-use super::mir::{interpret_mir, lower_to_mir, pad16};
-
-pub(crate) fn path_to_const<'a, 'g>(
- db: &'a dyn HirDatabase,
- resolver: &Resolver<'a>,
- path: &Path,
- args: impl FnOnce() -> &'g Generics,
- expected_ty: Ty<'a>,
-) -> Option<Const<'a>> {
- let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
- match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
- Some(ValueNs::GenericParam(p)) => {
- let args = args();
- match args
- .type_or_const_param(p.into())
- .and_then(|(idx, p)| p.const_param().map(|p| (idx, p.clone())))
- {
- Some((idx, _param)) => {
- Some(Const::new_param(interner, ParamConst { index: idx as u32, id: p }))
- }
- None => {
- never!(
- "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
- args,
- path,
- p
- );
- None
- }
- }
- }
- Some(ValueNs::ConstId(c)) => {
- let args = GenericArgs::new_from_iter(interner, []);
- Some(Const::new(
- interner,
- rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new(
- SolverDefId::ConstId(c),
- args,
- )),
- ))
- }
- _ => None,
- }
-}
-
-pub fn unknown_const<'db>(ty: Ty<'db>) -> Const<'db> {
- Const::new(DbInterner::conjure(), rustc_type_ir::ConstKind::Error(ErrorGuaranteed))
-}
-
-pub fn unknown_const_as_generic<'db>(ty: Ty<'db>) -> GenericArg<'db> {
- unknown_const(ty).into()
-}
-
-/// Interns a constant scalar with the given type
-pub fn intern_const_ref<'a>(
- db: &'a dyn HirDatabase,
- value: &LiteralConstRef,
- ty: Ty<'a>,
- krate: Crate,
-) -> Const<'a> {
- let interner = DbInterner::new_with(db, Some(krate), None);
- let layout = db.layout_of_ty(ty, TraitEnvironment::empty(krate));
- let kind = match value {
- LiteralConstRef::Int(i) => {
- // FIXME: We should handle failure of layout better.
- let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
- rustc_type_ir::ConstKind::Value(ValueConst::new(
- ty,
- ConstBytes(i.to_le_bytes()[0..size].into(), MemoryMap::default()),
- ))
- }
- LiteralConstRef::UInt(i) => {
- let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
- rustc_type_ir::ConstKind::Value(ValueConst::new(
- ty,
- ConstBytes(i.to_le_bytes()[0..size].into(), MemoryMap::default()),
- ))
- }
- LiteralConstRef::Bool(b) => rustc_type_ir::ConstKind::Value(ValueConst::new(
- ty,
- ConstBytes(Box::new([*b as u8]), MemoryMap::default()),
- )),
- LiteralConstRef::Char(c) => rustc_type_ir::ConstKind::Value(ValueConst::new(
- ty,
- ConstBytes((*c as u32).to_le_bytes().into(), MemoryMap::default()),
- )),
- LiteralConstRef::Unknown => rustc_type_ir::ConstKind::Error(ErrorGuaranteed),
- };
- Const::new(interner, kind)
-}
-
-/// Interns a possibly-unknown target usize
-pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option<u128>, krate: Crate) -> Const<'db> {
- intern_const_ref(
- db,
- &value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt),
- Ty::new_uint(DbInterner::new_with(db, Some(krate), None), rustc_type_ir::UintTy::Usize),
- krate,
- )
-}
-
-pub fn try_const_usize<'db>(db: &'db dyn HirDatabase, c: Const<'db>) -> Option<u128> {
- let interner = DbInterner::new_with(db, None, None);
- match c.kind() {
- ConstKind::Param(_) => None,
- ConstKind::Infer(_) => None,
- ConstKind::Bound(_, _) => None,
- ConstKind::Placeholder(_) => None,
- ConstKind::Unevaluated(unevaluated_const) => {
- let c = match unevaluated_const.def {
- SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
- SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
- _ => unreachable!(),
- };
- let subst = unevaluated_const.args.to_chalk(interner);
- let ec = db.const_eval(c, subst, None).ok()?.to_nextsolver(interner);
- try_const_usize(db, ec)
- }
- ConstKind::Value(val) => Some(u128::from_le_bytes(pad16(&val.value.inner().0, false))),
- ConstKind::Error(_) => None,
- ConstKind::Expr(_) => None,
- }
-}
-
-pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option<i128> {
- let interner = DbInterner::new_with(db, None, None);
- match (*c).kind() {
- ConstKind::Param(_) => None,
- ConstKind::Infer(_) => None,
- ConstKind::Bound(_, _) => None,
- ConstKind::Placeholder(_) => None,
- ConstKind::Unevaluated(unevaluated_const) => {
- let c = match unevaluated_const.def {
- SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
- SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
- _ => unreachable!(),
- };
- let subst = unevaluated_const.args.to_chalk(interner);
- let ec = db.const_eval(c, subst, None).ok()?.to_nextsolver(interner);
- try_const_isize(db, &ec)
- }
- ConstKind::Value(val) => Some(i128::from_le_bytes(pad16(&val.value.inner().0, true))),
- ConstKind::Error(_) => None,
- ConstKind::Expr(_) => None,
- }
-}
-
-pub(crate) fn const_eval_discriminant_variant(
- db: &dyn HirDatabase,
- variant_id: EnumVariantId,
-) -> Result<i128, ConstEvalError> {
- let interner = DbInterner::new_with(db, None, None);
- let def = variant_id.into();
- let body = db.body(def);
- let loc = variant_id.lookup(db);
- if matches!(body[body.body_expr], Expr::Missing) {
- let prev_idx = loc.index.checked_sub(1);
- let value = match prev_idx {
- Some(prev_idx) => {
- 1 + db.const_eval_discriminant(
- loc.parent.enum_variants(db).variants[prev_idx as usize].0,
- )?
- }
- _ => 0,
- };
- return Ok(value);
- }
-
- let repr = db.enum_signature(loc.parent).repr;
- let is_signed = repr.and_then(|repr| repr.int).is_none_or(|int| int.is_signed());
-
- let mir_body = db.monomorphized_mir_body(
- def,
- Substitution::empty(Interner),
- db.trait_environment_for_body(def),
- )?;
- let c = interpret_mir(db, mir_body, false, None)?.0?;
- let c = c.to_nextsolver(interner);
- let c = if is_signed {
- try_const_isize(db, &c).unwrap()
- } else {
- try_const_usize(db, c).unwrap() as i128
- };
- Ok(c)
-}
-
-// FIXME: Ideally constants in const eval should have separate body (issue #7434), and this function should
-// get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here
-// and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
-pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'db>) -> Const<'db> {
- let interner = DbInterner::new_with(ctx.db, None, None);
- let infer = ctx.clone().resolve_all();
- fn has_closure(body: &Body, expr: ExprId) -> bool {
- if matches!(body[expr], Expr::Closure { .. }) {
- return true;
- }
- let mut r = false;
- body.walk_child_exprs(expr, |idx| r |= has_closure(body, idx));
- r
- }
- if has_closure(ctx.body, expr) {
- // Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
- return unknown_const(infer[expr].clone().to_nextsolver(interner));
- }
- if let Expr::Path(p) = &ctx.body[expr] {
- let resolver = &ctx.resolver;
- if let Some(c) = path_to_const(
- ctx.db,
- resolver,
- p,
- || ctx.generics(),
- infer[expr].to_nextsolver(interner),
- ) {
- return c;
- }
- }
- if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
- && let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None)
- {
- return result.to_nextsolver(interner);
- }
- unknown_const(infer[expr].to_nextsolver(interner))
-}