Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/tests.rs')
-rw-r--r--crates/hir-ty/src/tests.rs95
1 files changed, 68 insertions, 27 deletions
diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs
index 430a570444..d259ce7963 100644
--- a/crates/hir-ty/src/tests.rs
+++ b/crates/hir-ty/src/tests.rs
@@ -16,8 +16,8 @@ mod traits;
use base_db::{Crate, SourceDatabase};
use expect_test::Expect;
use hir_def::{
- AssocItemId, DefWithBodyId, GenericDefId, HasModule, Lookup, ModuleDefId, ModuleId,
- SyntheticSyntax,
+ AdtId, AssocItemId, DefWithBodyId, GenericDefId, HasModule, Lookup, ModuleDefId, ModuleId,
+ SyntheticSyntax, VariantId,
expr_store::{Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap},
hir::{ExprId, Pat, PatId},
item_scope::ItemScope,
@@ -36,9 +36,10 @@ use syntax::{
use test_fixture::WithFixture;
use crate::{
- InferenceResult,
+ InferenceDiagnostic, InferenceResult,
+ db::{AnonConstId, HirDatabase},
display::{DisplayTarget, HirDisplay},
- infer::{Adjustment, TypeMismatch},
+ infer::Adjustment,
next_solver::Ty,
setup_tracing,
test_db::TestDB,
@@ -88,15 +89,12 @@ fn check_impl(
let file_range = FileRange { file_id, range };
if only_types {
types.insert(file_range, expected);
- } else if expected.starts_with("type: ") {
- types.insert(file_range, expected.trim_start_matches("type: ").to_owned());
+ } else if let Some(ty) = expected.strip_prefix("type: ") {
+ types.insert(file_range, ty.to_owned());
} 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:").trim().to_owned(),
- );
+ } else if let Some(adjs) = expected.strip_prefix("adjustments:") {
+ adjustments.insert(file_range, adjs.trim().to_owned());
} else {
panic!("unexpected annotation: {expected} @ {range:?}");
}
@@ -198,7 +196,14 @@ fn check_impl(
}
}
- for (expr_or_pat, mismatch) in inference_result.type_mismatches() {
+ let type_mismatches =
+ inference_result.diagnostics().iter().filter_map(|diag| match diag {
+ InferenceDiagnostic::TypeMismatch { node, expected, found } => {
+ Some((*node, expected.as_ref(), found.as_ref()))
+ }
+ _ => None,
+ });
+ for (expr_or_pat, expected, actual) in type_mismatches {
let Some(node) = (match expr_or_pat {
hir_def::hir::ExprOrPatId::ExprId(expr) => {
expr_node(body_source_map, expr, &db)
@@ -210,8 +215,8 @@ fn check_impl(
let range = node.as_ref().original_file_range_rooted(&db);
let actual = format!(
"expected {}, got {}",
- mismatch.expected.as_ref().display_test(&db, display_target),
- mismatch.actual.as_ref().display_test(&db, display_target)
+ expected.display_test(&db, display_target),
+ actual.display_test(&db, display_target)
);
match mismatches.remove(&range) {
Some(annotation) => assert_eq!(actual, annotation),
@@ -329,7 +334,17 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
krate: Crate| {
let display_target = DisplayTarget::from_crate(&db, krate);
let mut types: Vec<(InFile<SyntaxNode>, Ty<'_>)> = Vec::new();
- let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new();
+ let type_mismatch_for_node = inference_result
+ .diagnostics()
+ .iter()
+ .filter_map(|diag| match diag {
+ InferenceDiagnostic::TypeMismatch { node, expected, found } => {
+ Some((*node, (expected.as_ref(), found.as_ref())))
+ }
+ _ => None,
+ })
+ .collect::<FxHashMap<_, _>>();
+ let mut mismatches: Vec<(InFile<SyntaxNode>, (Ty<'_>, Ty<'_>))> = Vec::new();
if let Some((binding_id, syntax_ptr)) = self_param {
let ty = &inference_result.type_of_binding[binding_id];
@@ -352,8 +367,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
Err(SyntheticSyntax) => continue,
};
types.push((node.clone(), ty.as_ref()));
- if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat) {
- mismatches.push((node, mismatch));
+ if let Some(mismatch) = type_mismatch_for_node.get(&pat.into()) {
+ mismatches.push((node, *mismatch));
}
}
@@ -366,8 +381,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
Err(SyntheticSyntax) => continue,
};
types.push((node.clone(), ty.as_ref()));
- if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) {
- mismatches.push((node, mismatch));
+ if let Some(mismatch) = type_mismatch_for_node.get(&expr.into()) {
+ mismatches.push((node, *mismatch));
}
}
@@ -398,7 +413,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
let range = node.value.text_range();
(range.start(), range.end())
});
- for (src_ptr, mismatch) in &mismatches {
+ for (src_ptr, (expected, actual)) in &mismatches {
let range = src_ptr.value.text_range();
let macro_prefix = if src_ptr.file_id != file_id { "!" } else { "" };
format_to!(
@@ -406,8 +421,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
"{}{:?}: expected {}, got {}\n",
macro_prefix,
range,
- mismatch.expected.as_ref().display_test(&db, display_target),
- mismatch.actual.as_ref().display_test(&db, display_target),
+ expected.display_test(&db, display_target),
+ actual.display_test(&db, display_target),
);
}
}
@@ -418,6 +433,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
let mut generic_defs: Vec<(GenericDefId, Crate)> = Vec::new();
+ let mut variants: Vec<(VariantId, Crate)> = Vec::new();
visit_module(&db, def_map, module, &mut |it| {
let krate = module.krate(&db);
match it {
@@ -438,6 +454,16 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
}
ModuleDefId::AdtId(it) => {
generic_defs.push((it.into(), krate));
+ match it {
+ AdtId::StructId(id) => variants.push((id.into(), krate)),
+ AdtId::UnionId(id) => variants.push((id.into(), krate)),
+ AdtId::EnumId(id) => variants.extend(
+ id.enum_variants(&db)
+ .variants
+ .iter()
+ .map(|&(variant, ..)| (variant.into(), krate)),
+ ),
+ }
}
ModuleDefId::TraitId(it) => {
generic_defs.push((it.into(), krate));
@@ -488,7 +514,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
for (def, krate) in defs {
let (body, source_map) = Body::with_source_map(&db, def);
let infer = InferenceResult::of(&db, def);
- let self_param = body.self_param.map(|id| (id, source_map.self_param_syntax()));
+ let self_param = body.self_param().map(|id| (id, source_map.self_param_syntax()));
infer_def(infer, body, source_map, self_param, krate);
}
@@ -497,11 +523,26 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
for (def, krate) in generic_defs {
let (store, source_map) = ExpressionStore::with_source_map(&db, def.into());
// Skip if there are no const expressions in the signature
- if store.const_expr_origins().is_empty() {
+ if store.expr_roots().next().is_none() {
continue;
}
- let infer = InferenceResult::of(&db, def);
- infer_def(infer, store, source_map, None, krate);
+ for &anon_const in AnonConstId::all_from_signature(&db, def).into_iter().flatten() {
+ let infer = InferenceResult::of(&db, anon_const);
+ infer_def(infer, store, source_map, None, krate);
+ }
+ }
+ variants.dedup();
+ for (def, krate) in variants {
+ let (store, source_map) = ExpressionStore::with_source_map(&db, def.into());
+ // Skip if there are no const expressions in the signature
+ if store.expr_roots().next().is_none() {
+ continue;
+ }
+ let anon_consts = db.field_types_with_diagnostics(def).defined_anon_consts();
+ for &anon_const in anon_consts {
+ let infer = InferenceResult::of(&db, anon_const);
+ infer_def(infer, store, source_map, None, krate);
+ }
}
buf.truncate(buf.trim_end().len());
@@ -558,7 +599,7 @@ pub(crate) fn visit_module(
let body = Body::of(db, it.into());
visit_body(db, body, cb);
}
- ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
+ ModuleDefId::AdtId(AdtId::EnumId(it)) => {
it.enum_variants(db).variants.iter().for_each(|&(it, _, _)| {
let body = Body::of(db, it.into());
cb(it.into());