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.rs | 151 |
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"); |