diff options
Diffstat (limited to 'crates/hir_def/src/body.rs')
-rw-r--r-- | crates/hir_def/src/body.rs | 63 |
1 files changed, 21 insertions, 42 deletions
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index d51036e4f..d10b1af01 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -1,6 +1,9 @@ | |||
1 | //! Defines `Body`: a lowered representation of bodies of functions, statics and | 1 | //! Defines `Body`: a lowered representation of bodies of functions, statics and |
2 | //! consts. | 2 | //! consts. |
3 | mod lower; | 3 | mod lower; |
4 | mod diagnostics; | ||
5 | #[cfg(test)] | ||
6 | mod tests; | ||
4 | pub mod scope; | 7 | pub mod scope; |
5 | 8 | ||
6 | use std::{mem, ops::Index, sync::Arc}; | 9 | use std::{mem, ops::Index, sync::Arc}; |
@@ -10,7 +13,10 @@ use base_db::CrateId; | |||
10 | use cfg::CfgOptions; | 13 | use cfg::CfgOptions; |
11 | use drop_bomb::DropBomb; | 14 | use drop_bomb::DropBomb; |
12 | use either::Either; | 15 | use either::Either; |
13 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId}; | 16 | use hir_expand::{ |
17 | ast_id_map::AstIdMap, diagnostics::DiagnosticSink, hygiene::Hygiene, AstId, HirFileId, InFile, | ||
18 | MacroDefId, | ||
19 | }; | ||
14 | use rustc_hash::FxHashMap; | 20 | use rustc_hash::FxHashMap; |
15 | use syntax::{ast, AstNode, AstPtr}; | 21 | use syntax::{ast, AstNode, AstPtr}; |
16 | use test_utils::mark; | 22 | use test_utils::mark; |
@@ -150,8 +156,12 @@ impl Expander { | |||
150 | InFile { file_id: self.current_file_id, value } | 156 | InFile { file_id: self.current_file_id, value } |
151 | } | 157 | } |
152 | 158 | ||
153 | pub(crate) fn is_cfg_enabled(&self, owner: &dyn ast::AttrsOwner) -> bool { | 159 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { |
154 | self.cfg_expander.is_cfg_enabled(owner) | 160 | self.cfg_expander.parse_attrs(owner) |
161 | } | ||
162 | |||
163 | pub(crate) fn cfg_options(&self) -> &CfgOptions { | ||
164 | &self.cfg_expander.cfg_options | ||
155 | } | 165 | } |
156 | 166 | ||
157 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 167 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
@@ -219,6 +229,10 @@ pub struct BodySourceMap { | |||
219 | pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, | 229 | pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, |
220 | field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, | 230 | field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, |
221 | expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, | 231 | expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, |
232 | |||
233 | /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in | ||
234 | /// the source map (since they're just as volatile). | ||
235 | diagnostics: Vec<diagnostics::BodyDiagnostic>, | ||
222 | } | 236 | } |
223 | 237 | ||
224 | #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)] | 238 | #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)] |
@@ -318,45 +332,10 @@ impl BodySourceMap { | |||
318 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> { | 332 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> { |
319 | self.field_map[&(expr, field)].clone() | 333 | self.field_map[&(expr, field)].clone() |
320 | } | 334 | } |
321 | } | ||
322 | |||
323 | #[cfg(test)] | ||
324 | mod tests { | ||
325 | use base_db::{fixture::WithFixture, SourceDatabase}; | ||
326 | use test_utils::mark; | ||
327 | 335 | ||
328 | use crate::ModuleDefId; | 336 | pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) { |
329 | 337 | for diag in &self.diagnostics { | |
330 | use super::*; | 338 | diag.add_to(sink); |
331 | 339 | } | |
332 | fn lower(ra_fixture: &str) -> Arc<Body> { | ||
333 | let (db, file_id) = crate::test_db::TestDB::with_single_file(ra_fixture); | ||
334 | |||
335 | let krate = db.crate_graph().iter().next().unwrap(); | ||
336 | let def_map = db.crate_def_map(krate); | ||
337 | let module = def_map.modules_for_file(file_id).next().unwrap(); | ||
338 | let module = &def_map[module]; | ||
339 | let fn_def = match module.scope.declarations().next().unwrap() { | ||
340 | ModuleDefId::FunctionId(it) => it, | ||
341 | _ => panic!(), | ||
342 | }; | ||
343 | |||
344 | db.body(fn_def.into()) | ||
345 | } | ||
346 | |||
347 | #[test] | ||
348 | fn your_stack_belongs_to_me() { | ||
349 | mark::check!(your_stack_belongs_to_me); | ||
350 | lower( | ||
351 | " | ||
352 | macro_rules! n_nuple { | ||
353 | ($e:tt) => (); | ||
354 | ($($rest:tt)*) => {{ | ||
355 | (n_nuple!($($rest)*)None,) | ||
356 | }}; | ||
357 | } | ||
358 | fn main() { n_nuple!(1,2,3); } | ||
359 | ", | ||
360 | ); | ||
361 | } | 340 | } |
362 | } | 341 | } |