Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/tests/incremental.rs')
-rw-r--r--crates/hir-ty/src/tests/incremental.rs598
1 files changed, 489 insertions, 109 deletions
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index e8e3812c69..3159499e86 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -1,5 +1,7 @@
use base_db::SourceDatabase;
-use hir_def::ModuleDefId;
+use expect_test::Expect;
+use hir_def::{DefWithBodyId, ModuleDefId};
+use salsa::EventKind;
use test_fixture::WithFixture;
use crate::{db::HirDatabase, test_db::TestDB};
@@ -15,8 +17,9 @@ fn foo() -> i32 {
$01 + 1
}",
);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
@@ -24,9 +27,31 @@ fn foo() -> i32 {
db.infer(it.into());
}
});
- });
- assert!(format!("{events:?}").contains("infer_shim"))
- }
+ },
+ &[("infer_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "infer_shim",
+ "function_signature_shim",
+ "function_signature_with_source_map_shim",
+ "attrs_shim",
+ "body_shim",
+ "body_with_source_map_shim",
+ "trait_environment_shim",
+ "return_type_impl_traits_shim",
+ "expr_scopes_shim",
+ "lang_item",
+ "crate_lang_items",
+ "lang_item",
+ ]
+ "#]],
+ );
let new_text = "
fn foo() -> i32 {
@@ -37,8 +62,9 @@ fn foo() -> i32 {
db.set_file_text(pos.file_id.file_id(&db), new_text);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
@@ -46,9 +72,22 @@ fn foo() -> i32 {
db.infer(it.into());
}
});
- });
- assert!(!format!("{events:?}").contains("infer_shim"), "{events:#?}")
- }
+ },
+ &[("infer_shim", 0)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "attrs_shim",
+ "function_signature_with_source_map_shim",
+ "function_signature_shim",
+ "body_with_source_map_shim",
+ "body_shim",
+ ]
+ "#]],
+ );
}
#[test]
@@ -66,8 +105,9 @@ fn baz() -> i32 {
1 + 1
}",
);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
@@ -75,9 +115,49 @@ fn baz() -> i32 {
db.infer(it.into());
}
});
- });
- assert!(format!("{events:?}").contains("infer_shim"))
- }
+ },
+ &[("infer_shim", 3)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "infer_shim",
+ "function_signature_shim",
+ "function_signature_with_source_map_shim",
+ "attrs_shim",
+ "body_shim",
+ "body_with_source_map_shim",
+ "trait_environment_shim",
+ "return_type_impl_traits_shim",
+ "expr_scopes_shim",
+ "lang_item",
+ "crate_lang_items",
+ "attrs_shim",
+ "attrs_shim",
+ "lang_item",
+ "infer_shim",
+ "function_signature_shim",
+ "function_signature_with_source_map_shim",
+ "body_shim",
+ "body_with_source_map_shim",
+ "trait_environment_shim",
+ "return_type_impl_traits_shim",
+ "expr_scopes_shim",
+ "infer_shim",
+ "function_signature_shim",
+ "function_signature_with_source_map_shim",
+ "body_shim",
+ "body_with_source_map_shim",
+ "trait_environment_shim",
+ "return_type_impl_traits_shim",
+ "expr_scopes_shim",
+ ]
+ "#]],
+ );
let new_text = "
fn foo() -> f32 {
@@ -93,8 +173,9 @@ fn baz() -> i32 {
db.set_file_text(pos.file_id.file_id(&db), new_text);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
@@ -102,9 +183,34 @@ fn baz() -> i32 {
db.infer(it.into());
}
});
- });
- assert_eq!(format!("{events:?}").matches("infer_shim").count(), 1, "{events:#?}")
- }
+ },
+ &[("infer_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "attrs_shim",
+ "function_signature_with_source_map_shim",
+ "function_signature_shim",
+ "body_with_source_map_shim",
+ "body_shim",
+ "attrs_shim",
+ "attrs_shim",
+ "function_signature_with_source_map_shim",
+ "function_signature_shim",
+ "body_with_source_map_shim",
+ "body_shim",
+ "infer_shim",
+ "expr_scopes_shim",
+ "function_signature_with_source_map_shim",
+ "function_signature_shim",
+ "body_with_source_map_shim",
+ "body_shim",
+ ]
+ "#]],
+ );
}
#[test]
@@ -121,14 +227,26 @@ fn bar() -> f32 {
}
$0",
);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
- assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
let new_text = "
fn foo() -> i32 {
@@ -146,24 +264,25 @@ pub struct NewStruct {
db.set_file_text(pos.file_id.file_id(&db), new_text);
- {
- let actual = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
-
- let expected = vec![
- "parse_shim".to_owned(),
- "ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
- "real_span_map_shim".to_owned(),
- "crate_local_def_map".to_owned(),
- "trait_impls_in_crate_shim".to_owned(),
- ];
-
- assert_eq!(expected, actual);
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "crate_local_def_map",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
}
#[test]
@@ -180,14 +299,26 @@ fn bar() -> f32 {
}
$0",
);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
- assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
let new_text = "
fn foo() -> i32 {
@@ -206,24 +337,25 @@ pub enum SomeEnum {
db.set_file_text(pos.file_id.file_id(&db), new_text);
- {
- let actual = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
-
- let expected = vec![
- "parse_shim".to_owned(),
- "ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
- "real_span_map_shim".to_owned(),
- "crate_local_def_map".to_owned(),
- "trait_impls_in_crate_shim".to_owned(),
- ];
-
- assert_eq!(expected, actual);
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "crate_local_def_map",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
}
#[test]
@@ -240,14 +372,26 @@ fn bar() -> f32 {
}
$0",
);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
- assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
let new_text = "
use std::collections::HashMap;
@@ -263,24 +407,25 @@ fn bar() -> f32 {
db.set_file_text(pos.file_id.file_id(&db), new_text);
- {
- let actual = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
-
- let expected = vec![
- "parse_shim".to_owned(),
- "ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
- "real_span_map_shim".to_owned(),
- "crate_local_def_map".to_owned(),
- "trait_impls_in_crate_shim".to_owned(),
- ];
-
- assert_eq!(expected, actual);
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "crate_local_def_map",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
}
#[test]
@@ -301,14 +446,26 @@ pub struct SomeStruct {
}
$0",
);
- {
- let events = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
- assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "trait_impls_in_crate_shim",
+ ]
+ "#]],
+ );
let new_text = "
fn foo() -> i32 {
@@ -332,30 +489,253 @@ impl SomeStruct {
db.set_file_text(pos.file_id.file_id(&db), new_text);
- {
- let actual = db.log_executed(|| {
+ execute_assert_events(
+ &db,
+ || {
let module = db.module_for_file(pos.file_id.file_id(&db));
let _crate_def_map = module.def_map(&db);
db.trait_impls_in_crate(module.krate());
- });
-
- let expected = vec![
- "parse_shim".to_owned(),
- "ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
- "real_span_map_shim".to_owned(),
- "crate_local_def_map".to_owned(),
- "trait_impls_in_crate_shim".to_owned(),
- "attrs_shim".to_owned(),
- "impl_trait_with_diagnostics_shim".to_owned(),
- "impl_signature_shim".to_owned(),
- "impl_signature_with_source_map_shim".to_owned(),
- "impl_self_ty_with_diagnostics_shim".to_owned(),
- "struct_signature_shim".to_owned(),
- "struct_signature_with_source_map_shim".to_owned(),
- "type_for_adt_tracked".to_owned(),
- ];
-
- assert_eq!(expected, actual);
- }
+ },
+ &[("trait_impls_in_crate_shim", 1)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "crate_local_def_map",
+ "trait_impls_in_crate_shim",
+ "attrs_shim",
+ "impl_trait_with_diagnostics_shim",
+ "impl_signature_shim",
+ "impl_signature_with_source_map_shim",
+ "impl_self_ty_with_diagnostics_shim",
+ "struct_signature_shim",
+ "struct_signature_with_source_map_shim",
+ "attrs_shim",
+ "type_for_adt_tracked",
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn add_struct_invalidates_trait_solve() {
+ let (mut db, file_id) = TestDB::with_single_file(
+ "
+//- /main.rs crate:main
+struct SomeStruct;
+
+trait Trait<T> {
+ fn method(&self) -> T;
+}
+impl Trait<u32> for SomeStruct {}
+
+fn main() {
+ let s = SomeStruct;
+ s.method();
+ s.$0
+}",
+ );
+
+ execute_assert_events(
+ &db,
+ || {
+ let module = db.module_for_file(file_id.file_id(&db));
+ let crate_def_map = module.def_map(&db);
+ let mut defs: Vec<DefWithBodyId> = vec![];
+ visit_module(&db, crate_def_map, module.local_id, &mut |it| {
+ let def = match it {
+ ModuleDefId::FunctionId(it) => it.into(),
+ ModuleDefId::EnumVariantId(it) => it.into(),
+ ModuleDefId::ConstId(it) => it.into(),
+ ModuleDefId::StaticId(it) => it.into(),
+ _ => return,
+ };
+ defs.push(def);
+ });
+
+ for def in defs {
+ let _inference_result = db.infer(def);
+ }
+ },
+ &[("trait_solve_shim", 2)],
+ expect_test::expect![[r#"
+ [
+ "source_root_crates_shim",
+ "crate_local_def_map",
+ "file_item_tree_query",
+ "ast_id_map_shim",
+ "parse_shim",
+ "real_span_map_shim",
+ "TraitItems::query_with_diagnostics_",
+ "body_shim",
+ "body_with_source_map_shim",
+ "attrs_shim",
+ "ImplItems::of_",
+ "infer_shim",
+ "trait_signature_shim",
+ "trait_signature_with_source_map_shim",
+ "attrs_shim",
+ "function_signature_shim",
+ "function_signature_with_source_map_shim",
+ "attrs_shim",
+ "body_shim",
+ "body_with_source_map_shim",
+ "trait_environment_shim",
+ "lang_item",
+ "crate_lang_items",
+ "attrs_shim",
+ "attrs_shim",
+ "return_type_impl_traits_shim",
+ "infer_shim",
+ "function_signature_shim",
+ "function_signature_with_source_map_shim",
+ "trait_environment_shim",
+ "expr_scopes_shim",
+ "struct_signature_shim",
+ "struct_signature_with_source_map_shim",
+ "generic_predicates_shim",
+ "value_ty_shim",
+ "VariantFields::firewall_",
+ "VariantFields::query_",
+ "lang_item",
+ "inherent_impls_in_crate_shim",
+ "impl_signature_shim",
+ "impl_signature_with_source_map_shim",
+ "callable_item_signature_shim",
+ "adt_variance_shim",
+ "variances_of_shim",
+ "trait_solve_shim",
+ "trait_datum_shim",
+ "generic_predicates_shim",
+ "adt_datum_shim",
+ "trait_impls_in_deps_shim",
+ "trait_impls_in_crate_shim",
+ "impl_trait_with_diagnostics_shim",
+ "impl_self_ty_with_diagnostics_shim",
+ "type_for_adt_tracked",
+ "impl_datum_shim",
+ "generic_predicates_shim",
+ "program_clauses_for_chalk_env_shim",
+ "value_ty_shim",
+ "generic_predicates_shim",
+ "trait_solve_shim",
+ "lang_item",
+ ]
+ "#]],
+ );
+
+ let new_text = "
+//- /main.rs crate:main
+struct AnotherStruct;
+
+struct SomeStruct;
+
+trait Trait<T> {
+ fn method(&self) -> T;
+}
+impl Trait<u32> for SomeStruct {}
+
+fn main() {
+ let s = SomeStruct;
+ s.method();
+ s.$0
+}";
+
+ db.set_file_text(file_id.file_id(&db), new_text);
+
+ execute_assert_events(
+ &db,
+ || {
+ let module = db.module_for_file(file_id.file_id(&db));
+ let crate_def_map = module.def_map(&db);
+ let mut defs: Vec<DefWithBodyId> = vec![];
+
+ visit_module(&db, crate_def_map, module.local_id, &mut |it| {
+ let def = match it {
+ ModuleDefId::FunctionId(it) => it.into(),
+ ModuleDefId::EnumVariantId(it) => it.into(),
+ ModuleDefId::ConstId(it) => it.into(),
+ ModuleDefId::StaticId(it) => it.into(),
+ _ => return,
+ };
+ defs.push(def);
+ });
+
+ for def in defs {
+ let _inference_result = db.infer(def);
+ }
+ },
+ &[("trait_solve_shim", 0)],
+ expect_test::expect![[r#"
+ [
+ "parse_shim",
+ "ast_id_map_shim",
+ "file_item_tree_query",
+ "real_span_map_shim",
+ "crate_local_def_map",
+ "TraitItems::query_with_diagnostics_",
+ "body_with_source_map_shim",
+ "attrs_shim",
+ "body_shim",
+ "ImplItems::of_",
+ "infer_shim",
+ "attrs_shim",
+ "trait_signature_with_source_map_shim",
+ "attrs_shim",
+ "function_signature_with_source_map_shim",
+ "function_signature_shim",
+ "body_with_source_map_shim",
+ "body_shim",
+ "trait_environment_shim",
+ "crate_lang_items",
+ "attrs_shim",
+ "attrs_shim",
+ "attrs_shim",
+ "return_type_impl_traits_shim",
+ "infer_shim",
+ "function_signature_with_source_map_shim",
+ "expr_scopes_shim",
+ "struct_signature_with_source_map_shim",
+ "VariantFields::query_",
+ "inherent_impls_in_crate_shim",
+ "impl_signature_with_source_map_shim",
+ "impl_signature_shim",
+ "callable_item_signature_shim",
+ "generic_predicates_shim",
+ "trait_impls_in_crate_shim",
+ "impl_trait_with_diagnostics_shim",
+ "impl_self_ty_with_diagnostics_shim",
+ "generic_predicates_shim",
+ ]
+ "#]],
+ );
+}
+
+fn execute_assert_events(
+ db: &TestDB,
+ f: impl FnOnce(),
+ required: &[(&str, usize)],
+ expect: Expect,
+) {
+ let (executed, events) = db.log_executed(f);
+ salsa::attach(db, || {
+ for (event, count) in required {
+ let n = executed.iter().filter(|it| it.contains(event)).count();
+ assert_eq!(
+ n,
+ *count,
+ "Expected {event} to be executed {count} times, but only got {n}:\n \
+ Executed: {executed:#?}\n \
+ Event log: {events:#?}",
+ events = events
+ .iter()
+ .filter(|event| !matches!(event.kind, EventKind::WillCheckCancellation))
+ .map(|event| { format!("{:?}", event.kind) })
+ .collect::<Vec<_>>(),
+ );
+ }
+ expect.assert_debug_eq(&executed);
+ });
}