]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests.rs
Merge #11842
[rust.git] / crates / hir_ty / src / tests.rs
index 0651f34ae6cca512f296671d84398e6faae94c6d..d2f13e4351c73b17cca725446ddfcbd772988e4f 100644 (file)
@@ -8,6 +8,7 @@
 mod macros;
 mod display_source_code;
 mod incremental;
+mod diagnostics;
 
 use std::{collections::HashMap, env, sync::Arc};
 
 use once_cell::race::OnceBool;
 use stdx::format_to;
 use syntax::{
-    ast::{self, AstNode, NameOwner},
+    ast::{self, AstNode, HasName},
     SyntaxNode,
 };
 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
 use tracing_tree::HierarchicalLayer;
 
 use crate::{
-    db::HirDatabase, display::HirDisplay, infer::TypeMismatch, test_db::TestDB, InferenceResult, Ty,
+    db::HirDatabase,
+    display::HirDisplay,
+    infer::{Adjustment, TypeMismatch},
+    test_db::TestDB,
+    InferenceResult, Ty,
 };
 
 // These tests compare the inference results for all expressions in a file
@@ -79,6 +84,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
     let mut had_annotations = false;
     let mut mismatches = HashMap::new();
     let mut types = HashMap::new();
+    let mut adjustments = HashMap::<_, Vec<_>>::new();
     for (file_id, annotations) in db.extract_annotations() {
         for (range, expected) in annotations {
             let file_range = FileRange { file_id, range };
@@ -88,6 +94,16 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                 types.insert(file_range, expected.trim_start_matches("type: ").to_string());
             } else if expected.starts_with("expected") {
                 mismatches.insert(file_range, expected);
+            } else if expected.starts_with("adjustments: ") {
+                adjustments.insert(
+                    file_range,
+                    expected
+                        .trim_start_matches("adjustments: ")
+                        .split(',')
+                        .map(|it| it.trim().to_string())
+                        .filter(|it| !it.is_empty())
+                        .collect(),
+                );
             } else {
                 panic!("unexpected annotation: {}", expected);
             }
@@ -155,6 +171,19 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                 };
                 assert_eq!(actual, expected);
             }
+            if let Some(expected) = adjustments.remove(&range) {
+                if let Some(adjustments) = inference_result.expr_adjustments.get(&expr) {
+                    assert_eq!(
+                        expected,
+                        adjustments
+                            .iter()
+                            .map(|Adjustment { kind, .. }| format!("{:?}", kind))
+                            .collect::<Vec<_>>()
+                    );
+                } else {
+                    panic!("expected {:?} adjustments, found none", expected);
+                }
+            }
         }
 
         for (pat, mismatch) in inference_result.pat_type_mismatches() {
@@ -168,10 +197,9 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                 mismatch.expected.display_test(&db),
                 mismatch.actual.display_test(&db)
             );
-            if let Some(annotation) = mismatches.remove(&range) {
-                assert_eq!(actual, annotation);
-            } else {
-                format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
+            match mismatches.remove(&range) {
+                Some(annotation) => assert_eq!(actual, annotation),
+                None => format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual),
             }
         }
         for (expr, mismatch) in inference_result.expr_type_mismatches() {
@@ -188,10 +216,9 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                 mismatch.expected.display_test(&db),
                 mismatch.actual.display_test(&db)
             );
-            if let Some(annotation) = mismatches.remove(&range) {
-                assert_eq!(actual, annotation);
-            } else {
-                format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
+            match mismatches.remove(&range) {
+                Some(annotation) => assert_eq!(actual, annotation),
+                None => format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual),
             }
         }
     }
@@ -212,6 +239,12 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
             format_to!(buf, "{:?}: type {}\n", t.0.range, t.1);
         }
     }
+    if !adjustments.is_empty() {
+        format_to!(buf, "Unchecked adjustments annotations:\n");
+        for t in adjustments {
+            format_to!(buf, "{:?}: type {:?}\n", t.0.range, t.1);
+        }
+    }
     assert!(buf.is_empty(), "{}", buf);
 }
 
@@ -305,7 +338,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
             let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) {
                 (self_param.name().unwrap().syntax().text_range(), "self".to_string())
             } else {
-                (node.value.text_range(), node.value.text().to_string().replace("\n", " "))
+                (node.value.text_range(), node.value.text().to_string().replace('\n', " "))
             };
             let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" };
             format_to!(