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 | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 73ae5eaeef..e89e16079d 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -16,7 +16,7 @@ use hir_def::{ use la_arena::ArenaMap; use crate::{ - consteval::ConstEvalError, db::HirDatabase, infer::TypeMismatch, + consteval::ConstEvalError, db::HirDatabase, display::HirDisplay, infer::TypeMismatch, inhabitedness::is_ty_uninhabited_from, layout::layout_of_ty, mapping::ToChalk, utils::generics, Adjust, AutoBorrow, CallableDefId, TyBuilder, TyExt, }; @@ -46,6 +46,7 @@ pub enum MirLowerError { LayoutError(LayoutError), IncompleteExpr, UnresolvedName(String), + RecordLiteralWithoutPath, UnresolvedMethod, UnresolvedField, MissingFunctionDefinition, @@ -88,7 +89,7 @@ impl MirLowerCtx<'_> { if matches!(ty.kind(Interner), TyKind::Slice(_) | TyKind::Dyn(_)) { not_supported!("unsized temporaries"); } - Ok(self.result.locals.alloc(Local { mutability: Mutability::Not, ty })) + Ok(self.result.locals.alloc(Local { ty })) } fn lower_expr_as_place(&self, expr_id: ExprId) -> Option<Place> { @@ -251,7 +252,7 @@ impl MirLowerCtx<'_> { match &self.body.exprs[expr_id] { Expr::Missing => Err(MirLowerError::IncompleteExpr), Expr::Path(p) => { - let unresolved_name = || MirLowerError::UnresolvedName("".to_string()); + let unresolved_name = || MirLowerError::UnresolvedName(p.display(self.db).to_string()); let resolver = resolver_for_expr(self.db.upcast(), self.owner, expr_id); let pr = resolver .resolve_path_in_value_ns(self.db.upcast(), p.mod_path()) @@ -259,19 +260,29 @@ impl MirLowerCtx<'_> { let pr = match pr { ResolveValueResult::ValueNs(v) => v, ResolveValueResult::Partial(..) => { - return match self + if let Some(assoc) = self .infer .assoc_resolutions_for_expr(expr_id) - .ok_or_else(unresolved_name)? - .0 - //.ok_or(ConstEvalError::SemanticError("unresolved assoc item"))? { - hir_def::AssocItemId::ConstId(c) => { - self.lower_const(c, current, place, expr_id.into())?; - Ok(Some(current)) - }, - _ => return Err(unresolved_name()), - }; + match assoc.0 { + hir_def::AssocItemId::ConstId(c) => { + self.lower_const(c, current, place, expr_id.into())?; + return Ok(Some(current)) + }, + _ => 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(_) => return Err(MirLowerError::ImplementationError("Union variant as path")), + } + } else { + return Err(unresolved_name()); + } } }; match pr { @@ -597,11 +608,14 @@ impl MirLowerCtx<'_> { Ok(None) } Expr::Yield { .. } => not_supported!("yield"), - Expr::RecordLit { fields, .. } => { + Expr::RecordLit { fields, path, .. } => { let variant_id = self .infer .variant_resolution_for_expr(expr_id) - .ok_or_else(|| MirLowerError::UnresolvedName("".to_string()))?; + .ok_or_else(|| match path { + Some(p) => MirLowerError::UnresolvedName(p.display(self.db).to_string()), + None => MirLowerError::RecordLiteralWithoutPath, + })?; let subst = match self.expr_ty(expr_id).kind(Interner) { TyKind::Adt(_, s) => s.clone(), _ => not_supported!("Non ADT record literal"), @@ -1437,17 +1451,17 @@ pub fn lower_to_mir( basic_blocks.alloc(BasicBlock { statements: vec![], terminator: None, is_cleanup: false }); let mut locals = Arena::new(); // 0 is return local - locals.alloc(Local { mutability: Mutability::Mut, ty: infer[root_expr].clone() }); + locals.alloc(Local { ty: infer[root_expr].clone() }); let mut binding_locals: ArenaMap<BindingId, LocalId> = ArenaMap::new(); - let param_locals: ArenaMap<PatId, LocalId> = if let DefWithBodyId::FunctionId(fid) = owner { + // 1 to param_len is for params + let param_locals: Vec<LocalId> = if let DefWithBodyId::FunctionId(fid) = owner { let substs = TyBuilder::placeholder_subst(db, fid); let callable_sig = db.callable_item_signature(fid.into()).substitute(Interner, &substs); - // 1 to param_len is for params body.params .iter() .zip(callable_sig.params().iter()) .map(|(&x, ty)| { - let local_id = locals.alloc(Local { mutability: Mutability::Not, ty: ty.clone() }); + let local_id = locals.alloc(Local { ty: ty.clone() }); if let Pat::Bind { id, subpat: None } = body[x] { if matches!( body.bindings[id].mode, @@ -1456,22 +1470,19 @@ pub fn lower_to_mir( binding_locals.insert(id, local_id); } } - (x, local_id) + local_id }) .collect() } else { if !body.params.is_empty() { return Err(MirLowerError::TypeError("Unexpected parameter for non function body")); } - ArenaMap::new() + vec![] }; // and then rest of bindings for (id, _) in body.bindings.iter() { if !binding_locals.contains_idx(id) { - binding_locals.insert( - id, - locals.alloc(Local { mutability: Mutability::Not, ty: infer[id].clone() }), - ); + binding_locals.insert(id, locals.alloc(Local { ty: infer[id].clone() })); } } let mir = MirBody { @@ -1479,6 +1490,7 @@ pub fn lower_to_mir( locals, start_block, binding_locals, + param_locals, owner, arg_count: body.params.len(), }; @@ -1492,17 +1504,17 @@ pub fn lower_to_mir( discr_temp: None, }; let mut current = start_block; - for ¶m in &body.params { + for (¶m, local) in body.params.iter().zip(ctx.result.param_locals.clone().into_iter()) { if let Pat::Bind { id, .. } = body[param] { - if param_locals[param] == ctx.result.binding_locals[id] { + if local == ctx.result.binding_locals[id] { continue; } } let r = ctx.pattern_match( current, None, - param_locals[param].into(), - ctx.result.locals[param_locals[param]].ty.clone(), + local.into(), + ctx.result.locals[local].ty.clone(), param, BindingAnnotation::Unannotated, )?; |