aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/display.rs63
-rw-r--r--crates/ra_hir_ty/src/infer.rs8
-rw-r--r--crates/ra_hir_ty/src/op.rs3
-rw-r--r--crates/ra_hir_ty/src/tests/display_source_code.rs27
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs29
5 files changed, 100 insertions, 30 deletions
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs
index f5edaea8c..b9c4d2e89 100644
--- a/crates/ra_hir_ty/src/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
@@ -136,6 +136,12 @@ enum DisplayTarget {
136 SourceCode { module_id: ModuleId }, 136 SourceCode { module_id: ModuleId },
137} 137}
138 138
139impl DisplayTarget {
140 fn is_source_code(&self) -> bool {
141 matches!(self, Self::SourceCode {..})
142 }
143}
144
139#[derive(Debug)] 145#[derive(Debug)]
140pub enum DisplaySourceCodeError { 146pub enum DisplaySourceCodeError {
141 PathNotFound, 147 PathNotFound,
@@ -303,37 +309,40 @@ impl HirDisplay for ApplicationTy {
303 309
304 if self.parameters.len() > 0 { 310 if self.parameters.len() > 0 {
305 let mut non_default_parameters = Vec::with_capacity(self.parameters.len()); 311 let mut non_default_parameters = Vec::with_capacity(self.parameters.len());
306 let parameters_to_write = if f.omit_verbose_types() { 312 let parameters_to_write =
307 match self 313 if f.display_target.is_source_code() || f.omit_verbose_types() {
308 .ctor 314 match self
309 .as_generic_def() 315 .ctor
310 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 316 .as_generic_def()
311 .filter(|defaults| !defaults.is_empty()) 317 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
312 { 318 .filter(|defaults| !defaults.is_empty())
313 None => self.parameters.0.as_ref(), 319 {
314 Some(default_parameters) => { 320 None => self.parameters.0.as_ref(),
315 for (i, parameter) in self.parameters.iter().enumerate() { 321 Some(default_parameters) => {
316 match (parameter, default_parameters.get(i)) { 322 for (i, parameter) in self.parameters.iter().enumerate() {
317 (&Ty::Unknown, _) | (_, None) => { 323 match (parameter, default_parameters.get(i)) {
318 non_default_parameters.push(parameter.clone()) 324 (&Ty::Unknown, _) | (_, None) => {
319 } 325 non_default_parameters.push(parameter.clone())
320 (_, Some(default_parameter)) 326 }
321 if parameter != default_parameter => 327 (_, Some(default_parameter))
322 { 328 if parameter != default_parameter =>
323 non_default_parameters.push(parameter.clone()) 329 {
330 non_default_parameters.push(parameter.clone())
331 }
332 _ => (),
324 } 333 }
325 _ => (),
326 } 334 }
335 &non_default_parameters
327 } 336 }
328 &non_default_parameters
329 } 337 }
330 } 338 } else {
331 } else { 339 self.parameters.0.as_ref()
332 self.parameters.0.as_ref() 340 };
333 }; 341 if !parameters_to_write.is_empty() {
334 write!(f, "<")?; 342 write!(f, "<")?;
335 f.write_joined(parameters_to_write, ", ")?; 343 f.write_joined(parameters_to_write, ", ")?;
336 write!(f, ">")?; 344 write!(f, ">")?;
345 }
337 } 346 }
338 } 347 }
339 TypeCtor::AssociatedType(type_alias) => { 348 TypeCtor::AssociatedType(type_alias) => {
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index a21ad8d86..fb7c6cd8c 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -22,7 +22,7 @@ use rustc_hash::FxHashMap;
22 22
23use hir_def::{ 23use hir_def::{
24 body::Body, 24 body::Body,
25 data::{ConstData, FunctionData}, 25 data::{ConstData, FunctionData, StaticData},
26 expr::{BindingAnnotation, ExprId, PatId}, 26 expr::{BindingAnnotation, ExprId, PatId},
27 lang_item::LangItemTarget, 27 lang_item::LangItemTarget,
28 path::{path, Path}, 28 path::{path, Path},
@@ -71,7 +71,7 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
71 match def { 71 match def {
72 DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)), 72 DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
73 DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)), 73 DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)),
74 DefWithBodyId::StaticId(s) => ctx.collect_const(&db.static_data(s)), 74 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
75 } 75 }
76 76
77 ctx.infer_body(); 77 ctx.infer_body();
@@ -485,6 +485,10 @@ impl<'a> InferenceContext<'a> {
485 self.return_ty = self.make_ty(&data.type_ref); 485 self.return_ty = self.make_ty(&data.type_ref);
486 } 486 }
487 487
488 fn collect_static(&mut self, data: &StaticData) {
489 self.return_ty = self.make_ty(&data.type_ref);
490 }
491
488 fn collect_fn(&mut self, data: &FunctionData) { 492 fn collect_fn(&mut self, data: &FunctionData) {
489 let body = Arc::clone(&self.body); // avoid borrow checker problem 493 let body = Arc::clone(&self.body); // avoid borrow checker problem
490 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 494 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
diff --git a/crates/ra_hir_ty/src/op.rs b/crates/ra_hir_ty/src/op.rs
index 54e2bd05a..0870874fc 100644
--- a/crates/ra_hir_ty/src/op.rs
+++ b/crates/ra_hir_ty/src/op.rs
@@ -30,7 +30,8 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
31 match op { 31 match op {
32 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), 32 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool),
33 BinaryOp::Assignment { op: None } | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { 33 BinaryOp::Assignment { op: None } => lhs_ty,
34 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty {
34 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 35 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
35 TypeCtor::Int(..) 36 TypeCtor::Int(..)
36 | TypeCtor::Float(..) 37 | TypeCtor::Float(..)
diff --git a/crates/ra_hir_ty/src/tests/display_source_code.rs b/crates/ra_hir_ty/src/tests/display_source_code.rs
index ca1748615..4088b1d22 100644
--- a/crates/ra_hir_ty/src/tests/display_source_code.rs
+++ b/crates/ra_hir_ty/src/tests/display_source_code.rs
@@ -21,3 +21,30 @@ fn bar() {
21 ); 21 );
22 assert_eq!("foo::Foo", displayed_source_at_pos(&db, pos)); 22 assert_eq!("foo::Foo", displayed_source_at_pos(&db, pos));
23} 23}
24
25#[test]
26fn omit_default_type_parameters() {
27 let (db, pos) = TestDB::with_position(
28 r"
29 //- /main.rs
30 struct Foo<T = u8> { t: T }
31 fn main() {
32 let foo = Foo { t: 5 };
33 foo<|>;
34 }
35 ",
36 );
37 assert_eq!("Foo", displayed_source_at_pos(&db, pos));
38
39 let (db, pos) = TestDB::with_position(
40 r"
41 //- /main.rs
42 struct Foo<K, T = u8> { k: K, t: T }
43 fn main() {
44 let foo = Foo { k: 400, t: 5 };
45 foo<|>;
46 }
47 ",
48 );
49 assert_eq!("Foo<i32>", displayed_source_at_pos(&db, pos));
50}
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 3820175f6..322838f02 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -1787,3 +1787,32 @@ fn main() {
1787 "### 1787 "###
1788 ) 1788 )
1789} 1789}
1790
1791#[test]
1792fn infer_generic_from_later_assignment() {
1793 assert_snapshot!(
1794 infer(r#"
1795enum Option<T> { Some(T), None }
1796use Option::*;
1797
1798fn test() {
1799 let mut end = None;
1800 loop {
1801 end = Some(true);
1802 }
1803}
1804"#),
1805 @r###"
1806 60..130 '{ ... } }': ()
1807 70..77 'mut end': Option<bool>
1808 80..84 'None': Option<bool>
1809 90..128 'loop {... }': !
1810 95..128 '{ ... }': ()
1811 105..108 'end': Option<bool>
1812 105..121 'end = ...(true)': ()
1813 111..115 'Some': Some<bool>(bool) -> Option<bool>
1814 111..121 'Some(true)': Option<bool>
1815 116..120 'true': bool
1816 "###
1817 );
1818}