mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 14:03:35 +00:00
Auto merge of #15075 - Veykril:bindings, r=Veykril
fix: Add binding definition for for-expr iterator desugared binding
This commit is contained in:
commit
5dccf3010b
3 changed files with 42 additions and 35 deletions
|
@ -188,7 +188,7 @@ impl ExprCollector<'_> {
|
||||||
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
|
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
|
||||||
{
|
{
|
||||||
let ptr = AstPtr::new(&self_param);
|
let ptr = AstPtr::new(&self_param);
|
||||||
let binding_id = self.alloc_binding(
|
let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
|
||||||
name![self],
|
name![self],
|
||||||
BindingAnnotation::new(
|
BindingAnnotation::new(
|
||||||
self_param.mut_token().is_some() && self_param.amp_token().is_none(),
|
self_param.mut_token().is_some() && self_param.amp_token().is_none(),
|
||||||
|
@ -745,16 +745,14 @@ impl ExprCollector<'_> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
fn collect_for_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::ForExpr) -> ExprId {
|
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: {
|
let Some((into_iter_fn, iter_next_fn, option_some, option_none)) = (|| {
|
||||||
if let Some(into_iter_fn) = LangItem::IntoIterIntoIter.path(self.db, self.krate) {
|
Some((
|
||||||
if let Some(iter_next_fn) = LangItem::IteratorNext.path(self.db, self.krate) {
|
LangItem::IntoIterIntoIter.path(self.db, self.krate)?,
|
||||||
if let Some(option_some) = LangItem::OptionSome.path(self.db, self.krate) {
|
LangItem::IteratorNext.path(self.db, self.krate)?,
|
||||||
if let Some(option_none) = LangItem::OptionNone.path(self.db, self.krate) {
|
LangItem::OptionSome.path(self.db, self.krate)?,
|
||||||
break 'if_chain (into_iter_fn, iter_next_fn, option_some, option_none);
|
LangItem::OptionNone.path(self.db, self.krate)?,
|
||||||
}
|
))
|
||||||
}
|
})() else {
|
||||||
}
|
|
||||||
}
|
|
||||||
// Some of the needed lang items are missing, so we can't desugar
|
// Some of the needed lang items are missing, so we can't desugar
|
||||||
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
||||||
};
|
};
|
||||||
|
@ -787,8 +785,8 @@ impl ExprCollector<'_> {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
let iter_name = Name::generate_new_name();
|
let iter_name = Name::generate_new_name();
|
||||||
let iter_binding = self.alloc_binding(iter_name.clone(), BindingAnnotation::Mutable);
|
let iter_expr =
|
||||||
let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name)), syntax_ptr.clone());
|
self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr.clone());
|
||||||
let iter_expr_mut = self.alloc_expr(
|
let iter_expr_mut = self.alloc_expr(
|
||||||
Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut },
|
Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut },
|
||||||
syntax_ptr.clone(),
|
syntax_ptr.clone(),
|
||||||
|
@ -808,7 +806,9 @@ impl ExprCollector<'_> {
|
||||||
);
|
);
|
||||||
let loop_outer =
|
let loop_outer =
|
||||||
self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr.clone());
|
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 });
|
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(
|
self.alloc_expr(
|
||||||
Expr::Match {
|
Expr::Match {
|
||||||
expr: iterator,
|
expr: iterator,
|
||||||
|
@ -830,18 +830,14 @@ impl ExprCollector<'_> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
fn collect_try_operator(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::TryExpr) -> ExprId {
|
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: {
|
let Some((try_branch, cf_continue, cf_break, try_from_residual)) = (|| {
|
||||||
if let Some(try_branch) = LangItem::TryTraitBranch.path(self.db, self.krate) {
|
Some((
|
||||||
if let Some(cf_continue) = LangItem::ControlFlowContinue.path(self.db, self.krate) {
|
LangItem::TryTraitBranch.path(self.db, self.krate)?,
|
||||||
if let Some(cf_break) = LangItem::ControlFlowBreak.path(self.db, self.krate) {
|
LangItem::ControlFlowContinue.path(self.db, self.krate)?,
|
||||||
if let Some(try_from_residual) =
|
LangItem::ControlFlowBreak.path(self.db, self.krate)?,
|
||||||
LangItem::TryTraitFromResidual.path(self.db, self.krate)
|
LangItem::TryTraitFromResidual.path(self.db, self.krate)?,
|
||||||
{
|
))
|
||||||
break 'if_chain (try_branch, cf_continue, cf_break, try_from_residual);
|
})() else {
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Some of the needed lang items are missing, so we can't desugar
|
// Some of the needed lang items are missing, so we can't desugar
|
||||||
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2800,6 +2800,22 @@ impl Local {
|
||||||
/// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = x;`
|
/// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = x;`
|
||||||
pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> {
|
pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> {
|
||||||
let (body, source_map) = db.body_with_source_map(self.parent);
|
let (body, source_map) = db.body_with_source_map(self.parent);
|
||||||
|
self.sources_(db, &body, &source_map).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = x;`
|
||||||
|
pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource {
|
||||||
|
let (body, source_map) = db.body_with_source_map(self.parent);
|
||||||
|
let src = self.sources_(db, &body, &source_map).next().unwrap();
|
||||||
|
src
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sources_<'a>(
|
||||||
|
self,
|
||||||
|
db: &'a dyn HirDatabase,
|
||||||
|
body: &'a hir_def::body::Body,
|
||||||
|
source_map: &'a hir_def::body::BodySourceMap,
|
||||||
|
) -> impl Iterator<Item = LocalSource> + 'a {
|
||||||
body[self.binding_id]
|
body[self.binding_id]
|
||||||
.definitions
|
.definitions
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -2812,14 +2828,7 @@ impl Local {
|
||||||
Either::Right(it) => Either::Right(it.to_node(&root)),
|
Either::Right(it) => Either::Right(it.to_node(&root)),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map(|source| LocalSource { local: self, source })
|
.map(move |source| LocalSource { local: self, source })
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = x;`
|
|
||||||
pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource {
|
|
||||||
let all_sources = self.sources(db);
|
|
||||||
all_sources.into_iter().next().unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,9 +165,11 @@ impl flags::AnalysisStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eprintln!(
|
eprintln!(
|
||||||
", mods: {}, decls: {num_decls}, bodies: {}",
|
", mods: {}, decls: {num_decls}, bodies: {}, adts: {}, consts: {}",
|
||||||
visited_modules.len(),
|
visited_modules.len(),
|
||||||
bodies.len()
|
bodies.len(),
|
||||||
|
adts.len(),
|
||||||
|
consts.len(),
|
||||||
);
|
);
|
||||||
eprintln!("{:<20} {}", "Item Collection:", analysis_sw.elapsed());
|
eprintln!("{:<20} {}", "Item Collection:", analysis_sw.elapsed());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue