mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-03 05:13:35 +00:00
Report unresolved idents for implicit captures in format_args!()
And also a bit of cleanup by storing the capture's span with the open quote included.
This commit is contained in:
parent
27e824fad4
commit
54ce1dda3a
7 changed files with 110 additions and 63 deletions
|
|
@ -18,6 +18,7 @@ use smallvec::SmallVec;
|
|||
use span::{Edition, MacroFileId};
|
||||
use syntax::{ast, AstPtr, SyntaxNodePtr};
|
||||
use triomphe::Arc;
|
||||
use tt::TextRange;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
|
|
@ -143,15 +144,7 @@ pub struct BodySourceMap {
|
|||
|
||||
pub types: TypesSourceMap,
|
||||
|
||||
// FIXME: Make this a sane struct.
|
||||
template_map: Option<
|
||||
Box<(
|
||||
// format_args!
|
||||
FxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>,
|
||||
// asm!
|
||||
FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>,
|
||||
)>,
|
||||
>,
|
||||
template_map: Option<Box<FormatTemplate>>,
|
||||
|
||||
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>,
|
||||
|
||||
|
|
@ -160,6 +153,20 @@ pub struct BodySourceMap {
|
|||
diagnostics: Vec<BodyDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Eq, PartialEq)]
|
||||
struct FormatTemplate {
|
||||
/// A map from `format_args!()` expressions to their captures.
|
||||
format_args_to_captures: FxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>,
|
||||
/// A map from `asm!()` expressions to their captures.
|
||||
asm_to_captures: FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>,
|
||||
/// A map from desugared expressions of implicit captures to their source.
|
||||
///
|
||||
/// The value stored for each capture is its template literal and offset inside it. The template literal
|
||||
/// is from the `format_args[_nl]!()` macro and so needs to be mapped up once to go to the user-written
|
||||
/// template.
|
||||
implicit_capture_to_source: FxHashMap<ExprId, InFile<(AstPtr<ast::Expr>, TextRange)>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum BodyDiagnostic {
|
||||
InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
|
||||
|
|
@ -798,18 +805,29 @@ impl BodySourceMap {
|
|||
node: InFile<&ast::FormatArgsExpr>,
|
||||
) -> Option<(HygieneId, &[(syntax::TextRange, Name)])> {
|
||||
let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
|
||||
let (hygiene, names) =
|
||||
self.template_map.as_ref()?.0.get(&self.expr_map.get(&src)?.as_expr()?)?;
|
||||
let (hygiene, names) = self
|
||||
.template_map
|
||||
.as_ref()?
|
||||
.format_args_to_captures
|
||||
.get(&self.expr_map.get(&src)?.as_expr()?)?;
|
||||
Some((*hygiene, &**names))
|
||||
}
|
||||
|
||||
pub fn format_args_implicit_capture(
|
||||
&self,
|
||||
capture_expr: ExprId,
|
||||
) -> Option<InFile<(AstPtr<ast::Expr>, TextRange)>> {
|
||||
self.template_map.as_ref()?.implicit_capture_to_source.get(&capture_expr).copied()
|
||||
}
|
||||
|
||||
pub fn asm_template_args(
|
||||
&self,
|
||||
node: InFile<&ast::AsmExpr>,
|
||||
) -> Option<(ExprId, &[Vec<(syntax::TextRange, usize)>])> {
|
||||
let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
|
||||
let expr = self.expr_map.get(&src)?.as_expr()?;
|
||||
Some(expr).zip(self.template_map.as_ref()?.1.get(&expr).map(std::ops::Deref::deref))
|
||||
Some(expr)
|
||||
.zip(self.template_map.as_ref()?.asm_to_captures.get(&expr).map(std::ops::Deref::deref))
|
||||
}
|
||||
|
||||
/// Get a reference to the body source map's diagnostics.
|
||||
|
|
@ -835,8 +853,14 @@ impl BodySourceMap {
|
|||
types,
|
||||
} = self;
|
||||
if let Some(template_map) = template_map {
|
||||
template_map.0.shrink_to_fit();
|
||||
template_map.1.shrink_to_fit();
|
||||
let FormatTemplate {
|
||||
format_args_to_captures,
|
||||
asm_to_captures,
|
||||
implicit_capture_to_source,
|
||||
} = &mut **template_map;
|
||||
format_args_to_captures.shrink_to_fit();
|
||||
asm_to_captures.shrink_to_fit();
|
||||
implicit_capture_to_source.shrink_to_fit();
|
||||
}
|
||||
expr_map.shrink_to_fit();
|
||||
expr_map_back.shrink_to_fit();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue