Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-ty/src/tests.rs | 97 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/patterns.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression.rs | 1 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression/new_solver.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/simple.rs | 39 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/traits.rs | 6 |
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 "#]], ) } |