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 | 83 |
1 files changed, 31 insertions, 52 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 6499c703a8..4359a1acb5 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -5,11 +5,11 @@ use std::{fmt::Write, iter, mem}; use base_db::Crate; use hir_def::{ AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, GenericParamId, HasModule, - ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId, + ItemContainerId, LocalFieldId, Lookup, TraitId, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{ ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ClosureKind, ExprId, ExprOrPatId, - LabelId, Literal, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread, + LabelId, Literal, MatchArm, Pat, PatId, RecordLitField, RecordSpread, generics::GenericParams, }, item_tree::FieldsShape, @@ -19,7 +19,7 @@ use hir_def::{ }; use hir_expand::name::Name; use itertools::{EitherOrBoth, Itertools}; -use la_arena::ArenaMap; +use la_arena::{ArenaMap, RawIdx}; use rustc_apfloat::Float; use rustc_hash::FxHashMap; use rustc_type_ir::inherent::{Const as _, GenericArgs as _, IntoKind, Ty as _}; @@ -43,11 +43,11 @@ use crate::{ layout::LayoutError, method_resolution::CandidateId, mir::{ - AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, Either, Expr, - FieldId, GenericArgs, Idx, InferenceResult, Local, LocalId, MemoryMap, MirBody, MirSpan, - Mutability, Operand, Place, PlaceElem, PointerCast, Projection, ProjectionElem, RawIdx, - Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, TupleFieldId, - Ty, UnOp, VariantId, return_slot, + AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, Expr, + FieldIndex, GenericArgs, Idx, InferenceResult, Local, LocalId, MemoryMap, MirBody, MirSpan, + Mutability, Operand, Place, PlaceElem, PointerCast, Projection, ProjectionElem, Rvalue, + Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, Ty, UnOp, VariantId, + return_slot, }, next_solver::{ Const, DbInterner, ParamConst, ParamEnv, Region, StoredGenericArgs, StoredTy, TyKind, @@ -919,20 +919,15 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { let rvalue = Rvalue::Aggregate( AggregateKind::Adt(variant_id, subst.store()), match spread_place { - Some(sp) => operands + Some(sp) if let VariantId::StructId(_) = variant_id => operands .into_iter() .enumerate() .map(|(i, it)| match it { Some(it) => it, None => { - let p = sp.project(ProjectionElem::Field( - Either::Left(FieldId { - parent: variant_id, - local_id: LocalFieldId::from_raw(RawIdx::from( - i as u32, - )), - }), - )); + let p = sp.project(ProjectionElem::Field(FieldIndex( + i as u32, + ))); Operand { kind: OperandKind::Copy(p.store()), span: None, @@ -940,6 +935,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } }) .collect(), + Some(_) => { + return Err(MirLowerError::TypeError( + "functional record update syntax requires a struct", + )); + } None => operands.into_iter().collect::<Option<_>>().ok_or( MirLowerError::TypeError("missing field in record literal"), )?, @@ -948,16 +948,13 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { self.push_assignment(current, place, rvalue, expr_id.into()); Ok(Some(current)) } - VariantId::UnionId(union_id) => { + VariantId::UnionId(_union_id) => { let [RecordLitField { name, expr }] = fields.as_ref() else { not_supported!("Union record literal with more than one field"); }; let local_id = variant_fields.field(name).ok_or(MirLowerError::UnresolvedField)?; - let place = place.project(PlaceElem::Field(Either::Left(FieldId { - parent: union_id.into(), - local_id, - }))); + let place = place.project(PlaceElem::Field(local_id.into())); self.lower_expr_to_place(*expr, place, current) } } @@ -1411,13 +1408,13 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { let index = name.as_tuple_index().ok_or(MirLowerError::TypeError("named field on tuple"))? as u32; - *place = place.project(ProjectionElem::Field(Either::Right(TupleFieldId { - tuple: TupleId(!0), // dummy as its unused - index, - }))) + *place = place.project(ProjectionElem::Field(FieldIndex(index))) } else { - let field = - self.infer.field_resolution(expr_id).ok_or(MirLowerError::UnresolvedField)?; + let field = self + .infer + .field_resolution(expr_id) + .ok_or(MirLowerError::UnresolvedField)? + .either(|f| f.local_id.into(), |t| FieldIndex(t.index)); *place = place.project(ProjectionElem::Field(field)); } } else { @@ -2087,35 +2084,18 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } fn convert_closure_capture_projections( - db: &dyn HirDatabase, + _db: &dyn HirDatabase, place: &HirPlace, ) -> impl Iterator<Item = PlaceElem> { place.projections.iter().enumerate().map(|(i, proj)| match proj.kind { HirProjectionKind::Deref => ProjectionElem::Deref, - HirProjectionKind::Field { field_idx, variant_idx } => { + HirProjectionKind::Field { field_idx, variant_idx: _ } => { let ty = place.ty_before_projection(i); match ty.kind() { - TyKind::Tuple(_) => { - ProjectionElem::Field(Either::Right(TupleFieldId { - tuple: TupleId(!0), // Dummy as it's unused - index: field_idx, - })) - } - TyKind::Adt(adt_def, _) => { + TyKind::Tuple(_) => ProjectionElem::Field(FieldIndex(field_idx)), + TyKind::Adt(_, _) => { let local_field_id = LocalFieldId::from_raw(RawIdx::from_u32(field_idx)); - let field = match adt_def.def_id() { - AdtId::StructId(id) => { - FieldId { parent: id.into(), local_id: local_field_id } - } - AdtId::UnionId(id) => { - FieldId { parent: id.into(), local_id: local_field_id } - } - AdtId::EnumId(id) => { - let variant = id.enum_variants(db).variants[variant_idx as usize].0; - FieldId { parent: variant.into(), local_id: local_field_id } - } - }; - ProjectionElem::Field(Either::Left(field)) + ProjectionElem::Field(local_field_id.into()) } _ => panic!("unexpected type"), } @@ -2208,7 +2188,7 @@ pub fn mir_body_for_closure_query<'db>( if is_by_ref_closure { projections.push(ProjectionElem::Deref); } - projections.push(ProjectionElem::ClosureField(capture_idx)); + projections.push(ProjectionElem::Field(FieldIndex(capture_idx as u32))); let capture_param_place = Place { local: closure_local, projection: Projection::new_from_slice(&projections).store(), @@ -2240,7 +2220,6 @@ pub fn mir_body_for_closure_query<'db>( let current = ctx.pop_drop_scope_assert_finished(current, root.into())?; ctx.set_terminator(current, TerminatorKind::Return, (*root).into()); } - let mut err = None; ctx.result.walk_places(|mir_place| { let mir_projections = mir_place.projection.lookup(); |