diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 82 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 127 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/coercion.rs | 103 |
3 files changed, 216 insertions, 96 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index ba63050a9..db3377357 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -14,7 +14,7 @@ | |||
14 | //! the `ena` crate, which is extracted from rustc. | 14 | //! the `ena` crate, which is extracted from rustc. |
15 | 15 | ||
16 | use std::borrow::Cow; | 16 | use std::borrow::Cow; |
17 | use std::iter::repeat; | 17 | use std::iter::{repeat, repeat_with}; |
18 | use std::mem; | 18 | use std::mem; |
19 | use std::ops::Index; | 19 | use std::ops::Index; |
20 | use std::sync::Arc; | 20 | use std::sync::Arc; |
@@ -876,10 +876,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
876 | } | 876 | } |
877 | 877 | ||
878 | /// Infer type of expression with possibly implicit coerce to the expected type. | 878 | /// Infer type of expression with possibly implicit coerce to the expected type. |
879 | /// Return the type after possible coercion. | ||
879 | fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 880 | fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
880 | let ty = self.infer_expr_inner(expr, &expected); | 881 | let ty = self.infer_expr_inner(expr, &expected); |
881 | self.coerce(&ty, &expected.ty); | 882 | let ty = if !self.coerce(&ty, &expected.ty) { |
882 | ty | 883 | self.result |
884 | .type_mismatches | ||
885 | .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }); | ||
886 | // Return actual type when type mismatch. | ||
887 | // This is needed for diagnostic when return type mismatch. | ||
888 | ty | ||
889 | } else if expected.ty == Ty::Unknown { | ||
890 | ty | ||
891 | } else { | ||
892 | expected.ty.clone() | ||
893 | }; | ||
894 | |||
895 | self.resolve_ty_as_possible(&mut vec![], ty) | ||
883 | } | 896 | } |
884 | 897 | ||
885 | /// Merge two types from different branches, with possible implicit coerce. | 898 | /// Merge two types from different branches, with possible implicit coerce. |
@@ -1328,6 +1341,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1328 | self.write_variant_resolution(tgt_expr.into(), variant); | 1341 | self.write_variant_resolution(tgt_expr.into(), variant); |
1329 | } | 1342 | } |
1330 | 1343 | ||
1344 | self.unify(&ty, &expected.ty); | ||
1345 | |||
1331 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1346 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
1332 | for (field_idx, field) in fields.iter().enumerate() { | 1347 | for (field_idx, field) in fields.iter().enumerate() { |
1333 | let field_ty = def_id | 1348 | let field_ty = def_id |
@@ -1343,7 +1358,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1343 | }) | 1358 | }) |
1344 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 1359 | .map_or(Ty::Unknown, |field| field.ty(self.db)) |
1345 | .subst(&substs); | 1360 | .subst(&substs); |
1346 | self.infer_expr(field.expr, &Expectation::has_type(field_ty)); | 1361 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
1347 | } | 1362 | } |
1348 | if let Some(expr) = spread { | 1363 | if let Some(expr) = spread { |
1349 | self.infer_expr(*expr, &Expectation::has_type(ty.clone())); | 1364 | self.infer_expr(*expr, &Expectation::has_type(ty.clone())); |
@@ -1513,35 +1528,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1513 | Ty::Unknown | 1528 | Ty::Unknown |
1514 | } | 1529 | } |
1515 | Expr::Tuple { exprs } => { | 1530 | Expr::Tuple { exprs } => { |
1516 | let mut ty_vec = Vec::with_capacity(exprs.len()); | 1531 | let mut tys = match &expected.ty { |
1517 | for arg in exprs.iter() { | 1532 | ty_app!(TypeCtor::Tuple { .. }, st) => st |
1518 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); | 1533 | .iter() |
1534 | .cloned() | ||
1535 | .chain(repeat_with(|| self.new_type_var())) | ||
1536 | .take(exprs.len()) | ||
1537 | .collect::<Vec<_>>(), | ||
1538 | _ => (0..exprs.len()).map(|_| self.new_type_var()).collect(), | ||
1539 | }; | ||
1540 | |||
1541 | for (expr, ty) in exprs.iter().zip(tys.iter_mut()) { | ||
1542 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | ||
1519 | } | 1543 | } |
1520 | 1544 | ||
1521 | Ty::apply( | 1545 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) |
1522 | TypeCtor::Tuple { cardinality: ty_vec.len() as u16 }, | ||
1523 | Substs(ty_vec.into()), | ||
1524 | ) | ||
1525 | } | 1546 | } |
1526 | Expr::Array(array) => { | 1547 | Expr::Array(array) => { |
1527 | let elem_ty = match &expected.ty { | 1548 | let elem_ty = match &expected.ty { |
1528 | Ty::Apply(a_ty) => match a_ty.ctor { | 1549 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { |
1529 | TypeCtor::Slice | TypeCtor::Array => { | 1550 | st.as_single().clone() |
1530 | Ty::clone(&a_ty.parameters.as_single()) | 1551 | } |
1531 | } | ||
1532 | _ => self.new_type_var(), | ||
1533 | }, | ||
1534 | _ => self.new_type_var(), | 1552 | _ => self.new_type_var(), |
1535 | }; | 1553 | }; |
1536 | 1554 | ||
1537 | match array { | 1555 | match array { |
1538 | Array::ElementList(items) => { | 1556 | Array::ElementList(items) => { |
1539 | for expr in items.iter() { | 1557 | for expr in items.iter() { |
1540 | self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); | 1558 | self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); |
1541 | } | 1559 | } |
1542 | } | 1560 | } |
1543 | Array::Repeat { initializer, repeat } => { | 1561 | Array::Repeat { initializer, repeat } => { |
1544 | self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone())); | 1562 | self.infer_expr_coerce( |
1563 | *initializer, | ||
1564 | &Expectation::has_type(elem_ty.clone()), | ||
1565 | ); | ||
1545 | self.infer_expr( | 1566 | self.infer_expr( |
1546 | *repeat, | 1567 | *repeat, |
1547 | &Expectation::has_type(Ty::simple(TypeCtor::Int( | 1568 | &Expectation::has_type(Ty::simple(TypeCtor::Int( |
@@ -1588,12 +1609,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1588 | Statement::Let { pat, type_ref, initializer } => { | 1609 | Statement::Let { pat, type_ref, initializer } => { |
1589 | let decl_ty = | 1610 | let decl_ty = |
1590 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); | 1611 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); |
1591 | let decl_ty = self.insert_type_vars(decl_ty); | 1612 | |
1613 | // Always use the declared type when specified | ||
1614 | let mut ty = decl_ty.clone(); | ||
1615 | |||
1592 | if let Some(expr) = initializer { | 1616 | if let Some(expr) = initializer { |
1593 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | 1617 | let actual_ty = |
1618 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | ||
1619 | if decl_ty == Ty::Unknown { | ||
1620 | ty = actual_ty; | ||
1621 | } | ||
1594 | } | 1622 | } |
1595 | 1623 | ||
1596 | let ty = self.resolve_ty_as_possible(&mut vec![], decl_ty); | 1624 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); |
1597 | self.infer_pat(*pat, &ty, BindingMode::default()); | 1625 | self.infer_pat(*pat, &ty, BindingMode::default()); |
1598 | } | 1626 | } |
1599 | Statement::Expr(expr) => { | 1627 | Statement::Expr(expr) => { |
@@ -1601,9 +1629,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1601 | } | 1629 | } |
1602 | } | 1630 | } |
1603 | } | 1631 | } |
1604 | let ty = | 1632 | |
1605 | if let Some(expr) = tail { self.infer_expr_inner(expr, expected) } else { Ty::unit() }; | 1633 | if let Some(expr) = tail { |
1606 | ty | 1634 | self.infer_expr_coerce(expr, expected) |
1635 | } else { | ||
1636 | self.coerce(&Ty::unit(), &expected.ty); | ||
1637 | Ty::unit() | ||
1638 | } | ||
1607 | } | 1639 | } |
1608 | 1640 | ||
1609 | fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) { | 1641 | fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index cd5a05092..4362bb27a 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -239,17 +239,23 @@ fn test() { | |||
239 | let a = 1isize; | 239 | let a = 1isize; |
240 | let b: usize = 1; | 240 | let b: usize = 1; |
241 | let c = b; | 241 | let c = b; |
242 | let d: u32; | ||
243 | let e; | ||
244 | let f: i32 = e; | ||
242 | } | 245 | } |
243 | "#), | 246 | "#), |
244 | @r###" | 247 | @r###" |
245 | 248 | [11; 118) '{ ...= e; }': () | |
246 | [11; 71) '{ ...= b; }': () | ||
247 | [21; 22) 'a': isize | 249 | [21; 22) 'a': isize |
248 | [25; 31) '1isize': isize | 250 | [25; 31) '1isize': isize |
249 | [41; 42) 'b': usize | 251 | [41; 42) 'b': usize |
250 | [52; 53) '1': usize | 252 | [52; 53) '1': usize |
251 | [63; 64) 'c': usize | 253 | [63; 64) 'c': usize |
252 | [67; 68) 'b': usize | 254 | [67; 68) 'b': usize |
255 | [78; 79) 'd': u32 | ||
256 | [94; 95) 'e': i32 | ||
257 | [105; 106) 'f': i32 | ||
258 | [114; 115) 'e': i32 | ||
253 | "### | 259 | "### |
254 | ); | 260 | ); |
255 | } | 261 | } |
@@ -331,14 +337,14 @@ fn test() { | |||
331 | "#), | 337 | "#), |
332 | @r###" | 338 | @r###" |
333 | [45; 49) 'self': &[T] | 339 | [45; 49) 'self': &[T] |
334 | [56; 79) '{ ... }': ! | 340 | [56; 79) '{ ... }': T |
335 | [66; 73) 'loop {}': ! | 341 | [66; 73) 'loop {}': ! |
336 | [71; 73) '{}': () | 342 | [71; 73) '{}': () |
337 | [133; 160) '{ ...o"); }': () | 343 | [133; 160) '{ ...o"); }': () |
338 | [139; 149) '<[_]>::foo': fn foo<u8>(&[T]) -> T | 344 | [139; 149) '<[_]>::foo': fn foo<u8>(&[T]) -> T |
339 | [139; 157) '<[_]>:..."foo")': u8 | 345 | [139; 157) '<[_]>:..."foo")': u8 |
340 | [150; 156) 'b"foo"': &[u8] | 346 | [150; 156) 'b"foo"': &[u8] |
341 | "### | 347 | "### |
342 | ); | 348 | ); |
343 | } | 349 | } |
344 | 350 | ||
@@ -817,7 +823,7 @@ struct A<T>(T); | |||
817 | 823 | ||
818 | impl<T> A<T> { | 824 | impl<T> A<T> { |
819 | fn foo(&self) -> &T { | 825 | fn foo(&self) -> &T { |
820 | self.0 | 826 | &self.0 |
821 | } | 827 | } |
822 | } | 828 | } |
823 | 829 | ||
@@ -837,28 +843,29 @@ fn test() { | |||
837 | @r###" | 843 | @r###" |
838 | [68; 72) 'self': &Self | 844 | [68; 72) 'self': &Self |
839 | [139; 143) 'self': &A<T> | 845 | [139; 143) 'self': &A<T> |
840 | [151; 173) '{ ... }': T | 846 | [151; 174) '{ ... }': &T |
841 | [161; 165) 'self': &A<T> | 847 | [161; 168) '&self.0': &T |
842 | [161; 167) 'self.0': T | 848 | [162; 166) 'self': &A<T> |
843 | [254; 258) 'self': &B<T> | 849 | [162; 168) 'self.0': T |
844 | [277; 300) '{ ... }': &T | 850 | [255; 259) 'self': &B<T> |
845 | [287; 294) '&self.0': &T | 851 | [278; 301) '{ ... }': &T |
846 | [288; 292) 'self': &B<T> | 852 | [288; 295) '&self.0': &T |
847 | [288; 294) 'self.0': T | 853 | [289; 293) 'self': &B<T> |
848 | [314; 352) '{ ...))); }': () | 854 | [289; 295) 'self.0': T |
849 | [324; 325) 't': &i32 | 855 | [315; 353) '{ ...))); }': () |
850 | [328; 334) 'A::foo': fn foo<i32>(&A<T>) -> &T | 856 | [325; 326) 't': &i32 |
851 | [328; 349) 'A::foo...42))))': &i32 | 857 | [329; 335) 'A::foo': fn foo<i32>(&A<T>) -> &T |
852 | [335; 348) '&&B(B(A(42)))': &&B<B<A<i32>>> | 858 | [329; 350) 'A::foo...42))))': &i32 |
853 | [336; 348) '&B(B(A(42)))': &B<B<A<i32>>> | 859 | [336; 349) '&&B(B(A(42)))': &&B<B<A<i32>>> |
854 | [337; 338) 'B': B<B<A<i32>>>(T) -> B<T> | 860 | [337; 349) '&B(B(A(42)))': &B<B<A<i32>>> |
855 | [337; 348) 'B(B(A(42)))': B<B<A<i32>>> | 861 | [338; 339) 'B': B<B<A<i32>>>(T) -> B<T> |
856 | [339; 340) 'B': B<A<i32>>(T) -> B<T> | 862 | [338; 349) 'B(B(A(42)))': B<B<A<i32>>> |
857 | [339; 347) 'B(A(42))': B<A<i32>> | 863 | [340; 341) 'B': B<A<i32>>(T) -> B<T> |
858 | [341; 342) 'A': A<i32>(T) -> A<T> | 864 | [340; 348) 'B(A(42))': B<A<i32>> |
859 | [341; 346) 'A(42)': A<i32> | 865 | [342; 343) 'A': A<i32>(T) -> A<T> |
860 | [343; 345) '42': i32 | 866 | [342; 347) 'A(42)': A<i32> |
861 | "### | 867 | [344; 346) '42': i32 |
868 | "### | ||
862 | ); | 869 | ); |
863 | } | 870 | } |
864 | 871 | ||
@@ -1109,13 +1116,12 @@ fn test(x: &str, y: isize) { | |||
1109 | 1116 | ||
1110 | let b = [a, ["b"]]; | 1117 | let b = [a, ["b"]]; |
1111 | let x: [u8; 0] = []; | 1118 | let x: [u8; 0] = []; |
1112 | let z: &[u8] = &[1, 2, 3]; | ||
1113 | } | 1119 | } |
1114 | "#), | 1120 | "#), |
1115 | @r###" | 1121 | @r###" |
1116 | [9; 10) 'x': &str | 1122 | [9; 10) 'x': &str |
1117 | [18; 19) 'y': isize | 1123 | [18; 19) 'y': isize |
1118 | [28; 324) '{ ... 3]; }': () | 1124 | [28; 293) '{ ... []; }': () |
1119 | [38; 39) 'a': [&str;_] | 1125 | [38; 39) 'a': [&str;_] |
1120 | [42; 45) '[x]': [&str;_] | 1126 | [42; 45) '[x]': [&str;_] |
1121 | [43; 44) 'x': &str | 1127 | [43; 44) 'x': &str |
@@ -1165,12 +1171,6 @@ fn test(x: &str, y: isize) { | |||
1165 | [260; 263) '"b"': &str | 1171 | [260; 263) '"b"': &str |
1166 | [275; 276) 'x': [u8;_] | 1172 | [275; 276) 'x': [u8;_] |
1167 | [288; 290) '[]': [u8;_] | 1173 | [288; 290) '[]': [u8;_] |
1168 | [300; 301) 'z': &[u8] | ||
1169 | [311; 321) '&[1, 2, 3]': &[u8;_] | ||
1170 | [312; 321) '[1, 2, 3]': [u8;_] | ||
1171 | [313; 314) '1': u8 | ||
1172 | [316; 317) '2': u8 | ||
1173 | [319; 320) '3': u8 | ||
1174 | "### | 1174 | "### |
1175 | ); | 1175 | ); |
1176 | } | 1176 | } |
@@ -1892,8 +1892,7 @@ fn test() { | |||
1892 | } | 1892 | } |
1893 | "#), | 1893 | "#), |
1894 | @r###" | 1894 | @r###" |
1895 | 1895 | [80; 104) '{ ... }': Gen<T> | |
1896 | [80; 104) '{ ... }': ! | ||
1897 | [90; 98) 'loop { }': ! | 1896 | [90; 98) 'loop { }': ! |
1898 | [95; 98) '{ }': () | 1897 | [95; 98) '{ }': () |
1899 | [118; 146) '{ ...e(); }': () | 1898 | [118; 146) '{ ...e(); }': () |
@@ -1923,8 +1922,7 @@ fn test() { | |||
1923 | } | 1922 | } |
1924 | "#), | 1923 | "#), |
1925 | @r###" | 1924 | @r###" |
1926 | 1925 | [76; 100) '{ ... }': Gen<T> | |
1927 | [76; 100) '{ ... }': ! | ||
1928 | [86; 94) 'loop { }': ! | 1926 | [86; 94) 'loop { }': ! |
1929 | [91; 94) '{ }': () | 1927 | [91; 94) '{ }': () |
1930 | [114; 149) '{ ...e(); }': () | 1928 | [114; 149) '{ ...e(); }': () |
@@ -1955,8 +1953,7 @@ fn test() { | |||
1955 | } | 1953 | } |
1956 | "#), | 1954 | "#), |
1957 | @r###" | 1955 | @r###" |
1958 | 1956 | [102; 126) '{ ... }': Gen<u32, T> | |
1959 | [102; 126) '{ ... }': ! | ||
1960 | [112; 120) 'loop { }': ! | 1957 | [112; 120) 'loop { }': ! |
1961 | [117; 120) '{ }': () | 1958 | [117; 120) '{ }': () |
1962 | [140; 180) '{ ...e(); }': () | 1959 | [140; 180) '{ ...e(); }': () |
@@ -2100,7 +2097,7 @@ fn test() { | |||
2100 | @r###" | 2097 | @r###" |
2101 | [11; 48) '{ ...&y]; }': () | 2098 | [11; 48) '{ ...&y]; }': () |
2102 | [21; 22) 'y': &{unknown} | 2099 | [21; 22) 'y': &{unknown} |
2103 | [25; 32) 'unknown': &&{unknown} | 2100 | [25; 32) 'unknown': &{unknown} |
2104 | [38; 45) '[y, &y]': [&&{unknown};_] | 2101 | [38; 45) '[y, &y]': [&&{unknown};_] |
2105 | [39; 40) 'y': &{unknown} | 2102 | [39; 40) 'y': &{unknown} |
2106 | [42; 44) '&y': &&{unknown} | 2103 | [42; 44) '&y': &&{unknown} |
@@ -2124,11 +2121,11 @@ fn test() { | |||
2124 | @r###" | 2121 | @r###" |
2125 | [11; 80) '{ ...x)]; }': () | 2122 | [11; 80) '{ ...x)]; }': () |
2126 | [21; 22) 'x': &&{unknown} | 2123 | [21; 22) 'x': &&{unknown} |
2127 | [25; 32) 'unknown': &&&{unknown} | 2124 | [25; 32) 'unknown': &&{unknown} |
2128 | [42; 43) 'y': &&{unknown} | 2125 | [42; 43) 'y': &&{unknown} |
2129 | [46; 53) 'unknown': &&&{unknown} | 2126 | [46; 53) 'unknown': &&{unknown} |
2130 | [59; 77) '[(x, y..., &x)]': [(&&{unknown}, &&{unknown});_] | 2127 | [59; 77) '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown});_] |
2131 | [60; 66) '(x, y)': (&&{unknown}, &&{unknown}) | 2128 | [60; 66) '(x, y)': (&&&{unknown}, &&&{unknown}) |
2132 | [61; 62) 'x': &&{unknown} | 2129 | [61; 62) 'x': &&{unknown} |
2133 | [64; 65) 'y': &&{unknown} | 2130 | [64; 65) 'y': &&{unknown} |
2134 | [68; 76) '(&y, &x)': (&&&{unknown}, &&&{unknown}) | 2131 | [68; 76) '(&y, &x)': (&&&{unknown}, &&&{unknown}) |
@@ -2149,7 +2146,7 @@ fn id<T>(x: T) -> T { | |||
2149 | } | 2146 | } |
2150 | 2147 | ||
2151 | fn clone<T>(x: &T) -> T { | 2148 | fn clone<T>(x: &T) -> T { |
2152 | x | 2149 | *x |
2153 | } | 2150 | } |
2154 | 2151 | ||
2155 | fn test() { | 2152 | fn test() { |
@@ -2160,26 +2157,26 @@ fn test() { | |||
2160 | } | 2157 | } |
2161 | "#), | 2158 | "#), |
2162 | @r###" | 2159 | @r###" |
2163 | |||
2164 | [10; 11) 'x': T | 2160 | [10; 11) 'x': T |
2165 | [21; 30) '{ x }': T | 2161 | [21; 30) '{ x }': T |
2166 | [27; 28) 'x': T | 2162 | [27; 28) 'x': T |
2167 | [44; 45) 'x': &T | 2163 | [44; 45) 'x': &T |
2168 | [56; 65) '{ x }': &T | 2164 | [56; 66) '{ *x }': T |
2169 | [62; 63) 'x': &T | 2165 | [62; 64) '*x': T |
2170 | [77; 157) '{ ...(1); }': () | 2166 | [63; 64) 'x': &T |
2171 | [87; 88) 'y': u32 | 2167 | [78; 158) '{ ...(1); }': () |
2172 | [91; 96) '10u32': u32 | 2168 | [88; 89) 'y': u32 |
2173 | [102; 104) 'id': fn id<u32>(T) -> T | 2169 | [92; 97) '10u32': u32 |
2174 | [102; 107) 'id(y)': u32 | 2170 | [103; 105) 'id': fn id<u32>(T) -> T |
2175 | [105; 106) 'y': u32 | 2171 | [103; 108) 'id(y)': u32 |
2176 | [117; 118) 'x': bool | 2172 | [106; 107) 'y': u32 |
2177 | [127; 132) 'clone': fn clone<bool>(&T) -> T | 2173 | [118; 119) 'x': bool |
2178 | [127; 135) 'clone(z)': bool | 2174 | [128; 133) 'clone': fn clone<bool>(&T) -> T |
2179 | [133; 134) 'z': &bool | 2175 | [128; 136) 'clone(z)': bool |
2180 | [141; 151) 'id::<i128>': fn id<i128>(T) -> T | 2176 | [134; 135) 'z': &bool |
2181 | [141; 154) 'id::<i128>(1)': i128 | 2177 | [142; 152) 'id::<i128>': fn id<i128>(T) -> T |
2182 | [152; 153) '1': i128 | 2178 | [142; 155) 'id::<i128>(1)': i128 |
2179 | [153; 154) '1': i128 | ||
2183 | "### | 2180 | "### |
2184 | ); | 2181 | ); |
2185 | } | 2182 | } |
@@ -3404,7 +3401,7 @@ impl S { | |||
3404 | } | 3401 | } |
3405 | 3402 | ||
3406 | fn test(s: Arc<S>) { | 3403 | fn test(s: Arc<S>) { |
3407 | (*s, s.foo())<|> | 3404 | (*s, s.foo())<|>; |
3408 | } | 3405 | } |
3409 | "#, | 3406 | "#, |
3410 | ); | 3407 | ); |
@@ -3488,7 +3485,7 @@ impl S { | |||
3488 | } | 3485 | } |
3489 | 3486 | ||
3490 | fn test(s: Arc<S>) { | 3487 | fn test(s: Arc<S>) { |
3491 | (*s, s.foo())<|> | 3488 | (*s, s.foo())<|>; |
3492 | } | 3489 | } |
3493 | "#, | 3490 | "#, |
3494 | ); | 3491 | ); |
diff --git a/crates/ra_hir/src/ty/tests/coercion.rs b/crates/ra_hir/src/ty/tests/coercion.rs index d80d3fb6f..1530fcc63 100644 --- a/crates/ra_hir/src/ty/tests/coercion.rs +++ b/crates/ra_hir/src/ty/tests/coercion.rs | |||
@@ -20,6 +20,97 @@ fn infer(source: &str) -> String { | |||
20 | } | 20 | } |
21 | 21 | ||
22 | #[test] | 22 | #[test] |
23 | fn infer_block_expr_type_mismatch() { | ||
24 | assert_snapshot!( | ||
25 | infer(r#" | ||
26 | fn test() { | ||
27 | let a: i32 = { 1i64 }; | ||
28 | } | ||
29 | "#), | ||
30 | @r###" | ||
31 | [11; 41) '{ ...4 }; }': () | ||
32 | [21; 22) 'a': i32 | ||
33 | [30; 38) '{ 1i64 }': i64 | ||
34 | [32; 36) '1i64': i64 | ||
35 | "###); | ||
36 | } | ||
37 | |||
38 | #[test] | ||
39 | fn coerce_places() { | ||
40 | assert_snapshot!( | ||
41 | infer(r#" | ||
42 | struct S<T> { a: T } | ||
43 | |||
44 | fn f<T>(_: &[T]) -> T { loop {} } | ||
45 | fn g<T>(_: S<&[T]>) -> T { loop {} } | ||
46 | |||
47 | fn gen<T>() -> *mut [T; 2] { loop {} } | ||
48 | fn test1<U>() -> *mut [U] { | ||
49 | gen() | ||
50 | } | ||
51 | |||
52 | fn test2() { | ||
53 | let arr: &[u8; 1] = &[1]; | ||
54 | |||
55 | let a: &[_] = arr; | ||
56 | let b = f(arr); | ||
57 | let c: &[_] = { arr }; | ||
58 | let d = g(S { a: arr }); | ||
59 | let e: [&[_]; 1] = [arr]; | ||
60 | let f: [&[_]; 2] = [arr; 2]; | ||
61 | let g: (&[_], &[_]) = (arr, arr); | ||
62 | } | ||
63 | "#), | ||
64 | @r###" | ||
65 | [31; 32) '_': &[T] | ||
66 | [45; 56) '{ loop {} }': T | ||
67 | [47; 54) 'loop {}': ! | ||
68 | [52; 54) '{}': () | ||
69 | [65; 66) '_': S<&[T]> | ||
70 | [82; 93) '{ loop {} }': T | ||
71 | [84; 91) 'loop {}': ! | ||
72 | [89; 91) '{}': () | ||
73 | [122; 133) '{ loop {} }': *mut [T;_] | ||
74 | [124; 131) 'loop {}': ! | ||
75 | [129; 131) '{}': () | ||
76 | [160; 173) '{ gen() }': *mut [U] | ||
77 | [166; 169) 'gen': fn gen<U>() -> *mut [T;_] | ||
78 | [166; 171) 'gen()': *mut [U;_] | ||
79 | [186; 420) '{ ...rr); }': () | ||
80 | [196; 199) 'arr': &[u8;_] | ||
81 | [212; 216) '&[1]': &[u8;_] | ||
82 | [213; 216) '[1]': [u8;_] | ||
83 | [214; 215) '1': u8 | ||
84 | [227; 228) 'a': &[u8] | ||
85 | [237; 240) 'arr': &[u8;_] | ||
86 | [250; 251) 'b': u8 | ||
87 | [254; 255) 'f': fn f<u8>(&[T]) -> T | ||
88 | [254; 260) 'f(arr)': u8 | ||
89 | [256; 259) 'arr': &[u8;_] | ||
90 | [270; 271) 'c': &[u8] | ||
91 | [280; 287) '{ arr }': &[u8] | ||
92 | [282; 285) 'arr': &[u8;_] | ||
93 | [297; 298) 'd': u8 | ||
94 | [301; 302) 'g': fn g<u8>(S<&[T]>) -> T | ||
95 | [301; 316) 'g(S { a: arr })': u8 | ||
96 | [303; 315) 'S { a: arr }': S<&[u8]> | ||
97 | [310; 313) 'arr': &[u8;_] | ||
98 | [326; 327) 'e': [&[u8];_] | ||
99 | [341; 346) '[arr]': [&[u8];_] | ||
100 | [342; 345) 'arr': &[u8;_] | ||
101 | [356; 357) 'f': [&[u8];_] | ||
102 | [371; 379) '[arr; 2]': [&[u8];_] | ||
103 | [372; 375) 'arr': &[u8;_] | ||
104 | [377; 378) '2': usize | ||
105 | [389; 390) 'g': (&[u8], &[u8]) | ||
106 | [407; 417) '(arr, arr)': (&[u8], &[u8]) | ||
107 | [408; 411) 'arr': &[u8;_] | ||
108 | [413; 416) 'arr': &[u8;_] | ||
109 | "### | ||
110 | ); | ||
111 | } | ||
112 | |||
113 | #[test] | ||
23 | fn infer_let_stmt_coerce() { | 114 | fn infer_let_stmt_coerce() { |
24 | assert_snapshot!( | 115 | assert_snapshot!( |
25 | infer(r#" | 116 | infer(r#" |
@@ -102,7 +193,7 @@ fn test() { | |||
102 | "#), | 193 | "#), |
103 | @r###" | 194 | @r###" |
104 | [11; 12) 'x': &[T] | 195 | [11; 12) 'x': &[T] |
105 | [28; 39) '{ loop {} }': ! | 196 | [28; 39) '{ loop {} }': &[T] |
106 | [30; 37) 'loop {}': ! | 197 | [30; 37) 'loop {}': ! |
107 | [35; 37) '{}': () | 198 | [35; 37) '{}': () |
108 | [50; 126) '{ ... }; }': () | 199 | [50; 126) '{ ... }; }': () |
@@ -119,7 +210,7 @@ fn test() { | |||
119 | [113; 117) '&[1]': &[i32;_] | 210 | [113; 117) '&[1]': &[i32;_] |
120 | [114; 117) '[1]': [i32;_] | 211 | [114; 117) '[1]': [i32;_] |
121 | [115; 116) '1': i32 | 212 | [115; 116) '1': i32 |
122 | "### | 213 | "### |
123 | ); | 214 | ); |
124 | } | 215 | } |
125 | 216 | ||
@@ -138,7 +229,7 @@ fn test() { | |||
138 | "#), | 229 | "#), |
139 | @r###" | 230 | @r###" |
140 | [11; 12) 'x': &[T] | 231 | [11; 12) 'x': &[T] |
141 | [28; 39) '{ loop {} }': ! | 232 | [28; 39) '{ loop {} }': &[T] |
142 | [30; 37) 'loop {}': ! | 233 | [30; 37) 'loop {}': ! |
143 | [35; 37) '{}': () | 234 | [35; 37) '{}': () |
144 | [50; 126) '{ ... }; }': () | 235 | [50; 126) '{ ... }; }': () |
@@ -155,7 +246,7 @@ fn test() { | |||
155 | [112; 116) '&[1]': &[i32;_] | 246 | [112; 116) '&[1]': &[i32;_] |
156 | [113; 116) '[1]': [i32;_] | 247 | [113; 116) '[1]': [i32;_] |
157 | [114; 115) '1': i32 | 248 | [114; 115) '1': i32 |
158 | "### | 249 | "### |
159 | ); | 250 | ); |
160 | } | 251 | } |
161 | 252 | ||
@@ -174,7 +265,7 @@ fn test(i: i32) { | |||
174 | "#), | 265 | "#), |
175 | @r###" | 266 | @r###" |
176 | [11; 12) 'x': &[T] | 267 | [11; 12) 'x': &[T] |
177 | [28; 39) '{ loop {} }': ! | 268 | [28; 39) '{ loop {} }': &[T] |
178 | [30; 37) 'loop {}': ! | 269 | [30; 37) 'loop {}': ! |
179 | [35; 37) '{}': () | 270 | [35; 37) '{}': () |
180 | [48; 49) 'i': i32 | 271 | [48; 49) 'i': i32 |
@@ -215,7 +306,7 @@ fn test(i: i32) { | |||
215 | "#), | 306 | "#), |
216 | @r###" | 307 | @r###" |
217 | [11; 12) 'x': &[T] | 308 | [11; 12) 'x': &[T] |
218 | [28; 39) '{ loop {} }': ! | 309 | [28; 39) '{ loop {} }': &[T] |
219 | [30; 37) 'loop {}': ! | 310 | [30; 37) 'loop {}': ! |
220 | [35; 37) '{}': () | 311 | [35; 37) '{}': () |
221 | [48; 49) 'i': i32 | 312 | [48; 49) 'i': i32 |