Skip to content
Open
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 Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/hir-def/src/nameres/attr_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl DefMap {
return Ok(ResolvedAttr::Other);
}
}
None => return Err(UnresolvedMacro { path: ast_id.path.as_ref().clone() }),
None => return Err(UnresolvedMacro { path: (*ast_id.path).clone() }),
};

Ok(ResolvedAttr::Macro(attr_macro_as_call_id(
Expand Down Expand Up @@ -145,7 +145,7 @@ pub(super) fn derive_macro_as_call_id(
) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
let (macro_id, def_id) = resolver(&item_attr.path)
.filter(|(_, def_id)| def_id.is_derive())
.ok_or_else(|| UnresolvedMacro { path: item_attr.path.as_ref().clone() })?;
.ok_or_else(|| UnresolvedMacro { path: (*item_attr.path).clone() })?;
let call_id = def_id.make_call(
db,
krate,
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1675,7 +1675,7 @@ impl<'db> DefCollector<'db> {
derive_index: *derive_pos as u32,
derive_macro_id: *derive_macro_id,
},
ast_id.path.as_ref().clone(),
(*ast_id.path).clone(),
));
}
// These are diagnosed by `reseed_with_unresolved_attribute`, as that function consumes them
Expand Down
149 changes: 89 additions & 60 deletions crates/hir-ty/src/consteval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ use crate::{
mir::{MirEvalError, MirLowerError},
next_solver::{
Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs,
ParamEnv, Ty, ValueConst,
ParamEnv, StoredConst, StoredGenericArgs, Ty, ValueConst,
},
traits::StoredParamEnvAndCrate,
};

use super::mir::{interpret_mir, lower_to_mir, pad16};
Expand All @@ -38,12 +39,12 @@ pub fn unknown_const_as_generic<'db>(ty: Ty<'db>) -> GenericArg<'db> {
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConstEvalError<'db> {
MirLowerError(MirLowerError<'db>),
MirEvalError(MirEvalError<'db>),
pub enum ConstEvalError {
MirLowerError(MirLowerError),
MirEvalError(MirEvalError),
}

impl ConstEvalError<'_> {
impl ConstEvalError {
pub fn pretty_print(
&self,
f: &mut String,
Expand All @@ -62,17 +63,17 @@ impl ConstEvalError<'_> {
}
}

impl<'db> From<MirLowerError<'db>> for ConstEvalError<'db> {
fn from(value: MirLowerError<'db>) -> Self {
impl From<MirLowerError> for ConstEvalError {
fn from(value: MirLowerError) -> Self {
match value {
MirLowerError::ConstEvalError(_, e) => *e,
_ => ConstEvalError::MirLowerError(value),
}
}
}

impl<'db> From<MirEvalError<'db>> for ConstEvalError<'db> {
fn from(value: MirEvalError<'db>) -> Self {
impl From<MirEvalError> for ConstEvalError {
fn from(value: MirEvalError) -> Self {
ConstEvalError::MirEvalError(value)
}
}
Expand All @@ -85,7 +86,8 @@ pub fn intern_const_ref<'a>(
krate: Crate,
) -> Const<'a> {
let interner = DbInterner::new_no_crate(db);
let layout = db.layout_of_ty(ty, ParamEnvAndCrate { param_env: ParamEnv::empty(), krate });
let layout = db
.layout_of_ty(ty.store(), ParamEnvAndCrate { param_env: ParamEnv::empty(), krate }.store());
let kind = match value {
LiteralConstRef::Int(i) => {
// FIXME: We should handle failure of layout better.
Expand Down Expand Up @@ -180,10 +182,10 @@ pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option<
}
}

pub(crate) fn const_eval_discriminant_variant<'db>(
db: &'db dyn HirDatabase,
pub(crate) fn const_eval_discriminant_variant(
db: &dyn HirDatabase,
variant_id: EnumVariantId,
) -> Result<i128, ConstEvalError<'db>> {
) -> Result<i128, ConstEvalError> {
let interner = DbInterner::new_no_crate(db);
let def = variant_id.into();
let body = db.body(def);
Expand All @@ -206,8 +208,9 @@ pub(crate) fn const_eval_discriminant_variant<'db>(

let mir_body = db.monomorphized_mir_body(
def,
GenericArgs::new_from_iter(interner, []),
ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) },
GenericArgs::empty(interner).store(),
ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) }
.store(),
)?;
let c = interpret_mir(db, mir_body, false, None)?.0?;
let c = if is_signed {
Expand All @@ -233,7 +236,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd
}
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]);
return Const::error(ctx.interner());
}
if let Expr::Path(p) = &ctx.body[expr] {
let mut ctx = TyLoweringContext::new(
Expand All @@ -252,63 +255,89 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd
{
return result;
}
unknown_const(infer[expr])
Const::error(ctx.interner())
}

pub(crate) fn const_eval_cycle_result<'db>(
_: &'db dyn HirDatabase,
_: salsa::Id,
_: ConstId,
_: GenericArgs<'db>,
_: Option<ParamEnvAndCrate<'db>>,
) -> Result<Const<'db>, ConstEvalError<'db>> {
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
}

pub(crate) fn const_eval_static_cycle_result<'db>(
_: &'db dyn HirDatabase,
_: salsa::Id,
_: StaticId,
) -> Result<Const<'db>, ConstEvalError<'db>> {
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
}

pub(crate) fn const_eval_discriminant_cycle_result<'db>(
_: &'db dyn HirDatabase,
pub(crate) fn const_eval_discriminant_cycle_result(
_: &dyn HirDatabase,
_: salsa::Id,
_: EnumVariantId,
) -> Result<i128, ConstEvalError<'db>> {
) -> Result<i128, ConstEvalError> {
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
}

pub(crate) fn const_eval_query<'db>(
pub(crate) fn const_eval<'db>(
db: &'db dyn HirDatabase,
def: ConstId,
subst: GenericArgs<'db>,
trait_env: Option<ParamEnvAndCrate<'db>>,
) -> Result<Const<'db>, ConstEvalError<'db>> {
let body = db.monomorphized_mir_body(
def.into(),
subst,
ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) },
)?;
let c = interpret_mir(db, body, false, trait_env)?.0?;
Ok(c)
) -> Result<Const<'db>, ConstEvalError> {
return match const_eval_query(db, def, subst.store(), trait_env.map(|env| env.store())) {
Ok(konst) => Ok(konst.as_ref()),
Err(err) => Err(err.clone()),
};

#[salsa::tracked(returns(ref), cycle_result = const_eval_cycle_result)]
pub(crate) fn const_eval_query<'db>(
db: &'db dyn HirDatabase,
def: ConstId,
subst: StoredGenericArgs,
trait_env: Option<StoredParamEnvAndCrate>,
) -> Result<StoredConst, ConstEvalError> {
let body = db.monomorphized_mir_body(
def.into(),
subst,
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())
}

pub(crate) fn const_eval_cycle_result(
_: &dyn HirDatabase,
_: salsa::Id,
_: ConstId,
_: StoredGenericArgs,
_: Option<StoredParamEnvAndCrate>,
) -> Result<StoredConst, ConstEvalError> {
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
}
}

pub(crate) fn const_eval_static_query<'db>(
pub(crate) fn const_eval_static<'db>(
db: &'db dyn HirDatabase,
def: StaticId,
) -> Result<Const<'db>, ConstEvalError<'db>> {
let interner = DbInterner::new_no_crate(db);
let body = db.monomorphized_mir_body(
def.into(),
GenericArgs::new_from_iter(interner, []),
ParamEnvAndCrate {
param_env: db.trait_environment_for_body(def.into()),
krate: def.krate(db),
},
)?;
let c = interpret_mir(db, body, false, None)?.0?;
Ok(c)
) -> Result<Const<'db>, ConstEvalError> {
return match const_eval_static_query(db, def) {
Ok(konst) => Ok(konst.as_ref()),
Err(err) => Err(err.clone()),
};

#[salsa::tracked(returns(ref), cycle_result = const_eval_static_cycle_result)]
pub(crate) fn const_eval_static_query<'db>(
db: &'db dyn HirDatabase,
def: StaticId,
) -> Result<StoredConst, ConstEvalError> {
let interner = DbInterner::new_no_crate(db);
let body = db.monomorphized_mir_body(
def.into(),
GenericArgs::empty(interner).store(),
ParamEnvAndCrate {
param_env: db.trait_environment_for_body(def.into()),
krate: def.krate(db),
}
.store(),
)?;
let c = interpret_mir(db, body, false, None)?.0?;
Ok(c.store())
}

pub(crate) fn const_eval_static_cycle_result(
_: &dyn HirDatabase,
_: salsa::Id,
_: StaticId,
) -> Result<StoredConst, ConstEvalError> {
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
}
}
10 changes: 5 additions & 5 deletions crates/hir-ty/src/consteval/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use super::{

mod intrinsics;

fn simplify(e: ConstEvalError<'_>) -> ConstEvalError<'_> {
fn simplify(e: ConstEvalError) -> ConstEvalError {
match e {
ConstEvalError::MirEvalError(MirEvalError::InFunction(e, _)) => {
simplify(ConstEvalError::MirEvalError(*e))
Expand All @@ -39,7 +39,7 @@ fn simplify(e: ConstEvalError<'_>) -> ConstEvalError<'_> {
#[track_caller]
fn check_fail(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
error: impl FnOnce(ConstEvalError<'_>) -> bool,
error: impl FnOnce(ConstEvalError) -> bool,
) {
let (db, file_id) = TestDB::with_single_file(ra_fixture);
crate::attach_db(&db, || match eval_goal(&db, file_id) {
Expand Down Expand Up @@ -104,7 +104,7 @@ fn check_answer(
});
}

fn pretty_print_err(e: ConstEvalError<'_>, db: &TestDB) -> String {
fn pretty_print_err(e: ConstEvalError, db: &TestDB) -> String {
let mut err = String::new();
let span_formatter = |file, range| format!("{file:?} {range:?}");
let display_target =
Expand All @@ -121,7 +121,7 @@ fn pretty_print_err(e: ConstEvalError<'_>, db: &TestDB) -> String {
err
}

fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEvalError<'_>> {
fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEvalError> {
let _tracing = setup_tracing();
let interner = DbInterner::new_no_crate(db);
let module_id = db.module_for_file(file_id.file_id(db));
Expand All @@ -142,7 +142,7 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEv
_ => None,
})
.expect("No const named GOAL found in the test");
db.const_eval(const_id, GenericArgs::new_from_iter(interner, []), None)
db.const_eval(const_id, GenericArgs::empty(interner), None)
}

#[test]
Expand Down
Loading