diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
commit | 94a0819fe3a0d679c3042a77bfe6a2afc505daea (patch) | |
tree | 2b827afe6a05f3538db3f7803a88c4587fe85648 /src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs | |
parent | Adding upstream version 1.64.0+dfsg1. (diff) | |
download | rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.tar.xz rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.zip |
Adding upstream version 1.66.0+dfsg1.upstream/1.66.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs | 169 |
1 files changed, 97 insertions, 72 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index 66f9c24e8..ccc01c3ef 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -24,13 +24,14 @@ use syntax::{ use crate::{ adt::StructKind, - body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, + body::{Body, BodySourceMap, Expander, ExprPtr, LabelPtr, LabelSource, PatPtr}, body::{BodyDiagnostic, ExprSource, PatSource}, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, db::DefDatabase, expr::{ - dummy_expr_id, Array, BindingAnnotation, Expr, ExprId, FloatTypeWrapper, Label, LabelId, - Literal, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, Statement, + dummy_expr_id, Array, BindingAnnotation, ClosureKind, Expr, ExprId, FloatTypeWrapper, + Label, LabelId, Literal, MatchArm, Movability, Pat, PatId, RecordFieldPat, RecordLitField, + Statement, }, intern::Interned, item_scope::BuiltinShadowMode, @@ -76,7 +77,7 @@ impl<'a> LowerCtx<'a> { pub(super) fn lower( db: &dyn DefDatabase, expander: Expander, - params: Option<ast::ParamList>, + params: Option<(ast::ParamList, impl Iterator<Item = bool>)>, body: Option<ast::Expr>, ) -> (Body, BodySourceMap) { ExprCollector { @@ -97,6 +98,7 @@ pub(super) fn lower( name_to_pat_grouping: Default::default(), is_lowering_inside_or_pat: false, is_lowering_assignee_expr: false, + is_lowering_generator: false, } .collect(params, body) } @@ -111,16 +113,19 @@ struct ExprCollector<'a> { name_to_pat_grouping: FxHashMap<Name, Vec<PatId>>, is_lowering_inside_or_pat: bool, is_lowering_assignee_expr: bool, + is_lowering_generator: bool, } impl ExprCollector<'_> { fn collect( mut self, - param_list: Option<ast::ParamList>, + param_list: Option<(ast::ParamList, impl Iterator<Item = bool>)>, body: Option<ast::Expr>, ) -> (Body, BodySourceMap) { - if let Some(param_list) = param_list { - if let Some(self_param) = param_list.self_param() { + if let Some((param_list, mut attr_enabled)) = param_list { + if let Some(self_param) = + param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false)) + { let ptr = AstPtr::new(&self_param); let param_pat = self.alloc_pat( Pat::Bind { @@ -136,7 +141,11 @@ impl ExprCollector<'_> { self.body.params.push(param_pat); } - for pat in param_list.params().filter_map(|param| param.pat()) { + for pat in param_list + .params() + .zip(attr_enabled) + .filter_map(|(param, enabled)| param.pat().filter(|_| enabled)) + { let param_pat = self.collect_pat(pat); self.body.params.push(param_pat); } @@ -150,21 +159,21 @@ impl ExprCollector<'_> { LowerCtx::new(self.db, self.expander.current_file_id) } - fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { + fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { let src = self.expander.to_source(ptr); - let id = self.make_expr(expr, Ok(src.clone())); + let id = self.make_expr(expr, src.clone()); self.source_map.expr_map.insert(src, id); id } // desugared exprs don't have ptr, that's wrong and should be fixed // somehow. fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId { - self.make_expr(expr, Err(SyntheticSyntax)) + self.body.exprs.alloc(expr) } fn missing_expr(&mut self) -> ExprId { self.alloc_expr_desugared(Expr::Missing) } - fn make_expr(&mut self, expr: Expr, src: Result<ExprSource, SyntheticSyntax>) -> ExprId { + fn make_expr(&mut self, expr: Expr, src: ExprSource) -> ExprId { let id = self.body.exprs.alloc(expr); self.source_map.expr_map_back.insert(id, src); id @@ -172,20 +181,20 @@ impl ExprCollector<'_> { fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let src = self.expander.to_source(ptr); - let id = self.make_pat(pat, Ok(src.clone())); + let id = self.make_pat(pat, src.clone()); self.source_map.pat_map.insert(src, id); id } fn missing_pat(&mut self) -> PatId { - self.make_pat(Pat::Missing, Err(SyntheticSyntax)) + self.body.pats.alloc(Pat::Missing) } - fn make_pat(&mut self, pat: Pat, src: Result<PatSource, SyntheticSyntax>) -> PatId { + fn make_pat(&mut self, pat: Pat, src: PatSource) -> PatId { let id = self.body.pats.alloc(pat); self.source_map.pat_map_back.insert(id, src); id } - fn alloc_label(&mut self, label: Label, ptr: AstPtr<ast::Label>) -> LabelId { + fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId { let src = self.expander.to_source(ptr); let id = self.make_label(label, src.clone()); self.source_map.label_map.insert(src, id); @@ -358,6 +367,7 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::Return { expr }, syntax_ptr) } ast::Expr::YieldExpr(e) => { + self.is_lowering_generator = true; let expr = e.expr().map(|e| self.collect_expr(e)); self.alloc_expr(Expr::Yield { expr }, syntax_ptr) } @@ -459,13 +469,31 @@ impl ExprCollector<'_> { .ret_type() .and_then(|r| r.ty()) .map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it))); + + let prev_is_lowering_generator = self.is_lowering_generator; + self.is_lowering_generator = false; + let body = self.collect_expr_opt(e.body()); + + let closure_kind = if self.is_lowering_generator { + let movability = if e.static_token().is_some() { + Movability::Static + } else { + Movability::Movable + }; + ClosureKind::Generator(movability) + } else { + ClosureKind::Closure + }; + self.is_lowering_generator = prev_is_lowering_generator; + self.alloc_expr( Expr::Closure { args: args.into(), arg_types: arg_types.into(), ret_type, body, + closure_kind, }, syntax_ptr, ) @@ -550,12 +578,6 @@ impl ExprCollector<'_> { None => self.alloc_expr(Expr::Missing, syntax_ptr), } } - ast::Expr::MacroStmts(e) => { - let statements = e.statements().filter_map(|s| self.collect_stmt(s)).collect(); - let tail = e.expr().map(|e| self.collect_expr(e)); - - self.alloc_expr(Expr::MacroStmts { tail, statements }, syntax_ptr) - } ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr), }) } @@ -632,11 +654,46 @@ impl ExprCollector<'_> { } } - fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Statement> { + fn collect_macro_as_stmt( + &mut self, + statements: &mut Vec<Statement>, + mac: ast::MacroExpr, + ) -> Option<ExprId> { + let mac_call = mac.macro_call()?; + let syntax_ptr = AstPtr::new(&ast::Expr::from(mac)); + let macro_ptr = AstPtr::new(&mac_call); + let expansion = self.collect_macro_call( + mac_call, + macro_ptr, + false, + |this, expansion: Option<ast::MacroStmts>| match expansion { + Some(expansion) => { + expansion.statements().for_each(|stmt| this.collect_stmt(statements, stmt)); + expansion.expr().and_then(|expr| match expr { + ast::Expr::MacroExpr(mac) => this.collect_macro_as_stmt(statements, mac), + expr => Some(this.collect_expr(expr)), + }) + } + None => None, + }, + ); + match expansion { + Some(tail) => { + // Make the macro-call point to its expanded expression so we can query + // semantics on syntax pointers to the macro + let src = self.expander.to_source(syntax_ptr); + self.source_map.expr_map.insert(src, tail); + Some(tail) + } + None => None, + } + } + + fn collect_stmt(&mut self, statements: &mut Vec<Statement>, s: ast::Stmt) { match s { ast::Stmt::LetStmt(stmt) => { if self.check_cfg(&stmt).is_none() { - return None; + return; } let pat = self.collect_pat_opt(stmt.pat()); let type_ref = @@ -646,61 +703,26 @@ impl ExprCollector<'_> { .let_else() .and_then(|let_else| let_else.block_expr()) .map(|block| self.collect_block(block)); - Some(Statement::Let { pat, type_ref, initializer, else_branch }) + statements.push(Statement::Let { pat, type_ref, initializer, else_branch }); } ast::Stmt::ExprStmt(stmt) => { let expr = stmt.expr(); - if let Some(expr) = &expr { - if self.check_cfg(expr).is_none() { - return None; - } + match &expr { + Some(expr) if self.check_cfg(expr).is_none() => return, + _ => (), } let has_semi = stmt.semicolon_token().is_some(); // Note that macro could be expanded to multiple statements - if let Some(expr @ ast::Expr::MacroExpr(mac)) = &expr { - let mac_call = mac.macro_call()?; - let syntax_ptr = AstPtr::new(expr); - let macro_ptr = AstPtr::new(&mac_call); - let stmt = self.collect_macro_call( - mac_call, - macro_ptr, - false, - |this, expansion: Option<ast::MacroStmts>| match expansion { - Some(expansion) => { - let statements = expansion - .statements() - .filter_map(|stmt| this.collect_stmt(stmt)) - .collect(); - let tail = expansion.expr().map(|expr| this.collect_expr(expr)); - - let mac_stmts = this.alloc_expr( - Expr::MacroStmts { tail, statements }, - AstPtr::new(&ast::Expr::MacroStmts(expansion)), - ); - - Some(mac_stmts) - } - None => None, - }, - ); - - let expr = match stmt { - Some(expr) => { - // Make the macro-call point to its expanded expression so we can query - // semantics on syntax pointers to the macro - let src = self.expander.to_source(syntax_ptr); - self.source_map.expr_map.insert(src, expr); - expr - } - None => self.alloc_expr(Expr::Missing, syntax_ptr), - }; - Some(Statement::Expr { expr, has_semi }) + if let Some(ast::Expr::MacroExpr(mac)) = expr { + if let Some(expr) = self.collect_macro_as_stmt(statements, mac) { + statements.push(Statement::Expr { expr, has_semi }) + } } else { let expr = self.collect_expr_opt(expr); - Some(Statement::Expr { expr, has_semi }) + statements.push(Statement::Expr { expr, has_semi }); } } - ast::Stmt::Item(_item) => None, + ast::Stmt::Item(_item) => (), } } @@ -721,9 +743,12 @@ impl ExprCollector<'_> { let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); let prev_local_module = mem::replace(&mut self.expander.module, module); - let mut statements: Vec<_> = - block.statements().filter_map(|s| self.collect_stmt(s)).collect(); - let tail = block.tail_expr().and_then(|e| self.maybe_collect_expr(e)); + let mut statements = Vec::new(); + block.statements().for_each(|s| self.collect_stmt(&mut statements, s)); + let tail = block.tail_expr().and_then(|e| match e { + ast::Expr::MacroExpr(mac) => self.collect_macro_as_stmt(&mut statements, mac), + expr => self.maybe_collect_expr(expr), + }); let tail = tail.or_else(|| { let stmt = statements.pop()?; if let Statement::Expr { expr, has_semi: false } = stmt { |