Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/tests.rs97
-rw-r--r--crates/hir-ty/src/tests/patterns.rs2
-rw-r--r--crates/hir-ty/src/tests/regression.rs1
-rw-r--r--crates/hir-ty/src/tests/regression/new_solver.rs8
-rw-r--r--crates/hir-ty/src/tests/simple.rs39
-rw-r--r--crates/hir-ty/src/tests/traits.rs6
6 files changed, 133 insertions, 20 deletions
diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs
index 67ab89f5ec..042f0568f3 100644
--- a/crates/hir-ty/src/tests.rs
+++ b/crates/hir-ty/src/tests.rs
@@ -16,9 +16,10 @@ mod traits;
use base_db::{Crate, SourceDatabase};
use expect_test::Expect;
use hir_def::{
- AssocItemId, DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, SyntheticSyntax,
+ AssocItemId, DefWithBodyId, GenericDefId, HasModule, Lookup, ModuleDefId, ModuleId,
+ SyntheticSyntax,
db::DefDatabase,
- expr_store::{Body, BodySourceMap},
+ expr_store::{Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap},
hir::{ExprId, Pat, PatId},
item_scope::ItemScope,
nameres::DefMap,
@@ -34,7 +35,6 @@ use syntax::{
ast::{self, AstNode, HasName},
};
use test_fixture::WithFixture;
-use triomphe::Arc;
use crate::{
InferenceResult,
@@ -321,16 +321,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
let mut buf = String::new();
let mut infer_def = |inference_result: &InferenceResult,
- body: Arc<Body>,
- body_source_map: Arc<BodySourceMap>,
+ store: &ExpressionStore,
+ source_map: &ExpressionStoreSourceMap,
+ self_param: Option<(
+ hir_def::hir::BindingId,
+ Option<InFile<hir_def::expr_store::SelfParamPtr>>,
+ )>,
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();
- if let Some(self_param) = body.self_param {
- let ty = &inference_result.type_of_binding[self_param];
- if let Some(syntax_ptr) = body_source_map.self_param_syntax() {
+ if let Some((binding_id, syntax_ptr)) = self_param {
+ let ty = &inference_result.type_of_binding[binding_id];
+ if let Some(syntax_ptr) = syntax_ptr {
let root = db.parse_or_expand(syntax_ptr.file_id);
let node = syntax_ptr.map(|ptr| ptr.to_node(&root).syntax().clone());
types.push((node, ty.as_ref()));
@@ -338,10 +342,10 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
}
for (pat, mut ty) in inference_result.type_of_pat.iter() {
- if let Pat::Bind { id, .. } = body[pat] {
+ if let Pat::Bind { id, .. } = store[pat] {
ty = &inference_result.type_of_binding[id];
}
- let node = match body_source_map.pat_syntax(pat) {
+ let node = match source_map.pat_syntax(pat) {
Ok(sp) => {
let root = db.parse_or_expand(sp.file_id);
sp.map(|ptr| ptr.to_node(&root).syntax().clone())
@@ -355,7 +359,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
}
for (expr, ty) in inference_result.type_of_expr.iter() {
- let node = match body_source_map.expr_syntax(expr) {
+ let node = match source_map.expr_syntax(expr) {
Ok(sp) => {
let root = db.parse_or_expand(sp.file_id);
sp.map(|ptr| ptr.to_node(&root).syntax().clone())
@@ -414,16 +418,56 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
let def_map = module.def_map(&db);
let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
+ let mut generic_defs: Vec<(GenericDefId, Crate)> = Vec::new();
visit_module(&db, def_map, module, &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, module.krate(&db)))
+ let krate = module.krate(&db);
+ match it {
+ ModuleDefId::FunctionId(it) => {
+ defs.push((it.into(), krate));
+ generic_defs.push((it.into(), krate));
+ }
+ ModuleDefId::EnumVariantId(it) => {
+ defs.push((it.into(), krate));
+ }
+ ModuleDefId::ConstId(it) => {
+ defs.push((it.into(), krate));
+ generic_defs.push((it.into(), krate));
+ }
+ ModuleDefId::StaticId(it) => {
+ defs.push((it.into(), krate));
+ generic_defs.push((it.into(), krate));
+ }
+ ModuleDefId::AdtId(it) => {
+ generic_defs.push((it.into(), krate));
+ }
+ ModuleDefId::TraitId(it) => {
+ generic_defs.push((it.into(), krate));
+ }
+ ModuleDefId::TypeAliasId(it) => {
+ generic_defs.push((it.into(), krate));
+ }
+ _ => {}
+ }
});
+ // Also collect impls
+ for impl_id in def_map[module].scope.impls() {
+ generic_defs.push((impl_id.into(), module.krate(&db)));
+ let impl_data = impl_id.impl_items(&db);
+ for &(_, item) in impl_data.items.iter() {
+ match item {
+ AssocItemId::FunctionId(it) => {
+ generic_defs.push((it.into(), module.krate(&db)));
+ }
+ AssocItemId::ConstId(it) => {
+ generic_defs.push((it.into(), module.krate(&db)));
+ }
+ AssocItemId::TypeAliasId(it) => {
+ generic_defs.push((it.into(), module.krate(&db)));
+ }
+ }
+ }
+ }
+
defs.sort_by_key(|(def, _)| match def {
DefWithBodyId::FunctionId(it) => {
let loc = it.lookup(&db);
@@ -445,7 +489,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
for (def, krate) in defs {
let (body, source_map) = db.body_with_source_map(def);
let infer = InferenceResult::for_body(&db, def);
- infer_def(infer, body, source_map, krate);
+ let self_param = body.self_param.map(|id| (id, source_map.self_param_syntax()));
+ infer_def(infer, &body, &source_map, self_param, krate);
+ }
+
+ // Also infer signature const expressions (array lengths, const generic args, etc.)
+ generic_defs.dedup();
+ for (def, krate) in generic_defs {
+ let (_, store, source_map) = db.generic_params_and_store_and_source_map(def);
+ // Skip if there are no const expressions in the signature
+ if store.const_expr_origins().is_empty() {
+ continue;
+ }
+ let infer = InferenceResult::for_signature(&db, def);
+ infer_def(infer, &store, &source_map, None, krate);
}
buf.truncate(buf.trim_end().len());
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index 8c7d29f993..42dc074309 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -421,6 +421,8 @@ fn infer_pattern_match_byte_string_literal() {
254..256 '&v': &'? [u8; 3]
255..256 'v': [u8; 3]
257..259 '{}': ()
+ 199..200 '3': usize
+ 62..63 'N': usize
"#]],
);
}
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index d88801a57b..e4fc7e56c6 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -2754,6 +2754,7 @@ where
664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static
691..698 'loop {}': !
696..698 '{}': ()
+ 512..513 'N': usize
"#]],
);
}
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
index f47a26d429..e6b3244cda 100644
--- a/crates/hir-ty/src/tests/regression/new_solver.rs
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -34,6 +34,7 @@ impl Space for [u8; 1] {
223..227 'iter': IntoIter<u8>
230..231 'a': Vec<u8>
230..243 'a.into_iter()': IntoIter<u8>
+ 322..323 '1': usize
"#]],
);
}
@@ -472,6 +473,8 @@ fn foo() {
249..257 'to_bytes': fn to_bytes() -> [u8; _]
249..259 'to_bytes()': [u8; _]
249..268 'to_byt..._vec()': Vec<<[u8; _] as Foo>::Item>
+ 205..206 '_': usize
+ 156..157 'N': usize
"#]],
);
}
@@ -541,6 +544,11 @@ fn test_at_most() {
617..620 'num': Between<0, 1, char>
623..626 ''9'': char
623..641 ''9'.at...:<1>()': Between<0, 1, char>
+ 320..335 '{ Consts::MAX }': usize
+ 322..333 'Consts::MAX': usize
+ 421..422 '0': i32
+ 144..159 '{ Consts::MAX }': usize
+ 146..157 'Consts::MAX': usize
"#]],
);
}
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index dab8bdb54b..3ea21f8265 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -3868,6 +3868,8 @@ fn main() {
208..209 'c': u8
213..214 'a': A
213..221 'a.into()': [u8; 2]
+ 33..34 '2': usize
+ 111..112 '3': usize
"#]],
);
}
@@ -4061,6 +4063,8 @@ fn foo() {
248..282 'LazyLo..._LOCK)': &'? [u32; _]
264..281 '&VALUE...Y_LOCK': &'? LazyLock<[u32; _]>
265..281 'VALUES...Y_LOCK': LazyLock<[u32; _]>
+ 197..202 '{ 0 }': usize
+ 199..200 '0': usize
"#]],
);
}
@@ -4109,3 +4113,38 @@ fn foo() {
"#,
);
}
+
+#[test]
+fn signature_inference() {
+ check_infer(
+ r#"
+trait Trait<const A: u8> {}
+struct S<T: Trait<2>, const C: f32 = 0.0>
+where
+ (): Trait<2>
+{
+ field: [(); { C as usize }],
+ field2: *mut S<T, 5.0>
+}
+
+struct S2<const C: u16>;
+
+type Alias = S2<0>;
+impl S2<0> {}
+enum E {
+ V(S2<0>) = 0,
+}
+union U {
+ field: S2<0>
+}
+ "#,
+ expect![[r#"
+ 242..243 '0': isize
+ 46..47 '2': i32
+ 65..68 '0.0': f32
+ 90..91 '2': i32
+ 200..201 '0': i32
+ 212..213 '0': i32
+ "#]],
+ );
+}
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 74e9a8dac0..22359d8f1f 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -1271,6 +1271,7 @@ fn bar() {
241..245 'R::B': fn B<(), i32>(i32) -> R<(), i32>
241..248 'R::B(7)': R<(), i32>
246..247 '7': i32
+ 46..47 '2': usize
"#]],
);
}
@@ -3781,6 +3782,8 @@ fn main() {
371..373 'v4': usize
376..378 'v3': [u8; 4]
376..389 'v3.do_thing()': usize
+ 86..87 '4': usize
+ 192..193 '2': usize
"#]],
)
}
@@ -3820,6 +3823,9 @@ fn main() {
240..242 'v2': [u8; 2]
245..246 'v': [u8; 2]
245..257 'v.do_thing()': [u8; 2]
+ 130..131 'L': usize
+ 102..103 'L': usize
+ 130..131 'L': usize
"#]],
)
}