diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/display.rs | 43 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 39 |
5 files changed, 81 insertions, 21 deletions
diff --git a/crates/ra_hir/src/ty/display.rs b/crates/ra_hir/src/ty/display.rs index 7910429d7..9bb3ece6c 100644 --- a/crates/ra_hir/src/ty/display.rs +++ b/crates/ra_hir/src/ty/display.rs | |||
@@ -7,15 +7,30 @@ use crate::db::HirDatabase; | |||
7 | pub struct HirFormatter<'a, 'b, DB> { | 7 | pub struct HirFormatter<'a, 'b, DB> { |
8 | pub db: &'a DB, | 8 | pub db: &'a DB, |
9 | fmt: &'a mut fmt::Formatter<'b>, | 9 | fmt: &'a mut fmt::Formatter<'b>, |
10 | buf: String, | ||
11 | curr_size: usize, | ||
12 | max_size: Option<usize>, | ||
10 | } | 13 | } |
11 | 14 | ||
12 | pub trait HirDisplay { | 15 | pub trait HirDisplay { |
13 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result; | 16 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result; |
17 | |||
14 | fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> | 18 | fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> |
15 | where | 19 | where |
16 | Self: Sized, | 20 | Self: Sized, |
17 | { | 21 | { |
18 | HirDisplayWrapper(db, self) | 22 | HirDisplayWrapper(db, self, None) |
23 | } | ||
24 | |||
25 | fn display_truncated<'a, DB>( | ||
26 | &'a self, | ||
27 | db: &'a DB, | ||
28 | max_size: Option<usize>, | ||
29 | ) -> HirDisplayWrapper<'a, DB, Self> | ||
30 | where | ||
31 | Self: Sized, | ||
32 | { | ||
33 | HirDisplayWrapper(db, self, max_size) | ||
19 | } | 34 | } |
20 | } | 35 | } |
21 | 36 | ||
@@ -41,11 +56,25 @@ where | |||
41 | 56 | ||
42 | /// This allows using the `write!` macro directly with a `HirFormatter`. | 57 | /// This allows using the `write!` macro directly with a `HirFormatter`. |
43 | pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { | 58 | pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { |
44 | fmt::write(self.fmt, args) | 59 | // We write to a buffer first to track output size |
60 | self.buf.clear(); | ||
61 | fmt::write(&mut self.buf, args)?; | ||
62 | self.curr_size += self.buf.len(); | ||
63 | |||
64 | // Then we write to the internal formatter from the buffer | ||
65 | self.fmt.write_str(&self.buf) | ||
66 | } | ||
67 | |||
68 | pub fn should_truncate(&self) -> bool { | ||
69 | if let Some(max_size) = self.max_size { | ||
70 | self.curr_size >= max_size | ||
71 | } else { | ||
72 | false | ||
73 | } | ||
45 | } | 74 | } |
46 | } | 75 | } |
47 | 76 | ||
48 | pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T); | 77 | pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>); |
49 | 78 | ||
50 | impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> | 79 | impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> |
51 | where | 80 | where |
@@ -53,6 +82,12 @@ where | |||
53 | T: HirDisplay, | 82 | T: HirDisplay, |
54 | { | 83 | { |
55 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 84 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
56 | self.1.hir_fmt(&mut HirFormatter { db: self.0, fmt: f }) | 85 | self.1.hir_fmt(&mut HirFormatter { |
86 | db: self.0, | ||
87 | fmt: f, | ||
88 | buf: String::with_capacity(20), | ||
89 | curr_size: 0, | ||
90 | max_size: self.2, | ||
91 | }) | ||
57 | } | 92 | } |
58 | } | 93 | } |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c35378cc4..7f9e81d64 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -37,14 +37,13 @@ use super::{ | |||
37 | TypeCtor, TypeWalk, Uncertain, | 37 | TypeCtor, TypeWalk, Uncertain, |
38 | }; | 38 | }; |
39 | use crate::{ | 39 | use crate::{ |
40 | adt::VariantDef, | ||
41 | code_model::TypeAlias, | 40 | code_model::TypeAlias, |
42 | db::HirDatabase, | 41 | db::HirDatabase, |
43 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 42 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
44 | resolve::{Resolver, TypeNs}, | 43 | resolve::{HasResolver, Resolver, TypeNs}, |
45 | ty::infer::diagnostics::InferenceDiagnostic, | 44 | ty::infer::diagnostics::InferenceDiagnostic, |
46 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, | 45 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, |
47 | StructField, | 46 | StructField, VariantDef, |
48 | }; | 47 | }; |
49 | 48 | ||
50 | macro_rules! ty_app { | 49 | macro_rules! ty_app { |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index de3c56097..397ee7d5f 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -19,18 +19,17 @@ use super::{ | |||
19 | TypeWalk, | 19 | TypeWalk, |
20 | }; | 20 | }; |
21 | use crate::{ | 21 | use crate::{ |
22 | adt::VariantDef, | ||
23 | db::HirDatabase, | 22 | db::HirDatabase, |
24 | generics::HasGenericParams, | 23 | generics::HasGenericParams, |
25 | generics::{GenericDef, WherePredicate}, | 24 | generics::{GenericDef, WherePredicate}, |
26 | resolve::{Resolver, TypeNs}, | 25 | resolve::{HasResolver, Resolver, TypeNs}, |
27 | ty::{ | 26 | ty::{ |
28 | primitive::{FloatTy, IntTy, Uncertain}, | 27 | primitive::{FloatTy, IntTy, Uncertain}, |
29 | Adt, | 28 | Adt, |
30 | }, | 29 | }, |
31 | util::make_mut_slice, | 30 | util::make_mut_slice, |
32 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, | 31 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, |
33 | TypeAlias, Union, | 32 | TypeAlias, Union, VariantDef, |
34 | }; | 33 | }; |
35 | 34 | ||
36 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -611,9 +610,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> | |||
611 | let defaults = generic_params | 610 | let defaults = generic_params |
612 | .params_including_parent() | 611 | .params_including_parent() |
613 | .into_iter() | 612 | .into_iter() |
614 | .map(|p| { | 613 | .map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) |
615 | p.default.as_ref().map_or(Ty::Unknown, |path| Ty::from_hir_path(db, &resolver, path)) | ||
616 | }) | ||
617 | .collect(); | 614 | .collect(); |
618 | 615 | ||
619 | Substs(defaults) | 616 | Substs(defaults) |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index d20aeaacf..f377fca48 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -232,8 +232,8 @@ fn iterate_trait_method_candidates<T>( | |||
232 | // trait, but if we find out it doesn't, we'll skip the rest of the | 232 | // trait, but if we find out it doesn't, we'll skip the rest of the |
233 | // iteration | 233 | // iteration |
234 | let mut known_implemented = false; | 234 | let mut known_implemented = false; |
235 | for &item in data.items() { | 235 | for &item in data.items.iter() { |
236 | if !is_valid_candidate(db, name, mode, item) { | 236 | if !is_valid_candidate(db, name, mode, item.into()) { |
237 | continue; | 237 | continue; |
238 | } | 238 | } |
239 | if !known_implemented { | 239 | if !known_implemented { |
@@ -243,7 +243,7 @@ fn iterate_trait_method_candidates<T>( | |||
243 | } | 243 | } |
244 | } | 244 | } |
245 | known_implemented = true; | 245 | known_implemented = true; |
246 | if let Some(result) = callback(&ty.value, item) { | 246 | if let Some(result) = callback(&ty.value, item.into()) { |
247 | return Some(result); | 247 | return Some(result); |
248 | } | 248 | } |
249 | } | 249 | } |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index ca1693679..74c12a0a2 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -11,6 +11,7 @@ use ra_syntax::{ | |||
11 | ast::{self, AstNode}, | 11 | ast::{self, AstNode}, |
12 | SyntaxKind::*, | 12 | SyntaxKind::*, |
13 | }; | 13 | }; |
14 | use rustc_hash::FxHashSet; | ||
14 | use test_utils::covers; | 15 | use test_utils::covers; |
15 | 16 | ||
16 | use crate::{ | 17 | use crate::{ |
@@ -1980,6 +1981,30 @@ fn test() { | |||
1980 | } | 1981 | } |
1981 | 1982 | ||
1982 | #[test] | 1983 | #[test] |
1984 | fn infer_associated_method_generics_with_default_tuple_param() { | ||
1985 | let t = type_at( | ||
1986 | r#" | ||
1987 | //- /main.rs | ||
1988 | struct Gen<T=()> { | ||
1989 | val: T | ||
1990 | } | ||
1991 | |||
1992 | impl<T> Gen<T> { | ||
1993 | pub fn make() -> Gen<T> { | ||
1994 | loop { } | ||
1995 | } | ||
1996 | } | ||
1997 | |||
1998 | fn test() { | ||
1999 | let a = Gen::make(); | ||
2000 | a.val<|>; | ||
2001 | } | ||
2002 | "#, | ||
2003 | ); | ||
2004 | assert_eq!(t, "()"); | ||
2005 | } | ||
2006 | |||
2007 | #[test] | ||
1983 | fn infer_associated_method_generics_without_args() { | 2008 | fn infer_associated_method_generics_without_args() { |
1984 | assert_snapshot!( | 2009 | assert_snapshot!( |
1985 | infer(r#" | 2010 | infer(r#" |
@@ -2494,7 +2519,6 @@ fn test() { | |||
2494 | [167; 179) 'GLOBAL_CONST': u32 | 2519 | [167; 179) 'GLOBAL_CONST': u32 |
2495 | [189; 191) 'id': u32 | 2520 | [189; 191) 'id': u32 |
2496 | [194; 210) 'Foo::A..._CONST': u32 | 2521 | [194; 210) 'Foo::A..._CONST': u32 |
2497 | [126; 128) '99': u32 | ||
2498 | "### | 2522 | "### |
2499 | ); | 2523 | ); |
2500 | } | 2524 | } |
@@ -4694,14 +4718,16 @@ fn infer(content: &str) -> String { | |||
4694 | } | 4718 | } |
4695 | 4719 | ||
4696 | // sort ranges for consistency | 4720 | // sort ranges for consistency |
4697 | types.sort_by_key(|(src_ptr, _)| (src_ptr.ast.range().start(), src_ptr.ast.range().end())); | 4721 | types.sort_by_key(|(src_ptr, _)| { |
4722 | (src_ptr.value.range().start(), src_ptr.value.range().end()) | ||
4723 | }); | ||
4698 | for (src_ptr, ty) in &types { | 4724 | for (src_ptr, ty) in &types { |
4699 | let node = src_ptr.ast.to_node(&src_ptr.file_syntax(&db)); | 4725 | let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db)); |
4700 | 4726 | ||
4701 | let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { | 4727 | let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { |
4702 | (self_param.self_kw_token().text_range(), "self".to_string()) | 4728 | (self_param.self_kw_token().text_range(), "self".to_string()) |
4703 | } else { | 4729 | } else { |
4704 | (src_ptr.ast.range(), node.text().to_string().replace("\n", " ")) | 4730 | (src_ptr.value.range(), node.text().to_string().replace("\n", " ")) |
4705 | }; | 4731 | }; |
4706 | let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; | 4732 | let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; |
4707 | write!( | 4733 | write!( |
@@ -4716,10 +4742,13 @@ fn infer(content: &str) -> String { | |||
4716 | } | 4742 | } |
4717 | }; | 4743 | }; |
4718 | 4744 | ||
4745 | let mut analyzed = FxHashSet::default(); | ||
4719 | for node in source_file.syntax().descendants() { | 4746 | for node in source_file.syntax().descendants() { |
4720 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { | 4747 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { |
4721 | let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); | 4748 | let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); |
4722 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); | 4749 | if analyzed.insert(analyzer.analyzed_declaration()) { |
4750 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); | ||
4751 | } | ||
4723 | } | 4752 | } |
4724 | } | 4753 | } |
4725 | 4754 | ||