diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-def/src/body')
3 files changed, 24 insertions, 5 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 e8da24e3a..04b1c4f01 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 @@ -10,6 +10,7 @@ use hir_expand::{ name::{name, AsName, Name}, AstId, ExpandError, HirFileId, InFile, }; +use intern::Interned; use la_arena::Arena; use once_cell::unsync::OnceCell; use profile::Count; @@ -33,7 +34,6 @@ use crate::{ Label, LabelId, Literal, MatchArm, Movability, Pat, PatId, RecordFieldPat, RecordLitField, Statement, }, - intern::Interned, item_scope::BuiltinShadowMode, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, @@ -67,9 +67,9 @@ impl<'a> LowerCtx<'a> { Path::from_src(ast, self) } - pub(crate) fn ast_id<N: AstNode>(&self, db: &dyn DefDatabase, item: &N) -> Option<AstId<N>> { + pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> Option<AstId<N>> { let &(file_id, ref ast_id_map) = self.ast_id_map.as_ref()?; - let ast_id_map = ast_id_map.get_or_init(|| db.ast_id_map(file_id)); + let ast_id_map = ast_id_map.get_or_init(|| self.db.ast_id_map(file_id)); Some(InFile::new(file_id, ast_id_map.ast_id(item))) } } @@ -624,6 +624,10 @@ impl ExprCollector<'_> { krate: *krate, }); } + Some(ExpandError::RecursionOverflowPosioned) => { + // Recursion limit has been reached in the macro expansion tree, but not in + // this very macro call. Don't add diagnostics to avoid duplication. + } Some(err) => { self.source_map.diagnostics.push(BodyDiagnostic::MacroError { node: InFile::new(outer_file, syntax_ptr), @@ -636,6 +640,8 @@ impl ExprCollector<'_> { match res.value { Some((mark, expansion)) => { + // Keep collecting even with expansion errors so we can provide completions and + // other services in incomplete macro expressions. self.source_map.expansions.insert(macro_call_ptr, self.expander.current_file_id); let prev_ast_id_map = mem::replace( &mut self.ast_id_map, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs index 10b9b26bb..4b4664a1c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs @@ -80,7 +80,7 @@ impl<'a> Write for Printer<'a> { fn write_str(&mut self, s: &str) -> fmt::Result { for line in s.split_inclusive('\n') { if self.needs_indent { - match self.buf.chars().rev().skip_while(|ch| *ch == ' ').next() { + match self.buf.chars().rev().find(|ch| *ch != ' ') { Some('\n') | None => {} _ => self.buf.push('\n'), } @@ -113,7 +113,7 @@ impl<'a> Printer<'a> { } fn newline(&mut self) { - match self.buf.chars().rev().skip_while(|ch| *ch == ' ').next() { + match self.buf.chars().rev().find(|ch| *ch != ' ') { Some('\n') | None => {} _ => writeln!(self).unwrap(), } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs index c9601f855..edee2c7ff 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs @@ -62,6 +62,19 @@ fn main() { n_nuple!(1,2,3); } } #[test] +fn your_stack_belongs_to_me2() { + cov_mark::check!(overflow_but_not_me); + lower( + r#" +macro_rules! foo { + () => {{ foo!(); foo!(); }} +} +fn main() { foo!(); } +"#, + ); +} + +#[test] fn recursion_limit() { cov_mark::check!(your_stack_belongs_to_me); |