Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/lower.rs')
| -rw-r--r-- | crates/hir-ty/src/mir/lower.rs | 281 |
1 files changed, 136 insertions, 145 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 520717e799..557027756f 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -2,21 +2,19 @@ use std::{fmt::Write, iter, mem}; -use base_db::{ra_salsa::Cycle, CrateId}; +use base_db::Crate; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ - data::adt::{StructKind, VariantData}, - expr_store::{Body, HygieneId}, + AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId, + Lookup, TraitId, TupleId, TypeOrConstParamId, + expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{ ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, }, + item_tree::FieldsShape, lang_item::{LangItem, LangItemTarget}, - path::Path, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, - type_ref::TypesMap, - AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId, - Lookup, TraitId, TupleId, TypeOrConstParamId, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -27,27 +25,27 @@ use syntax::TextRange; use triomphe::Arc; use crate::{ + Adjust, Adjustment, AutoBorrow, CallableDefId, TyBuilder, TyExt, consteval::ConstEvalError, - db::{HirDatabase, InternedClosure}, - display::{hir_display_with_types_map, DisplayTarget, HirDisplay}, + db::{HirDatabase, InternedClosure, InternedClosureId}, + display::{DisplayTarget, HirDisplay, hir_display_with_store}, error_lifetime, generics::generics, - infer::{cast::CastTy, unify::InferenceTable, CaptureKind, CapturedItem, TypeMismatch}, + infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy, unify::InferenceTable}, inhabitedness::is_ty_uninhabited_from, layout::LayoutError, mapping::ToChalk, mir::{ - intern_const_scalar, return_slot, AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, - BorrowKind, CastKind, ClosureId, ConstScalar, Either, Expr, FieldId, Idx, InferenceResult, - Interner, Local, LocalId, MemoryMap, MirBody, MirSpan, Mutability, Operand, Place, - PlaceElem, PointerCast, ProjectionElem, ProjectionStore, RawIdx, Rvalue, Statement, - StatementKind, Substitution, SwitchTargets, Terminator, TerminatorKind, TupleFieldId, Ty, - UnOp, VariantId, + AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, ConstScalar, + Either, Expr, FieldId, Idx, InferenceResult, Interner, Local, LocalId, MemoryMap, MirBody, + MirSpan, Mutability, Operand, Place, PlaceElem, PointerCast, ProjectionElem, + ProjectionStore, RawIdx, Rvalue, Statement, StatementKind, Substitution, SwitchTargets, + Terminator, TerminatorKind, TupleFieldId, Ty, UnOp, VariantId, intern_const_scalar, + return_slot, }, static_lifetime, traits::FnTrait, utils::ClosureSubst, - Adjust, Adjustment, AutoBorrow, CallableDefId, TyBuilder, TyExt, }; mod as_place; @@ -179,7 +177,7 @@ impl MirLowerError { writeln!( f, "Missing function definition for {}", - body.pretty_print_expr(db.upcast(), *owner, *it, display_target.edition) + body.pretty_print_expr(db, *owner, *it, display_target.edition) )?; } MirLowerError::HasErrors => writeln!(f, "Type inference result contains errors")?, @@ -195,10 +193,7 @@ impl MirLowerError { writeln!( f, "Generic arg not provided for {}", - param - .name() - .unwrap_or(&Name::missing()) - .display(db.upcast(), display_target.edition) + param.name().unwrap_or(&Name::missing()).display(db, display_target.edition) )?; writeln!(f, "Provided args: [")?; for g in subst.iter(Interner) { @@ -255,10 +250,10 @@ impl MirLowerError { db: &dyn HirDatabase, p: &Path, display_target: DisplayTarget, - types_map: &TypesMap, + store: &ExpressionStore, ) -> Self { Self::UnresolvedName( - hir_display_with_types_map(p, types_map).display(db, display_target).to_string(), + hir_display_with_store(p, store).display(db, display_target).to_string(), ) } } @@ -290,7 +285,7 @@ impl<'ctx> MirLowerCtx<'ctx> { owner, closures: vec![], }; - let resolver = owner.resolver(db.upcast()); + let resolver = owner.resolver(db); MirLowerCtx { result: mir, @@ -415,63 +410,62 @@ impl<'ctx> MirLowerCtx<'ctx> { } Expr::Missing => { if let DefWithBodyId::FunctionId(f) = self.owner { - let assoc = f.lookup(self.db.upcast()); + let assoc = f.lookup(self.db); if let ItemContainerId::TraitId(t) = assoc.container { - let name = &self.db.function_data(f).name; + let name = &self.db.function_signature(f).name; return Err(MirLowerError::TraitFunctionDefinition(t, name.clone())); } } Err(MirLowerError::IncompleteExpr) } Expr::Path(p) => { - let pr = if let Some((assoc, subst)) = - self.infer.assoc_resolutions_for_expr(expr_id) - { - match assoc { - hir_def::AssocItemId::ConstId(c) => { - self.lower_const( - c.into(), - current, - place, - subst, - expr_id.into(), - self.expr_ty_without_adjust(expr_id), - )?; - return Ok(Some(current)); - } - hir_def::AssocItemId::FunctionId(_) => { - // FnDefs are zero sized, no action is needed. - return Ok(Some(current)); + let pr = + if let Some((assoc, subst)) = self.infer.assoc_resolutions_for_expr(expr_id) { + match assoc { + hir_def::AssocItemId::ConstId(c) => { + self.lower_const( + c.into(), + current, + place, + subst, + expr_id.into(), + self.expr_ty_without_adjust(expr_id), + )?; + return Ok(Some(current)); + } + hir_def::AssocItemId::FunctionId(_) => { + // FnDefs are zero sized, no action is needed. + return Ok(Some(current)); + } + hir_def::AssocItemId::TypeAliasId(_) => { + // FIXME: If it is unreachable, use proper error instead of `not_supported`. + not_supported!("associated functions and types") + } } - hir_def::AssocItemId::TypeAliasId(_) => { - // FIXME: If it is unreachable, use proper error instead of `not_supported`. - not_supported!("associated functions and types") + } else if let Some(variant) = self.infer.variant_resolution_for_expr(expr_id) { + match variant { + VariantId::EnumVariantId(e) => ValueNs::EnumVariantId(e), + VariantId::StructId(s) => ValueNs::StructId(s), + VariantId::UnionId(_) => implementation_error!("Union variant as path"), } - } - } else if let Some(variant) = self.infer.variant_resolution_for_expr(expr_id) { - match variant { - VariantId::EnumVariantId(e) => ValueNs::EnumVariantId(e), - VariantId::StructId(s) => ValueNs::StructId(s), - VariantId::UnionId(_) => implementation_error!("Union variant as path"), - } - } else { - let resolver_guard = - self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr_id); - let hygiene = self.body.expr_path_hygiene(expr_id); - let result = self - .resolver - .resolve_path_in_value_ns_fully(self.db.upcast(), p, hygiene) - .ok_or_else(|| { - MirLowerError::unresolved_path( - self.db, - p, - DisplayTarget::from_crate(self.db, self.krate()), - &self.body.types, - ) - })?; - self.resolver.reset_to_guard(resolver_guard); - result - }; + } else { + let resolver_guard = + self.resolver.update_to_inner_scope(self.db, self.owner, expr_id); + let hygiene = self.body.expr_path_hygiene(expr_id); + let result = self + .resolver + .resolve_path_in_value_ns_fully(self.db, p, hygiene) + .ok_or_else(|| { + MirLowerError::unresolved_path( + self.db, + p, + DisplayTarget::from_crate(self.db, self.krate()), + self.body, + ) + })?; + self.resolver.reset_to_guard(resolver_guard); + result + }; match pr { ValueNs::LocalBinding(_) | ValueNs::StaticId(_) => { let Some((temp, current)) = @@ -499,8 +493,8 @@ impl<'ctx> MirLowerCtx<'ctx> { Ok(Some(current)) } ValueNs::EnumVariantId(variant_id) => { - let variant_data = &self.db.enum_variant_data(variant_id).variant_data; - if variant_data.kind() == StructKind::Unit { + let variant_fields = &self.db.variant_fields(variant_id.into()); + if variant_fields.shape == FieldsShape::Unit { let ty = self.infer.type_of_expr[expr_id].clone(); current = self.lower_enum_variant( variant_id, @@ -515,10 +509,10 @@ impl<'ctx> MirLowerCtx<'ctx> { Ok(Some(current)) } ValueNs::GenericParam(p) => { - let Some(def) = self.owner.as_generic_def_id(self.db.upcast()) else { + let Some(def) = self.owner.as_generic_def_id(self.db) else { not_supported!("owner without generic def id"); }; - let gen = generics(self.db.upcast(), def); + let generics = generics(self.db, def); let ty = self.expr_ty_without_adjust(expr_id); self.push_assignment( current, @@ -528,7 +522,7 @@ impl<'ctx> MirLowerCtx<'ctx> { ty, value: chalk_ir::ConstValue::BoundVar(BoundVar::new( DebruijnIndex::INNERMOST, - gen.type_or_const_param_idx(p.into()).ok_or( + generics.type_or_const_param_idx(p.into()).ok_or( MirLowerError::TypeError( "fail to lower const generic param", ), @@ -579,7 +573,7 @@ impl<'ctx> MirLowerCtx<'ctx> { }; self.push_fake_read(current, cond_place, expr_id.into()); let resolver_guard = - self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr_id); + self.resolver.update_to_inner_scope(self.db, self.owner, expr_id); let (then_target, else_target) = self.pattern_match(current, None, cond_place, *pat)?; self.resolver.reset_to_guard(resolver_guard); @@ -695,7 +689,7 @@ impl<'ctx> MirLowerCtx<'ctx> { let (func_id, generic_args) = self.infer.method_resolution(expr_id).ok_or_else(|| { MirLowerError::UnresolvedMethod( - method_name.display(self.db.upcast(), self.edition()).to_string(), + method_name.display(self.db, self.edition()).to_string(), ) })?; let func = Operand::from_fn(self.db, func_id, generic_args); @@ -717,7 +711,7 @@ impl<'ctx> MirLowerCtx<'ctx> { self.push_fake_read(current, cond_place, expr_id.into()); let mut end = None; let resolver_guard = - self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr_id); + self.resolver.update_to_inner_scope(self.db, self.owner, expr_id); for MatchArm { pat, guard, expr } in arms.iter() { let (then, mut otherwise) = self.pattern_match(current, None, cond_place, *pat)?; @@ -840,7 +834,7 @@ impl<'ctx> MirLowerCtx<'ctx> { let variant_id = self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path { Some(p) => MirLowerError::UnresolvedName( - hir_display_with_types_map(&**p, &self.body.types) + hir_display_with_store(&**p, self.body) .display(self.db, self.display_target()) .to_string(), ), @@ -850,13 +844,13 @@ impl<'ctx> MirLowerCtx<'ctx> { TyKind::Adt(_, s) => s.clone(), _ => not_supported!("Non ADT record literal"), }; - let variant_data = variant_id.variant_data(self.db.upcast()); + let variant_fields = self.db.variant_fields(variant_id); match variant_id { VariantId::EnumVariantId(_) | VariantId::StructId(_) => { - let mut operands = vec![None; variant_data.fields().len()]; + let mut operands = vec![None; variant_fields.fields().len()]; for RecordLitField { name, expr } in fields.iter() { let field_id = - variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?; + variant_fields.field(name).ok_or(MirLowerError::UnresolvedField)?; let Some((op, c)) = self.lower_expr_to_some_operand(*expr, current)? else { return Ok(None); @@ -899,7 +893,7 @@ impl<'ctx> MirLowerCtx<'ctx> { not_supported!("Union record literal with more than one field"); }; let local_id = - variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?; + variant_fields.field(name).ok_or(MirLowerError::UnresolvedField)?; let place = place.project( PlaceElem::Field(Either::Left(FieldId { parent: union_id.into(), @@ -914,17 +908,18 @@ impl<'ctx> MirLowerCtx<'ctx> { Expr::Await { .. } => not_supported!("await"), Expr::Yeet { .. } => not_supported!("yeet"), Expr::Async { .. } => not_supported!("async block"), - &Expr::Const(id) => { - let subst = self.placeholder_subst(); - self.lower_const( - id.into(), - current, - place, - subst, - expr_id.into(), - self.expr_ty_without_adjust(expr_id), - )?; - Ok(Some(current)) + &Expr::Const(_) => { + // let subst = self.placeholder_subst(); + // self.lower_const( + // id.into(), + // current, + // place, + // subst, + // expr_id.into(), + // self.expr_ty_without_adjust(expr_id), + // )?; + // Ok(Some(current)) + not_supported!("const block") } Expr::Cast { expr, type_ref: _ } => { let Some((it, current)) = self.lower_expr_to_some_operand(*expr, current)? else { @@ -1130,7 +1125,7 @@ impl<'ctx> MirLowerCtx<'ctx> { }; self.push_fake_read(current, value, expr_id.into()); let resolver_guard = - self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr_id); + self.resolver.update_to_inner_scope(self.db, self.owner, expr_id); current = self.pattern_match_assignment(current, value, target)?; self.resolver.reset_to_guard(resolver_guard); Ok(Some(current)) @@ -1165,8 +1160,7 @@ impl<'ctx> MirLowerCtx<'ctx> { Rvalue::Aggregate( AggregateKind::Adt(st.into(), subst.clone()), self.db - .struct_data(st) - .variant_data + .variant_fields(st.into()) .fields() .iter() .map(|it| { @@ -1279,7 +1273,7 @@ impl<'ctx> MirLowerCtx<'ctx> { _ => { return Err(MirLowerError::TypeError( "Array expression with non array type", - )) + )); } }; let Some(values) = elements @@ -1311,7 +1305,7 @@ impl<'ctx> MirLowerCtx<'ctx> { _ => { return Err(MirLowerError::TypeError( "Array repeat expression with non array type", - )) + )); } }; let r = Rvalue::Repeat(init, len); @@ -1330,7 +1324,7 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn placeholder_subst(&mut self) -> Substitution { - match self.owner.as_generic_def_id(self.db.upcast()) { + match self.owner.as_generic_def_id(self.db) { Some(it) => TyBuilder::placeholder_subst(self.db, it), None => Substitution::empty(Interner), } @@ -1371,13 +1365,13 @@ impl<'ctx> MirLowerCtx<'ctx> { MirLowerError::unresolved_path( self.db, c, - DisplayTarget::from_crate(db, owner.krate(db.upcast())), - &self.body.types, + DisplayTarget::from_crate(db, owner.krate(db)), + self.body, ) }; let pr = self .resolver - .resolve_path_in_value_ns(self.db.upcast(), c, HygieneId::ROOT) + .resolve_path_in_value_ns(self.db, c, HygieneId::ROOT) .ok_or_else(unresolved_name)?; match pr { ResolveValueResult::ValueNs(v, _) => { @@ -1442,7 +1436,7 @@ impl<'ctx> MirLowerCtx<'ctx> { _ => { return Err(MirLowerError::TypeError( "float with size other than 2, 4, 8 or 16 bytes", - )) + )); } }, }; @@ -1477,7 +1471,7 @@ impl<'ctx> MirLowerCtx<'ctx> { // We can't evaluate constant with substitution now, as generics are not monomorphized in lowering. intern_const_scalar(ConstScalar::UnevaluatedConst(const_id, subst), ty) } else { - let name = const_id.name(self.db.upcast()); + let name = const_id.name(self.db); self.db .const_eval(const_id, subst, None) .map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))? @@ -1636,10 +1630,12 @@ impl<'ctx> MirLowerCtx<'ctx> { f: impl FnOnce(&mut MirLowerCtx<'_>, BasicBlockId) -> Result<()>, ) -> Result<Option<BasicBlockId>> { let begin = self.new_basic_block(); - let prev = mem::replace( - &mut self.current_loop_blocks, - Some(LoopBlocks { begin, end: None, place, drop_scope_index: self.drop_scopes.len() }), - ); + let prev = self.current_loop_blocks.replace(LoopBlocks { + begin, + end: None, + place, + drop_scope_index: self.drop_scopes.len(), + }); let prev_label = if let Some(label) = label { // We should generate the end now, to make sure that it wouldn't change later. It is // bad as we may emit end (unnecessary unreachable block) for unterminating loop, but @@ -1708,7 +1704,7 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn is_uninhabited(&self, expr_id: ExprId) -> bool { - is_ty_uninhabited_from(self.db, &self.infer[expr_id], self.owner.module(self.db.upcast())) + is_ty_uninhabited_from(self.db, &self.infer[expr_id], self.owner.module(self.db)) } /// This function push `StorageLive` statement for the binding, and applies changes to add `StorageDead` and @@ -1730,7 +1726,7 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn resolve_lang_item(&self, item: LangItem) -> Result<LangItemTarget> { - let crate_id = self.owner.module(self.db.upcast()).krate(); + let crate_id = self.owner.module(self.db).krate(); self.db.lang_item(crate_id, item).ok_or(MirLowerError::LangItemNotFound(item)) } @@ -1758,11 +1754,8 @@ impl<'ctx> MirLowerCtx<'ctx> { self.push_fake_read(current, init_place, span); // Using the initializer for the resolver scope is good enough for us, as it cannot create new declarations // and has all declarations of the `let`. - let resolver_guard = self.resolver.update_to_inner_scope( - self.db.upcast(), - self.owner, - *expr_id, - ); + let resolver_guard = + self.resolver.update_to_inner_scope(self.db, self.owner, *expr_id); (current, else_block) = self.pattern_match(current, None, init_place, *pat)?; self.resolver.reset_to_guard(resolver_guard); @@ -1906,13 +1899,13 @@ impl<'ctx> MirLowerCtx<'ctx> { Ok(r) => Ok(r), Err(e) => { let edition = self.edition(); - let db = self.db.upcast(); + let db = self.db; let loc = variant.lookup(db); let enum_loc = loc.parent.lookup(db); 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(MirLowerError::ConstEvalError(name.into(), Box::new(e))) } @@ -1920,11 +1913,11 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn edition(&self) -> Edition { - self.db.crate_graph()[self.krate()].edition + self.krate().data(self.db).edition } - fn krate(&self) -> CrateId { - self.owner.krate(self.db.upcast()) + fn krate(&self) -> Crate { + self.owner.krate(self.db) } fn display_target(&self) -> DisplayTarget { @@ -2016,9 +2009,9 @@ fn cast_kind(table: &mut InferenceTable<'_>, source_ty: &Ty, target_ty: &Ty) -> pub fn mir_body_for_closure_query( db: &dyn HirDatabase, - closure: ClosureId, + closure: InternedClosureId, ) -> Result<Arc<MirBody>> { - let InternedClosure(owner, expr) = db.lookup_intern_closure(closure.into()); + let InternedClosure(owner, expr) = db.lookup_intern_closure(closure); let body = db.body(owner); let infer = db.infer(owner); let Expr::Closure { args, body: root, .. } = &body[expr] else { @@ -2027,7 +2020,7 @@ pub fn mir_body_for_closure_query( let TyKind::Closure(_, substs) = &infer[expr].kind(Interner) else { implementation_error!("closure expression is not closure"); }; - let (captures, kind) = infer.closure_info(&closure); + let (captures, kind) = infer.closure_info(&closure.into()); let mut ctx = MirLowerCtx::new(db, owner, &body, &infer); // 0 is return local ctx.result.locals.alloc(Local { ty: infer[*root].clone() }); @@ -2046,7 +2039,7 @@ pub fn mir_body_for_closure_query( let Some(sig) = ClosureSubst(substs).sig_ty().callable_sig(db) else { implementation_error!("closure has not callable sig"); }; - let resolver_guard = ctx.resolver.update_to_inner_scope(db.upcast(), owner, expr); + let resolver_guard = ctx.resolver.update_to_inner_scope(db, owner, expr); let current = ctx.lower_params_and_bindings( args.iter().zip(sig.params().iter()).map(|(it, y)| (*it, y.clone())), None, @@ -2120,26 +2113,29 @@ pub fn mir_body_for_closure_query( } pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<MirBody>> { - let krate = def.krate(db.upcast()); - let edition = db.crate_graph()[krate].edition; + let krate = def.krate(db); + let edition = krate.data(db).edition; let detail = match def { DefWithBodyId::FunctionId(it) => { - db.function_data(it).name.display(db.upcast(), edition).to_string() + db.function_signature(it).name.display(db, edition).to_string() } DefWithBodyId::StaticId(it) => { - db.static_data(it).name.display(db.upcast(), edition).to_string() + db.static_signature(it).name.display(db, edition).to_string() } DefWithBodyId::ConstId(it) => db - .const_data(it) + .const_signature(it) .name .clone() .unwrap_or_else(Name::missing) - .display(db.upcast(), edition) + .display(db, edition) .to_string(), DefWithBodyId::VariantId(it) => { - db.enum_variant_data(it).name.display(db.upcast(), edition).to_string() + let loc = it.lookup(db); + db.enum_variants(loc.parent).variants[loc.index as usize] + .1 + .display(db, edition) + .to_string() } - DefWithBodyId::InTypeConstId(it) => format!("in type const {it:?}"), }; let _p = tracing::info_span!("mir_body_query", ?detail).entered(); let body = db.body(def); @@ -2149,10 +2145,9 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi Ok(Arc::new(result)) } -pub fn mir_body_recover( +pub(crate) fn mir_body_cycle_result( _db: &dyn HirDatabase, - _cycle: &Cycle, - _def: &DefWithBodyId, + _def: DefWithBodyId, ) -> Result<Arc<MirBody>> { Err(MirLowerError::Loop) } @@ -2174,11 +2169,7 @@ pub fn lower_to_mir( ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr) }); let binding_picker = |b: BindingId| { let owner = ctx.body.binding_owners.get(&b).copied(); - if root_expr == body.body_expr { - owner.is_none() - } else { - owner == Some(root_expr) - } + if root_expr == body.body_expr { owner.is_none() } else { owner == Some(root_expr) } }; // 1 to param_len is for params // FIXME: replace with let chain once it becomes stable |