Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/body/lower.rs')
-rw-r--r--crates/hir-def/src/body/lower.rs72
1 files changed, 37 insertions, 35 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 7b88e525bf..b375ec63a6 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -11,7 +11,6 @@ use hir_expand::{
AstId, ExpandError, InFile,
};
use intern::Interned;
-use la_arena::Arena;
use profile::Count;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
@@ -40,7 +39,7 @@ use crate::{
nameres::{DefMap, MacroSubNs},
path::{GenericArgs, Path},
type_ref::{Mutability, Rawness, TypeRef},
- AdtId, BlockId, BlockLoc, DefWithBodyId, ModuleDefId, UnresolvedMacro,
+ AdtId, BlockId, BlockLoc, ConstBlockLoc, DefWithBodyId, ModuleDefId, UnresolvedMacro,
};
pub(super) fn lower(
@@ -60,10 +59,11 @@ pub(super) fn lower(
source_map: BodySourceMap::default(),
ast_id_map: db.ast_id_map(expander.current_file_id),
body: Body {
- exprs: Arena::default(),
- pats: Arena::default(),
- bindings: Arena::default(),
- labels: Arena::default(),
+ exprs: Default::default(),
+ pats: Default::default(),
+ bindings: Default::default(),
+ binding_owners: Default::default(),
+ labels: Default::default(),
params: Vec::new(),
body_expr: dummy_expr_id(),
block_scopes: Vec::new(),
@@ -188,7 +188,7 @@ impl ExprCollector<'_> {
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
{
let ptr = AstPtr::new(&self_param);
- let binding_id = self.alloc_binding(
+ let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
name![self],
BindingAnnotation::new(
self_param.mut_token().is_some() && self_param.amp_token().is_none(),
@@ -297,7 +297,10 @@ impl ExprCollector<'_> {
let (result_expr_id, prev_binding_owner) =
this.initialize_binding_owner(syntax_ptr);
let inner_expr = this.collect_block(e);
- let x = this.db.intern_anonymous_const((this.owner, inner_expr));
+ let x = this.db.intern_anonymous_const(ConstBlockLoc {
+ parent: this.owner,
+ root: inner_expr,
+ });
this.body.exprs[result_expr_id] = Expr::Const(x);
this.current_binding_owner = prev_binding_owner;
result_expr_id
@@ -742,16 +745,14 @@ impl ExprCollector<'_> {
/// }
/// ```
fn collect_for_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::ForExpr) -> ExprId {
- let (into_iter_fn, iter_next_fn, option_some, option_none) = 'if_chain: {
- if let Some(into_iter_fn) = LangItem::IntoIterIntoIter.path(self.db, self.krate) {
- if let Some(iter_next_fn) = LangItem::IteratorNext.path(self.db, self.krate) {
- if let Some(option_some) = LangItem::OptionSome.path(self.db, self.krate) {
- if let Some(option_none) = LangItem::OptionNone.path(self.db, self.krate) {
- break 'if_chain (into_iter_fn, iter_next_fn, option_some, option_none);
- }
- }
- }
- }
+ let Some((into_iter_fn, iter_next_fn, option_some, option_none)) = (|| {
+ Some((
+ LangItem::IntoIterIntoIter.path(self.db, self.krate)?,
+ LangItem::IteratorNext.path(self.db, self.krate)?,
+ LangItem::OptionSome.path(self.db, self.krate)?,
+ LangItem::OptionNone.path(self.db, self.krate)?,
+ ))
+ })() else {
// Some of the needed lang items are missing, so we can't desugar
return self.alloc_expr(Expr::Missing, syntax_ptr);
};
@@ -784,8 +785,8 @@ impl ExprCollector<'_> {
}),
};
let iter_name = Name::generate_new_name();
- let iter_binding = self.alloc_binding(iter_name.clone(), BindingAnnotation::Mutable);
- let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name)), syntax_ptr.clone());
+ let iter_expr =
+ self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr.clone());
let iter_expr_mut = self.alloc_expr(
Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut },
syntax_ptr.clone(),
@@ -805,7 +806,9 @@ impl ExprCollector<'_> {
);
let loop_outer =
self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr.clone());
+ let iter_binding = self.alloc_binding(iter_name, BindingAnnotation::Mutable);
let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None });
+ self.add_definition_to_binding(iter_binding, iter_pat);
self.alloc_expr(
Expr::Match {
expr: iterator,
@@ -827,18 +830,14 @@ impl ExprCollector<'_> {
/// }
/// ```
fn collect_try_operator(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::TryExpr) -> ExprId {
- let (try_branch, cf_continue, cf_break, try_from_residual) = 'if_chain: {
- if let Some(try_branch) = LangItem::TryTraitBranch.path(self.db, self.krate) {
- if let Some(cf_continue) = LangItem::ControlFlowContinue.path(self.db, self.krate) {
- if let Some(cf_break) = LangItem::ControlFlowBreak.path(self.db, self.krate) {
- if let Some(try_from_residual) =
- LangItem::TryTraitFromResidual.path(self.db, self.krate)
- {
- break 'if_chain (try_branch, cf_continue, cf_break, try_from_residual);
- }
- }
- }
- }
+ let Some((try_branch, cf_continue, cf_break, try_from_residual)) = (|| {
+ Some((
+ LangItem::TryTraitBranch.path(self.db, self.krate)?,
+ LangItem::ControlFlowContinue.path(self.db, self.krate)?,
+ LangItem::ControlFlowBreak.path(self.db, self.krate)?,
+ LangItem::TryTraitFromResidual.path(self.db, self.krate)?,
+ ))
+ })() else {
// Some of the needed lang items are missing, so we can't desugar
return self.alloc_expr(Expr::Missing, syntax_ptr);
};
@@ -1541,13 +1540,16 @@ impl ExprCollector<'_> {
}
fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
- self.body.bindings.alloc(Binding {
+ let binding = self.body.bindings.alloc(Binding {
name,
mode,
definitions: SmallVec::new(),
- owner: self.current_binding_owner,
problems: None,
- })
+ });
+ if let Some(owner) = self.current_binding_owner {
+ self.body.binding_owners.insert(binding, owner);
+ }
+ binding
}
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {