Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/consteval.rs')
-rw-r--r--crates/hir-ty/src/consteval.rs43
1 files changed, 21 insertions, 22 deletions
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index e1d6cec594..2c43feeb3b 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -5,7 +5,7 @@ mod tests;
use base_db::Crate;
use hir_def::{
- ConstId, EnumVariantId, ExpressionStoreOwnerId, GenericDefId, HasModule, StaticId,
+ ConstId, EnumVariantId, ExpressionStoreOwnerId, HasModule, StaticId,
attrs::AttrFlags,
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
hir::{Expr, ExprId, Literal},
@@ -303,6 +303,7 @@ pub(crate) enum CreateConstError<'db> {
UsedForbiddenParam,
ResolveToNonConst,
DoesNotResolve,
+ ConstHasGenerics,
UnderscoreExpr,
TypeMismatch {
#[expect(unused, reason = "will need this for diagnostics")]
@@ -321,9 +322,11 @@ pub(crate) fn path_to_const<'a, 'db>(
let resolution = resolver
.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT)
.ok_or(CreateConstError::DoesNotResolve)?;
+ let no_generics = |def| crate::generics::generics(db, def).has_no_params();
let konst = match resolution {
- ValueNs::ConstId(id) => GeneralConstId::ConstId(id),
+ ValueNs::ConstId(id) if no_generics(id.into()) => GeneralConstId::ConstId(id),
ValueNs::StaticId(id) => GeneralConstId::StaticId(id),
+ ValueNs::ConstId(_) => return Err(CreateConstError::ConstHasGenerics),
ValueNs::GenericParam(param) => {
let index = generics().type_or_const_param_idx(param.into());
if forbid_params_after.is_some_and(|forbid_after| index >= forbid_after) {
@@ -363,7 +366,10 @@ pub(crate) fn create_anon_const<'a, 'db>(
Expr::Path(path)
if let konst =
path_to_const(interner.db, resolver, generics, forbid_params_after, path)
- && !matches!(konst, Err(CreateConstError::DoesNotResolve)) =>
+ && !matches!(
+ konst,
+ Err(CreateConstError::DoesNotResolve | CreateConstError::ConstHasGenerics)
+ ) =>
{
konst
}
@@ -400,12 +406,10 @@ pub(crate) fn const_eval_discriminant_variant(
let body = Body::of(db, def);
let loc = variant_id.lookup(db);
if matches!(body[body.root_expr()], Expr::Missing) {
- let prev_idx = loc.index.checked_sub(1);
+ let prev_idx = loc.index(db).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,
- )?
+ 1 + db.const_eval_discriminant(loc.parent.enum_variants(db).variants[prev_idx].0)?
}
_ => 0,
};
@@ -418,8 +422,11 @@ pub(crate) fn const_eval_discriminant_variant(
let mir_body = db.monomorphized_mir_body(
def.into(),
GenericArgs::empty(interner).store(),
- ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }
- .store(),
+ ParamEnvAndCrate {
+ param_env: db.trait_environment(def.generic_def(db)),
+ krate: def.krate(db),
+ }
+ .store(),
)?;
let c = interpret_mir(db, mir_body, false, None)?.0?;
let c = if is_signed { allocation_as_isize(c) } else { allocation_as_usize(c) as i128 };
@@ -455,12 +462,8 @@ pub(crate) fn const_eval<'db>(
let body = db.monomorphized_mir_body(
def.into(),
subst,
- ParamEnvAndCrate {
- param_env: db
- .trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))),
- krate: def.krate(db),
- }
- .store(),
+ ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }
+ .store(),
)?;
let c = interpret_mir(db, body, false, trait_env.as_ref().map(|env| env.as_ref()))?.0?;
Ok(c.store())
@@ -499,7 +502,7 @@ pub(crate) fn anon_const_eval<'db>(
def.into(),
subst,
ParamEnvAndCrate {
- param_env: db.trait_environment(def.loc(db).owner),
+ param_env: db.trait_environment(def.loc(db).owner.generic_def(db)),
krate: def.krate(db),
}
.store(),
@@ -537,12 +540,8 @@ pub(crate) fn const_eval_static<'db>(
let body = db.monomorphized_mir_body(
def.into(),
GenericArgs::empty(interner).store(),
- ParamEnvAndCrate {
- param_env: db
- .trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))),
- krate: def.krate(db),
- }
- .store(),
+ ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }
+ .store(),
)?;
let c = interpret_mir(db, body, false, None)?.0?;
Ok(c.store())