about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-02-26 17:46:03 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-02-26 17:46:03 +0100
commit3856648b52cdc8d04a907e2fb2f881fa984368e8 (patch)
treeb81ec50fa83dfad41e2ebf62d3238a456305b13c
parent91554e0ae7436e1e49bb440f04cc91bad47f1db9 (diff)
downloadrust-3856648b52cdc8d04a907e2fb2f881fa984368e8.tar.gz
rust-3856648b52cdc8d04a907e2fb2f881fa984368e8.zip
fix: Don't panic on synthetic syntax in inference diagnostics
-rw-r--r--crates/hir/src/diagnostics.rs37
-rw-r--r--crates/ide-diagnostics/src/handlers/unresolved_ident.rs13
2 files changed, 33 insertions, 17 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 80cd0c9c794..fa9fe4953ed 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -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 {
@@ -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()
             }
@@ -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(),
@@ -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(),
@@ -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())?;
diff --git a/crates/ide-diagnostics/src/handlers/unresolved_ident.rs b/crates/ide-diagnostics/src/handlers/unresolved_ident.rs
index 295c8a2c615..7aa3e16536c 100644
--- a/crates/ide-diagnostics/src/handlers/unresolved_ident.rs
+++ b/crates/ide-diagnostics/src/handlers/unresolved_ident.rs
@@ -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(