diff options
Diffstat (limited to 'crates/hir_def/src/body.rs')
-rw-r--r-- | crates/hir_def/src/body.rs | 69 |
1 files changed, 25 insertions, 44 deletions
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 9a9a605dd..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; |
@@ -105,14 +111,16 @@ impl Expander { | |||
105 | 111 | ||
106 | let macro_call = InFile::new(self.current_file_id, ¯o_call); | 112 | let macro_call = InFile::new(self.current_file_id, ¯o_call); |
107 | 113 | ||
108 | if let Some(call_id) = macro_call.as_call_id(db, self.crate_def_map.krate, |path| { | 114 | let resolver = |path: ModPath| -> Option<MacroDefId> { |
109 | if let Some(local_scope) = local_scope { | 115 | if let Some(local_scope) = local_scope { |
110 | if let Some(def) = path.as_ident().and_then(|n| local_scope.get_legacy_macro(n)) { | 116 | if let Some(def) = path.as_ident().and_then(|n| local_scope.get_legacy_macro(n)) { |
111 | return Some(def); | 117 | return Some(def); |
112 | } | 118 | } |
113 | } | 119 | } |
114 | self.resolve_path_as_macro(db, &path) | 120 | self.resolve_path_as_macro(db, &path) |
115 | }) { | 121 | }; |
122 | |||
123 | if let Some(call_id) = macro_call.as_call_id(db, self.crate_def_map.krate, resolver) { | ||
116 | let file_id = call_id.as_file(); | 124 | let file_id = call_id.as_file(); |
117 | if let Some(node) = db.parse_or_expand(file_id) { | 125 | if let Some(node) = db.parse_or_expand(file_id) { |
118 | if let Some(expr) = T::cast(node) { | 126 | if let Some(expr) = T::cast(node) { |
@@ -148,8 +156,12 @@ impl Expander { | |||
148 | InFile { file_id: self.current_file_id, value } | 156 | InFile { file_id: self.current_file_id, value } |
149 | } | 157 | } |
150 | 158 | ||
151 | pub(crate) fn is_cfg_enabled(&self, owner: &dyn ast::AttrsOwner) -> bool { | 159 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { |
152 | 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 | ||
153 | } | 165 | } |
154 | 166 | ||
155 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 167 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
@@ -217,6 +229,10 @@ pub struct BodySourceMap { | |||
217 | pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, | 229 | pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, |
218 | field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, | 230 | field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, |
219 | 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>, | ||
220 | } | 236 | } |
221 | 237 | ||
222 | #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)] | 238 | #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)] |
@@ -316,45 +332,10 @@ impl BodySourceMap { | |||
316 | 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>> { |
317 | self.field_map[&(expr, field)].clone() | 333 | self.field_map[&(expr, field)].clone() |
318 | } | 334 | } |
319 | } | ||
320 | 335 | ||
321 | #[cfg(test)] | 336 | pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) { |
322 | mod tests { | 337 | for diag in &self.diagnostics { |
323 | use base_db::{fixture::WithFixture, SourceDatabase}; | 338 | diag.add_to(sink); |
324 | use test_utils::mark; | 339 | } |
325 | |||
326 | use crate::ModuleDefId; | ||
327 | |||
328 | use super::*; | ||
329 | |||
330 | fn lower(ra_fixture: &str) -> Arc<Body> { | ||
331 | let (db, file_id) = crate::test_db::TestDB::with_single_file(ra_fixture); | ||
332 | |||
333 | let krate = db.crate_graph().iter().next().unwrap(); | ||
334 | let def_map = db.crate_def_map(krate); | ||
335 | let module = def_map.modules_for_file(file_id).next().unwrap(); | ||
336 | let module = &def_map[module]; | ||
337 | let fn_def = match module.scope.declarations().next().unwrap() { | ||
338 | ModuleDefId::FunctionId(it) => it, | ||
339 | _ => panic!(), | ||
340 | }; | ||
341 | |||
342 | db.body(fn_def.into()) | ||
343 | } | ||
344 | |||
345 | #[test] | ||
346 | fn your_stack_belongs_to_me() { | ||
347 | mark::check!(your_stack_belongs_to_me); | ||
348 | lower( | ||
349 | " | ||
350 | macro_rules! n_nuple { | ||
351 | ($e:tt) => (); | ||
352 | ($($rest:tt)*) => {{ | ||
353 | (n_nuple!($($rest)*)None,) | ||
354 | }}; | ||
355 | } | ||
356 | fn main() { n_nuple!(1,2,3); } | ||
357 | ", | ||
358 | ); | ||
359 | } | 340 | } |
360 | } | 341 | } |