diff options
author | Aleksey Kladov <[email protected]> | 2021-05-04 20:03:16 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-05-04 20:41:43 +0100 |
commit | 95dc8ef265183a624593a5ef49df31e53daf160e (patch) | |
tree | 33300902005a3496602849a72fecfc350f61a2ed /crates/hir_expand/src/db.rs | |
parent | 7d9ea39de6d59fe59e628ef72983315e944412dc (diff) |
make illegal states unrepresentable
only declarative macros have def-site token map
Diffstat (limited to 'crates/hir_expand/src/db.rs')
-rw-r--r-- | crates/hir_expand/src/db.rs | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 5ea41ba78..935c547b0 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -28,9 +28,9 @@ const TOKEN_LIMIT: usize = 524288; | |||
28 | #[derive(Debug, Clone, Eq, PartialEq)] | 28 | #[derive(Debug, Clone, Eq, PartialEq)] |
29 | pub enum TokenExpander { | 29 | pub enum TokenExpander { |
30 | /// Old-style `macro_rules`. | 30 | /// Old-style `macro_rules`. |
31 | MacroRules(mbe::MacroRules), | 31 | MacroRules { mac: mbe::MacroRules, def_site_token_map: mbe::TokenMap }, |
32 | /// AKA macros 2.0. | 32 | /// AKA macros 2.0. |
33 | MacroDef(mbe::MacroDef), | 33 | MacroDef { mac: mbe::MacroDef, def_site_token_map: mbe::TokenMap }, |
34 | /// Stuff like `line!` and `file!`. | 34 | /// Stuff like `line!` and `file!`. |
35 | Builtin(BuiltinFnLikeExpander), | 35 | Builtin(BuiltinFnLikeExpander), |
36 | /// `derive(Copy)` and such. | 36 | /// `derive(Copy)` and such. |
@@ -47,8 +47,8 @@ impl TokenExpander { | |||
47 | tt: &tt::Subtree, | 47 | tt: &tt::Subtree, |
48 | ) -> mbe::ExpandResult<tt::Subtree> { | 48 | ) -> mbe::ExpandResult<tt::Subtree> { |
49 | match self { | 49 | match self { |
50 | TokenExpander::MacroRules(it) => it.expand(tt), | 50 | TokenExpander::MacroRules { mac, .. } => mac.expand(tt), |
51 | TokenExpander::MacroDef(it) => it.expand(tt), | 51 | TokenExpander::MacroDef { mac, .. } => mac.expand(tt), |
52 | TokenExpander::Builtin(it) => it.expand(db, id, tt), | 52 | TokenExpander::Builtin(it) => it.expand(db, id, tt), |
53 | // FIXME switch these to ExpandResult as well | 53 | // FIXME switch these to ExpandResult as well |
54 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), | 54 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), |
@@ -63,21 +63,21 @@ impl TokenExpander { | |||
63 | 63 | ||
64 | pub(crate) fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId { | 64 | pub(crate) fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId { |
65 | match self { | 65 | match self { |
66 | TokenExpander::MacroRules(it) => it.map_id_down(id), | 66 | TokenExpander::MacroRules { mac, .. } => mac.map_id_down(id), |
67 | TokenExpander::MacroDef(it) => it.map_id_down(id), | 67 | TokenExpander::MacroDef { mac, .. } => mac.map_id_down(id), |
68 | TokenExpander::Builtin(..) => id, | 68 | TokenExpander::Builtin(..) |
69 | TokenExpander::BuiltinDerive(..) => id, | 69 | | TokenExpander::BuiltinDerive(..) |
70 | TokenExpander::ProcMacro(..) => id, | 70 | | TokenExpander::ProcMacro(..) => id, |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | pub(crate) fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, mbe::Origin) { | 74 | pub(crate) fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, mbe::Origin) { |
75 | match self { | 75 | match self { |
76 | TokenExpander::MacroRules(it) => it.map_id_up(id), | 76 | TokenExpander::MacroRules { mac, .. } => mac.map_id_up(id), |
77 | TokenExpander::MacroDef(it) => it.map_id_up(id), | 77 | TokenExpander::MacroDef { mac, .. } => mac.map_id_up(id), |
78 | TokenExpander::Builtin(..) => (id, mbe::Origin::Call), | 78 | TokenExpander::Builtin(..) |
79 | TokenExpander::BuiltinDerive(..) => (id, mbe::Origin::Call), | 79 | | TokenExpander::BuiltinDerive(..) |
80 | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), | 80 | | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), |
81 | } | 81 | } |
82 | } | 82 | } |
83 | } | 83 | } |
@@ -102,7 +102,7 @@ pub trait AstDatabase: SourceDatabase { | |||
102 | #[salsa::transparent] | 102 | #[salsa::transparent] |
103 | fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; | 103 | fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; |
104 | fn macro_arg_text(&self, id: MacroCallId) -> Option<GreenNode>; | 104 | fn macro_arg_text(&self, id: MacroCallId) -> Option<GreenNode>; |
105 | fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>; | 105 | fn macro_def(&self, id: MacroDefId) -> Option<Arc<TokenExpander>>; |
106 | 106 | ||
107 | fn macro_expand(&self, macro_call: MacroCallId) -> ExpandResult<Option<Arc<tt::Subtree>>>; | 107 | fn macro_expand(&self, macro_call: MacroCallId) -> ExpandResult<Option<Arc<tt::Subtree>>>; |
108 | fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>; | 108 | fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>; |
@@ -133,7 +133,7 @@ pub fn expand_hypothetical( | |||
133 | macro_expand_with_arg(db, macro_file.macro_call_id, Some(Arc::new((tt, tmap_1)))); | 133 | macro_expand_with_arg(db, macro_file.macro_call_id, Some(Arc::new((tt, tmap_1)))); |
134 | let (node, tmap_2) = expansion_to_syntax(db, macro_file, hypothetical_expansion).value?; | 134 | let (node, tmap_2) = expansion_to_syntax(db, macro_file, hypothetical_expansion).value?; |
135 | 135 | ||
136 | let token_id = macro_def.0.map_id_down(token_id); | 136 | let token_id = macro_def.map_id_down(token_id); |
137 | let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; | 137 | let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; |
138 | let token = node.syntax_node().covering_element(range).into_token()?; | 138 | let token = node.syntax_node().covering_element(range).into_token()?; |
139 | Some((node.syntax_node(), token)) | 139 | Some((node.syntax_node(), token)) |
@@ -262,13 +262,13 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> { | |||
262 | Some(arg.green()) | 262 | Some(arg.green()) |
263 | } | 263 | } |
264 | 264 | ||
265 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | 265 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<TokenExpander>> { |
266 | match id.kind { | 266 | match id.kind { |
267 | MacroDefKind::Declarative(ast_id) => match ast_id.to_node(db) { | 267 | MacroDefKind::Declarative(ast_id) => match ast_id.to_node(db) { |
268 | ast::Macro::MacroRules(macro_rules) => { | 268 | ast::Macro::MacroRules(macro_rules) => { |
269 | let arg = macro_rules.token_tree()?; | 269 | let arg = macro_rules.token_tree()?; |
270 | let (tt, tmap) = mbe::ast_to_token_tree(&arg); | 270 | let (tt, def_site_token_map) = mbe::ast_to_token_tree(&arg); |
271 | let rules = match mbe::MacroRules::parse(&tt) { | 271 | let mac = match mbe::MacroRules::parse(&tt) { |
272 | Ok(it) => it, | 272 | Ok(it) => it, |
273 | Err(err) => { | 273 | Err(err) => { |
274 | let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default(); | 274 | let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default(); |
@@ -276,12 +276,12 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, | |||
276 | return None; | 276 | return None; |
277 | } | 277 | } |
278 | }; | 278 | }; |
279 | Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) | 279 | Some(Arc::new(TokenExpander::MacroRules { mac, def_site_token_map })) |
280 | } | 280 | } |
281 | ast::Macro::MacroDef(macro_def) => { | 281 | ast::Macro::MacroDef(macro_def) => { |
282 | let arg = macro_def.body()?; | 282 | let arg = macro_def.body()?; |
283 | let (tt, tmap) = mbe::ast_to_token_tree(&arg); | 283 | let (tt, def_site_token_map) = mbe::ast_to_token_tree(&arg); |
284 | let rules = match mbe::MacroDef::parse(&tt) { | 284 | let mac = match mbe::MacroDef::parse(&tt) { |
285 | Ok(it) => it, | 285 | Ok(it) => it, |
286 | Err(err) => { | 286 | Err(err) => { |
287 | let name = macro_def.name().map(|n| n.to_string()).unwrap_or_default(); | 287 | let name = macro_def.name().map(|n| n.to_string()).unwrap_or_default(); |
@@ -289,19 +289,15 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, | |||
289 | return None; | 289 | return None; |
290 | } | 290 | } |
291 | }; | 291 | }; |
292 | Some(Arc::new((TokenExpander::MacroDef(rules), tmap))) | 292 | Some(Arc::new(TokenExpander::MacroDef { mac, def_site_token_map })) |
293 | } | 293 | } |
294 | }, | 294 | }, |
295 | MacroDefKind::BuiltIn(expander, _) => { | 295 | MacroDefKind::BuiltIn(expander, _) => Some(Arc::new(TokenExpander::Builtin(expander))), |
296 | Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default()))) | ||
297 | } | ||
298 | MacroDefKind::BuiltInDerive(expander, _) => { | 296 | MacroDefKind::BuiltInDerive(expander, _) => { |
299 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) | 297 | Some(Arc::new(TokenExpander::BuiltinDerive(expander))) |
300 | } | 298 | } |
301 | MacroDefKind::BuiltInEager(..) => None, | 299 | MacroDefKind::BuiltInEager(..) => None, |
302 | MacroDefKind::ProcMacro(expander, ..) => { | 300 | MacroDefKind::ProcMacro(expander, ..) => Some(Arc::new(TokenExpander::ProcMacro(expander))), |
303 | Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default()))) | ||
304 | } | ||
305 | } | 301 | } |
306 | } | 302 | } |
307 | 303 | ||
@@ -313,7 +309,7 @@ fn macro_expand_error(db: &dyn AstDatabase, macro_call: MacroCallId) -> Option<E | |||
313 | db.macro_expand(macro_call).err | 309 | db.macro_expand(macro_call).err |
314 | } | 310 | } |
315 | 311 | ||
316 | fn expander(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | 312 | fn expander(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<TokenExpander>> { |
317 | let lazy_id = match id { | 313 | let lazy_id = match id { |
318 | MacroCallId::LazyMacro(id) => id, | 314 | MacroCallId::LazyMacro(id) => id, |
319 | MacroCallId::EagerMacro(_id) => { | 315 | MacroCallId::EagerMacro(_id) => { |
@@ -359,7 +355,7 @@ fn macro_expand_with_arg( | |||
359 | Some(it) => it, | 355 | Some(it) => it, |
360 | None => return ExpandResult::str_err("Fail to find macro definition".into()), | 356 | None => return ExpandResult::str_err("Fail to find macro definition".into()), |
361 | }; | 357 | }; |
362 | let ExpandResult { value: tt, err } = macro_rules.0.expand(db, lazy_id, ¯o_arg.0); | 358 | let ExpandResult { value: tt, err } = macro_rules.expand(db, lazy_id, ¯o_arg.0); |
363 | // Set a hard limit for the expanded tt | 359 | // Set a hard limit for the expanded tt |
364 | let count = tt.count(); | 360 | let count = tt.count(); |
365 | if count > TOKEN_LIMIT { | 361 | if count > TOKEN_LIMIT { |