aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/display.rs43
-rw-r--r--crates/ra_hir/src/ty/infer.rs5
-rw-r--r--crates/ra_hir/src/ty/lower.rs9
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs6
-rw-r--r--crates/ra_hir/src/ty/tests.rs39
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;
7pub struct HirFormatter<'a, 'b, DB> { 7pub 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
12pub trait HirDisplay { 15pub 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
48pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T); 77pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>);
49 78
50impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> 79impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T>
51where 80where
@@ -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};
39use crate::{ 39use 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
50macro_rules! ty_app { 49macro_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};
21use crate::{ 21use 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};
14use rustc_hash::FxHashSet;
14use test_utils::covers; 15use test_utils::covers;
15 16
16use crate::{ 17use crate::{
@@ -1980,6 +1981,30 @@ fn test() {
1980} 1981}
1981 1982
1982#[test] 1983#[test]
1984fn infer_associated_method_generics_with_default_tuple_param() {
1985 let t = type_at(
1986 r#"
1987//- /main.rs
1988struct Gen<T=()> {
1989 val: T
1990}
1991
1992impl<T> Gen<T> {
1993 pub fn make() -> Gen<T> {
1994 loop { }
1995 }
1996}
1997
1998fn test() {
1999 let a = Gen::make();
2000 a.val<|>;
2001}
2002"#,
2003 );
2004 assert_eq!(t, "()");
2005}
2006
2007#[test]
1983fn infer_associated_method_generics_without_args() { 2008fn 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