]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/body.rs
parameters.split_last()
[rust.git] / crates / hir_def / src / body.rs
index 0eff093beb4bdd639d7e79638bac733c5ebb87d2..8488b4f0d03ff5fe1c4cadf978fbbf920ab96a2d 100644 (file)
@@ -12,7 +12,8 @@
 use drop_bomb::DropBomb;
 use either::Either;
 use hir_expand::{
-    ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandResult, HirFileId, InFile, MacroDefId,
+    ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandError, ExpandResult, HirFileId, InFile,
+    MacroCallId, MacroDefId,
 };
 use la_arena::{Arena, ArenaMap};
 use limit::Limit;
@@ -53,12 +54,6 @@ pub struct Expander {
     recursion_limit: usize,
 }
 
-#[cfg(test)]
-const EXPANSION_RECURSION_LIMIT: Limit = Limit::new(32);
-
-#[cfg(not(test))]
-const EXPANSION_RECURSION_LIMIT: Limit = Limit::new(128);
-
 impl CfgExpander {
     pub(crate) fn new(
         db: &dyn DefDatabase,
@@ -100,7 +95,7 @@ pub fn enter_expand<T: ast::AstNode>(
         db: &dyn DefDatabase,
         macro_call: ast::MacroCall,
     ) -> Result<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> {
-        if EXPANSION_RECURSION_LIMIT.check(self.recursion_limit + 1).is_err() {
+        if self.recursion_limit(db).check(self.recursion_limit + 1).is_err() {
             cov_mark::hit!(your_stack_belongs_to_me);
             return Ok(ExpandResult::str_err(
                 "reached recursion limit during macro expansion".into(),
@@ -124,6 +119,23 @@ pub fn enter_expand<T: ast::AstNode>(
             }
         };
 
+        Ok(self.enter_expand_inner(db, call_id, err))
+    }
+
+    pub fn enter_expand_id<T: ast::AstNode>(
+        &mut self,
+        db: &dyn DefDatabase,
+        call_id: MacroCallId,
+    ) -> ExpandResult<Option<(Mark, T)>> {
+        self.enter_expand_inner(db, call_id, None)
+    }
+
+    fn enter_expand_inner<T: ast::AstNode>(
+        &mut self,
+        db: &dyn DefDatabase,
+        call_id: MacroCallId,
+        mut err: Option<ExpandError>,
+    ) -> ExpandResult<Option<(Mark, T)>> {
         if err.is_none() {
             err = db.macro_expand_error(call_id);
         }
@@ -138,9 +150,9 @@ pub fn enter_expand<T: ast::AstNode>(
                     tracing::warn!("no error despite `parse_or_expand` failing");
                 }
 
-                return Ok(ExpandResult::only_err(err.unwrap_or_else(|| {
+                return ExpandResult::only_err(err.unwrap_or_else(|| {
                     mbe::ExpandError::Other("failed to parse macro invocation".into())
-                })));
+                }));
             }
         };
 
@@ -148,7 +160,7 @@ pub fn enter_expand<T: ast::AstNode>(
             Some(it) => it,
             None => {
                 // This can happen without being an error, so only forward previous errors.
-                return Ok(ExpandResult { value: None, err });
+                return ExpandResult { value: None, err };
             }
         };
 
@@ -164,7 +176,7 @@ pub fn enter_expand<T: ast::AstNode>(
         self.current_file_id = file_id;
         self.ast_id_map = db.ast_id_map(file_id);
 
-        Ok(ExpandResult { value: Some((mark, node)), err })
+        ExpandResult { value: Some((mark, node)), err }
     }
 
     pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
@@ -204,6 +216,17 @@ fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> {
         let file_local_id = self.ast_id_map.ast_id(item);
         AstId::new(self.current_file_id, file_local_id)
     }
+
+    fn recursion_limit(&self, db: &dyn DefDatabase) -> Limit {
+        let limit = db.crate_limits(self.cfg_expander.krate).recursion_limit as _;
+
+        #[cfg(not(test))]
+        return Limit::new(limit);
+
+        // Without this, `body::tests::your_stack_belongs_to_me` stack-overflows in debug
+        #[cfg(test)]
+        return Limit::new(std::cmp::min(32, limit));
+    }
 }
 
 #[derive(Debug)]