Skip to content

Commit

Permalink
fix: Don't panic on synthetic syntax in inference diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Feb 26, 2024
1 parent 91554e0 commit 3856648
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
37 changes: 20 additions & 17 deletions crates/hir/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,12 @@ impl AnyDiagnostic {
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 {
Expand All @@ -533,23 +537,23 @@ impl AnyDiagnostic {
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()
}
Expand All @@ -559,7 +563,7 @@ impl AnyDiagnostic {
name,
method_with_same_name_exists,
} => {
let expr = expr_syntax(*expr);
let expr = expr_syntax(*expr)?;
UnresolvedField {
expr,
name: name.clone(),
Expand All @@ -575,7 +579,7 @@ impl AnyDiagnostic {
field_with_same_name,
assoc_func_with_same_name,
} => {
let expr = expr_syntax(*expr);
let expr = expr_syntax(*expr)?;
UnresolvedMethodCall {
expr,
name: name.clone(),
Expand All @@ -589,29 +593,28 @@ impl AnyDiagnostic {
}
&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())?;
Expand Down
13 changes: 13 additions & 0 deletions crates/ide-diagnostics/src/handlers/unresolved_ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 3856648

Please sign in to comment.