about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Barsky <me@davidbarsky.com>2025-06-08 13:17:56 -0400
committerDavid Barsky <me@davidbarsky.com>2025-06-11 12:12:58 -0400
commitfb169ff8a71a77078de98ecd05d42fd48d020db4 (patch)
tree779e00c74080a528310c7931eeee096a3270b863
parent6e5439b8f928abdb97d5b06283667f315f67a8aa (diff)
downloadrust-fb169ff8a71a77078de98ecd05d42fd48d020db4.tar.gz
rust-fb169ff8a71a77078de98ecd05d42fd48d020db4.zip
hir-ty: test (the absence of) incremental trait solving
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs88
1 files changed, 87 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
index e8e3812c69d..6ac260ac768 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
@@ -1,5 +1,5 @@
 use base_db::SourceDatabase;
-use hir_def::ModuleDefId;
+use hir_def::{DefWithBodyId, ModuleDefId};
 use test_fixture::WithFixture;
 
 use crate::{db::HirDatabase, test_db::TestDB};
@@ -359,3 +359,89 @@ impl SomeStruct {
         assert_eq!(expected, actual);
     }
 }
+
+#[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
+}",
+    );
+
+    {
+        let events = db.log_executed(|| {
+            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);
+            }
+        });
+        assert!(format!("{events:?}").contains("trait_solve_shim"))
+    }
+
+    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);
+
+    {
+        let events = db.log_executed(|| {
+            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);
+            }
+        });
+        assert!(format!("{events:?}").contains("trait_solve_shim"))
+    }
+}