Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/eval.rs')
-rw-r--r--crates/hir-ty/src/mir/eval.rs151
1 files changed, 73 insertions, 78 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 74a34e2981..386226b16d 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -2,26 +2,27 @@
use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range};
-use base_db::CrateId;
-use chalk_ir::{cast::Cast, Mutability};
+use base_db::Crate;
+use chalk_ir::{Mutability, cast::Cast};
use either::Either;
use hir_def::{
+ AdtId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId,
+ VariantId,
builtin_type::BuiltinType,
- data::adt::{StructFlags, VariantData},
expr_store::HygieneId,
+ item_tree::FieldsShape,
lang_item::LangItem,
layout::{TagEncoding, Variants},
resolver::{HasResolver, TypeNs, ValueNs},
- AdtId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId,
- VariantId,
+ signatures::{StaticFlags, StructFlags},
};
-use hir_expand::{mod_path::path, name::Name, HirFileIdExt, InFile};
+use hir_expand::{InFile, mod_path::path, name::Name};
use intern::sym;
use la_arena::ArenaMap;
use rustc_abi::TargetDataLayout;
use rustc_apfloat::{
- ieee::{Half as f16, Quad as f128},
Float,
+ ieee::{Half as f16, Quad as f128},
};
use rustc_hash::{FxHashMap, FxHashSet};
use span::FileId;
@@ -30,7 +31,9 @@ use syntax::{SyntaxNodePtr, TextRange};
use triomphe::Arc;
use crate::{
- consteval::{intern_const_scalar, try_const_usize, ConstEvalError},
+ CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId, Interner,
+ MemoryMap, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
+ consteval::{ConstEvalError, intern_const_scalar, try_const_usize},
db::{HirDatabase, InternedClosure},
display::{ClosureStyle, DisplayTarget, HirDisplay},
infer::PointerCast,
@@ -39,15 +42,13 @@ use crate::{
method_resolution::{is_dyn_method, lookup_impl_const},
static_lifetime,
traits::FnTrait,
- utils::{detect_variant_from_bytes, ClosureSubst},
- CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId, Interner,
- MemoryMap, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
+ utils::{ClosureSubst, detect_variant_from_bytes},
};
use super::{
- return_slot, AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError,
- MirSpan, Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
- TerminatorKind, UnOp,
+ AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan,
+ Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
+ TerminatorKind, UnOp, return_slot,
};
mod shim;
@@ -186,7 +187,7 @@ pub struct Evaluator<'a> {
cached_fn_trait_func: Option<FunctionId>,
cached_fn_mut_trait_func: Option<FunctionId>,
cached_fn_once_trait_func: Option<FunctionId>,
- crate_id: CrateId,
+ crate_id: Crate,
// FIXME: This is a workaround, see the comment on `interpret_mir`
assert_placeholder_ty_is_unused: bool,
/// A general limit on execution, to prevent non terminating programs from breaking r-a main process
@@ -368,11 +369,11 @@ impl MirEvalError {
for (func, span, def) in stack.iter().take(30).rev() {
match func {
Either::Left(func) => {
- let function_name = db.function_data(*func);
+ let function_name = db.function_signature(*func);
writeln!(
f,
"In function {} ({:?})",
- function_name.name.display(db.upcast(), display_target.edition),
+ function_name.name.display(db, display_target.edition),
func
)?;
}
@@ -406,9 +407,9 @@ impl MirEvalError {
},
MirSpan::Unknown => continue,
};
- let file_id = span.file_id.original_file(db.upcast());
+ let file_id = span.file_id.original_file(db);
let text_range = span.value.text_range();
- writeln!(f, "{}", span_formatter(file_id.file_id(), text_range))?;
+ writeln!(f, "{}", span_formatter(file_id.file_id(db), text_range))?;
}
}
match err {
@@ -421,10 +422,10 @@ impl MirEvalError {
)?;
}
MirEvalError::MirLowerError(func, err) => {
- let function_name = db.function_data(*func);
- let self_ = match func.lookup(db.upcast()).container {
+ let function_name = db.function_signature(*func);
+ let self_ = match func.lookup(db).container {
ItemContainerId::ImplId(impl_id) => Some({
- let generics = crate::generics::generics(db.upcast(), impl_id.into());
+ let generics = crate::generics::generics(db, impl_id.into());
let substs = generics.placeholder_subst(db);
db.impl_self_ty(impl_id)
.substitute(Interner, &substs)
@@ -432,10 +433,7 @@ impl MirEvalError {
.to_string()
}),
ItemContainerId::TraitId(it) => Some(
- db.trait_data(it)
- .name
- .display(db.upcast(), display_target.edition)
- .to_string(),
+ db.trait_signature(it).name.display(db, display_target.edition).to_string(),
),
_ => None,
};
@@ -444,7 +442,7 @@ impl MirEvalError {
"MIR lowering for function `{}{}{}` ({:?}) failed due:",
self_.as_deref().unwrap_or_default(),
if self_.is_some() { "::" } else { "" },
- function_name.name.display(db.upcast(), display_target.edition),
+ function_name.name.display(db, display_target.edition),
func
)?;
err.pretty_print(f, db, span_formatter, display_target)?;
@@ -627,7 +625,7 @@ impl Evaluator<'_> {
assert_placeholder_ty_is_unused: bool,
trait_env: Option<Arc<TraitEnvironment>>,
) -> Result<Evaluator<'_>> {
- let crate_id = owner.module(db.upcast()).krate();
+ let crate_id = owner.module(db).krate();
let target_data_layout = match db.target_data_layout(crate_id) {
Ok(target_data_layout) => target_data_layout,
Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)),
@@ -660,20 +658,18 @@ impl Evaluator<'_> {
cached_fn_trait_func: db
.lang_item(crate_id, LangItem::Fn)
.and_then(|x| x.as_trait())
- .and_then(|x| {
- db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call.clone()))
- }),
+ .and_then(|x| db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call))),
cached_fn_mut_trait_func: db
.lang_item(crate_id, LangItem::FnMut)
.and_then(|x| x.as_trait())
.and_then(|x| {
- db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut.clone()))
+ db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut))
}),
cached_fn_once_trait_func: db
.lang_item(crate_id, LangItem::FnOnce)
.and_then(|x| x.as_trait())
.and_then(|x| {
- db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once.clone()))
+ db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once))
}),
})
}
@@ -820,12 +816,12 @@ impl Evaluator<'_> {
Variants::Multiple { variants, .. } => {
&variants[match f.parent {
hir_def::VariantId::EnumVariantId(it) => {
- RustcEnumVariantIdx(it.lookup(self.db.upcast()).index as usize)
+ RustcEnumVariantIdx(it.lookup(self.db).index as usize)
}
_ => {
return Err(MirEvalError::InternalError(
"mismatched layout".into(),
- ))
+ ));
}
}]
}
@@ -1119,7 +1115,7 @@ impl Evaluator<'_> {
"Stack overflow. Tried to grow stack to {stack_size} bytes"
)));
}
- self.stack.extend(iter::repeat(0).take(stack_size));
+ self.stack.extend(std::iter::repeat_n(0, stack_size));
Ok((locals, prev_stack_pointer))
}
@@ -1641,7 +1637,8 @@ impl Evaluator<'_> {
match &layout.variants {
Variants::Empty => unreachable!(),
Variants::Single { index } => {
- let r = self.const_eval_discriminant(self.db.enum_data(e).variants[index.0].0)?;
+ let r =
+ self.const_eval_discriminant(self.db.enum_variants(e).variants[index.0].0)?;
Ok(r)
}
Variants::Multiple { tag, tag_encoding, variants, .. } => {
@@ -1666,7 +1663,7 @@ impl Evaluator<'_> {
.unwrap_or(*untagged_variant)
.0;
let result =
- self.const_eval_discriminant(self.db.enum_data(e).variants[idx].0)?;
+ self.const_eval_discriminant(self.db.enum_variants(e).variants[idx].0)?;
Ok(result)
}
}
@@ -1760,7 +1757,7 @@ impl Evaluator<'_> {
AdtId::EnumId(_) => not_supported!("unsizing enums"),
};
let Some((last_field, _)) =
- self.db.struct_data(id).variant_data.fields().iter().next_back()
+ self.db.variant_fields(id.into()).fields().iter().next_back()
else {
not_supported!("unsizing struct without field");
};
@@ -1788,11 +1785,11 @@ impl Evaluator<'_> {
subst: Substitution,
locals: &Locals,
) -> Result<(usize, Arc<Layout>, Option<(usize, usize, i128)>)> {
- let adt = it.adt_id(self.db.upcast());
+ let adt = it.adt_id(self.db);
if let DefWithBodyId::VariantId(f) = locals.body.owner {
if let VariantId::EnumVariantId(it) = it {
if let AdtId::EnumId(e) = adt {
- if f.lookup(self.db.upcast()).parent == e {
+ if f.lookup(self.db).parent == e {
// Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
// infinite sized type errors) we use a dummy layout
let i = self.const_eval_discriminant(it)?;
@@ -1810,7 +1807,7 @@ impl Evaluator<'_> {
_ => not_supported!("multi variant layout for non-enums"),
};
let mut discriminant = self.const_eval_discriminant(enum_variant_id)?;
- let lookup = enum_variant_id.lookup(self.db.upcast());
+ let lookup = enum_variant_id.lookup(self.db);
let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize);
let variant_layout = variants[rustc_enum_variant_idx].clone();
let have_tag = match tag_encoding {
@@ -1863,7 +1860,7 @@ impl Evaluator<'_> {
"encoded tag ({offset}, {size}, {value}) is out of bounds 0..{size}"
)
.into(),
- ))
+ ));
}
}
}
@@ -1875,7 +1872,7 @@ impl Evaluator<'_> {
None => {
return Err(MirEvalError::InternalError(
format!("field offset ({offset}) is out of bounds 0..{size}").into(),
- ))
+ ));
}
}
}
@@ -1917,7 +1914,7 @@ impl Evaluator<'_> {
.db
.const_eval(const_id, subst, Some(self.trait_env.clone()))
.map_err(|e| {
- let name = const_id.name(self.db.upcast());
+ let name = const_id.name(self.db);
MirEvalError::ConstEvalError(name, Box::new(e))
})?;
if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value {
@@ -2053,7 +2050,7 @@ impl Evaluator<'_> {
_ => {
return Err(MirEvalError::UndefinedBehavior(format!(
"invalid memory write at address {addr:?}"
- )))
+ )));
}
}
@@ -2068,7 +2065,7 @@ impl Evaluator<'_> {
}
if let DefWithBodyId::VariantId(f) = locals.body.owner {
if let Some((AdtId::EnumId(e), _)) = ty.as_adt() {
- if f.lookup(self.db.upcast()).parent == e {
+ if f.lookup(self.db).parent == e {
// Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
// infinite sized type errors) we use a dummy size
return Ok(Some((16, 16)));
@@ -2121,7 +2118,7 @@ impl Evaluator<'_> {
return Err(MirEvalError::Panic(format!("Memory allocation of {size} bytes failed")));
}
let pos = self.heap.len();
- self.heap.extend(iter::repeat(0).take(size));
+ self.heap.extend(std::iter::repeat_n(0, size));
Ok(Address::Heap(pos))
}
@@ -2242,10 +2239,10 @@ impl Evaluator<'_> {
}
chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
AdtId::StructId(s) => {
- let data = this.db.struct_data(s);
+ let data = this.db.variant_fields(s.into());
let layout = this.layout(ty)?;
let field_types = this.db.field_types(s.into());
- for (f, _) in data.variant_data.fields().iter() {
+ for (f, _) in data.fields().iter() {
let offset = layout
.fields
.offset(u32::from(f.into_raw()) as usize)
@@ -2271,7 +2268,7 @@ impl Evaluator<'_> {
bytes,
e,
) {
- let data = &this.db.enum_variant_data(v).variant_data;
+ let data = &this.db.variant_fields(v.into());
let field_types = this.db.field_types(v.into());
for (f, _) in data.fields().iter() {
let offset =
@@ -2451,7 +2448,7 @@ impl Evaluator<'_> {
let mir_body = self
.db
.monomorphized_mir_body_for_closure(
- closure,
+ closure.into(),
generic_args.clone(),
self.trait_env.clone(),
)
@@ -2558,6 +2555,7 @@ impl Evaluator<'_> {
} else {
let (imp, generic_args) =
self.db.lookup_impl_method(self.trait_env.clone(), def, generic_args.clone());
+
let mir_body = self
.db
.monomorphized_mir_body(imp.into(), generic_args, self.trait_env.clone())
@@ -2616,13 +2614,10 @@ impl Evaluator<'_> {
let ty = ty.clone().cast(Interner);
let generics_for_target = Substitution::from_iter(
Interner,
- generic_args.iter(Interner).enumerate().map(|(i, it)| {
- if i == self_ty_idx {
- &ty
- } else {
- it
- }
- }),
+ generic_args
+ .iter(Interner)
+ .enumerate()
+ .map(|(i, it)| if i == self_ty_idx { &ty } else { it }),
);
self.exec_fn_with_args(
def,
@@ -2756,8 +2751,8 @@ impl Evaluator<'_> {
if let Some(o) = self.static_locations.get(&st) {
return Ok(*o);
};
- let static_data = self.db.static_data(st);
- let result = if !static_data.is_extern {
+ let static_data = self.db.static_signature(st);
+ let result = if !static_data.flags.contains(StaticFlags::EXTERN) {
let konst = self.db.const_eval_static(st).map_err(|e| {
MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e))
})?;
@@ -2781,14 +2776,14 @@ impl Evaluator<'_> {
match r {
Ok(r) => Ok(r),
Err(e) => {
- let db = self.db.upcast();
+ let db = self.db;
let loc = variant.lookup(db);
let enum_loc = loc.parent.lookup(db);
- let edition = self.db.crate_graph()[self.crate_id].edition;
+ let edition = self.crate_id.data(self.db).edition;
let name = format!(
"{}::{}",
- enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast(), edition),
- loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
+ enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db, edition),
+ loc.id.item_tree(db)[loc.id.value].name.display(db, edition),
);
Err(MirEvalError::ConstEvalError(name, Box::new(e)))
}
@@ -2817,7 +2812,7 @@ impl Evaluator<'_> {
) -> Result<()> {
let Some(drop_fn) = (|| {
let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?;
- self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop.clone()))
+ self.db.trait_items(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop))
})() else {
// in some tests we don't have drop trait in minicore, and
// we can ignore drop in them.
@@ -2842,16 +2837,16 @@ impl Evaluator<'_> {
TyKind::Adt(id, subst) => {
match id.0 {
AdtId::StructId(s) => {
- let data = self.db.struct_data(s);
+ let data = self.db.struct_signature(s);
if data.flags.contains(StructFlags::IS_MANUALLY_DROP) {
return Ok(());
}
let layout = self.layout_adt(id.0, subst.clone())?;
- match data.variant_data.as_ref() {
- VariantData::Record { fields, .. }
- | VariantData::Tuple { fields, .. } => {
+ let variant_fields = self.db.variant_fields(s.into());
+ match variant_fields.shape {
+ FieldsShape::Record | FieldsShape::Tuple => {
let field_types = self.db.field_types(s.into());
- for (field, _) in fields.iter() {
+ for (field, _) in variant_fields.fields().iter() {
let offset = layout
.fields
.offset(u32::from(field.into_raw()) as usize)
@@ -2861,7 +2856,7 @@ impl Evaluator<'_> {
self.run_drop_glue_deep(ty, locals, addr, &[], span)?;
}
}
- VariantData::Unit => (),
+ FieldsShape::Unit => (),
}
}
AdtId::UnionId(_) => (), // union fields don't need drop
@@ -2919,15 +2914,15 @@ pub fn render_const_using_debug_impl(
drop_flags: DropFlags::default(),
};
let data = evaluator.allocate_const_in_heap(locals, c)?;
- let resolver = owner.resolver(db.upcast());
+ let resolver = owner.resolver(db);
let Some(TypeNs::TraitId(debug_trait)) = resolver.resolve_path_in_type_ns_fully(
- db.upcast(),
- &hir_def::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]),
+ db,
+ &hir_def::expr_store::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]),
) else {
not_supported!("core::fmt::Debug not found");
};
let Some(debug_fmt_fn) =
- db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt.clone()))
+ db.trait_items(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt))
else {
not_supported!("core::fmt::Debug::fmt not found");
};
@@ -2952,8 +2947,8 @@ pub fn render_const_using_debug_impl(
evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a2.to_bytes())?;
evaluator.write_memory(a3.offset(3 * evaluator.ptr_size()), &[1])?;
let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully(
- db.upcast(),
- &hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
+ db,
+ &hir_def::expr_store::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
HygieneId::ROOT,
) else {
not_supported!("std::fmt::format not found");