Auto merge of #16684 - Veykril:synthetic-fmt-args, r=Veykril

fix: Don't panic on synthetic syntax in inference diagnostics

Temporary fix for https://github.com/rust-lang/rust-analyzer/issues/16682

We ought to rethink how we attach diagnostics to things, as IDs don't work for `format_args` like that!
This commit is contained in:
bors 2024-02-26 16:47:57 +00:00
commit 1d3558bfe1
2 changed files with 33 additions and 17 deletions

View File

@ -518,8 +518,12 @@ pub(crate) fn inference_diagnostic(
d: &InferenceDiagnostic,
source_map: &hir_def::body::BodySourceMap,
) -> Option<AnyDiagnostic> {
let expr_syntax = |expr| source_map.expr_syntax(expr).expect("unexpected synthetic");
let pat_syntax = |pat| source_map.pat_syntax(pat).expect("unexpected synthetic");
let expr_syntax = |expr| {
source_map.expr_syntax(expr).inspect_err(|_| tracing::error!("synthetic syntax")).ok()
};
let pat_syntax = |pat| {
source_map.pat_syntax(pat).inspect_err(|_| tracing::error!("synthetic syntax")).ok()
};
Some(match d {
&InferenceDiagnostic::NoSuchField { field: expr, private } => {
let expr_or_pat = match expr {
@ -533,23 +537,23 @@ pub(crate) fn inference_diagnostic(
NoSuchField { field: expr_or_pat, private }.into()
}
&InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
MismatchedArgCount { call_expr: expr_syntax(call_expr), expected, found }.into()
MismatchedArgCount { call_expr: expr_syntax(call_expr)?, expected, found }.into()
}
&InferenceDiagnostic::PrivateField { expr, field } => {
let expr = expr_syntax(expr);
let expr = expr_syntax(expr)?;
let field = field.into();
PrivateField { expr, field }.into()
}
&InferenceDiagnostic::PrivateAssocItem { id, item } => {
let expr_or_pat = match id {
ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
ExprOrPatId::PatId(pat) => pat_syntax(pat).map(AstPtr::wrap_right),
ExprOrPatId::ExprId(expr) => expr_syntax(expr)?.map(AstPtr::wrap_left),
ExprOrPatId::PatId(pat) => pat_syntax(pat)?.map(AstPtr::wrap_right),
};
let item = item.into();
PrivateAssocItem { expr_or_pat, item }.into()
}
InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
let call_expr = expr_syntax(*call_expr);
let call_expr = expr_syntax(*call_expr)?;
ExpectedFunction { call: call_expr, found: Type::new(db, def, found.clone()) }
.into()
}
@ -559,7 +563,7 @@ pub(crate) fn inference_diagnostic(
name,
method_with_same_name_exists,
} => {
let expr = expr_syntax(*expr);
let expr = expr_syntax(*expr)?;
UnresolvedField {
expr,
name: name.clone(),
@ -575,7 +579,7 @@ pub(crate) fn inference_diagnostic(
field_with_same_name,
assoc_func_with_same_name,
} => {
let expr = expr_syntax(*expr);
let expr = expr_syntax(*expr)?;
UnresolvedMethodCall {
expr,
name: name.clone(),
@ -589,29 +593,28 @@ pub(crate) fn inference_diagnostic(
}
&InferenceDiagnostic::UnresolvedAssocItem { id } => {
let expr_or_pat = match id {
ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
ExprOrPatId::PatId(pat) => pat_syntax(pat).map(AstPtr::wrap_right),
ExprOrPatId::ExprId(expr) => expr_syntax(expr)?.map(AstPtr::wrap_left),
ExprOrPatId::PatId(pat) => pat_syntax(pat)?.map(AstPtr::wrap_right),
};
UnresolvedAssocItem { expr_or_pat }.into()
}
&InferenceDiagnostic::UnresolvedIdent { expr } => {
let expr = expr_syntax(expr);
let expr = expr_syntax(expr)?;
UnresolvedIdent { expr }.into()
}
&InferenceDiagnostic::BreakOutsideOfLoop { expr, is_break, bad_value_break } => {
let expr = expr_syntax(expr);
let expr = expr_syntax(expr)?;
BreakOutsideOfLoop { expr, is_break, bad_value_break }.into()
}
InferenceDiagnostic::TypedHole { expr, expected } => {
let expr = expr_syntax(*expr);
let expr = expr_syntax(*expr)?;
TypedHole { expr, expected: Type::new(db, def, expected.clone()) }.into()
}
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
let expr_or_pat = match pat {
ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
ExprOrPatId::ExprId(expr) => expr_syntax(expr)?.map(AstPtr::wrap_left),
ExprOrPatId::PatId(pat) => {
let InFile { file_id, value } =
source_map.pat_syntax(pat).expect("unexpected synthetic");
let InFile { file_id, value } = pat_syntax(pat)?;
// cast from Either<Pat, SelfParam> -> Either<_, Pat>
let ptr = AstPtr::try_from_raw(value.syntax_node_ptr())?;

View File

@ -20,6 +20,19 @@ pub(crate) fn unresolved_ident(
mod tests {
use crate::tests::check_diagnostics;
// FIXME: This should show a diagnostic
#[test]
fn feature() {
check_diagnostics(
r#"
//- minicore: fmt
fn main() {
format_args!("{unresolved}");
}
"#,
)
}
#[test]
fn missing() {
check_diagnostics(