aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/ty/infer.rs82
-rw-r--r--crates/ra_hir/src/ty/tests.rs127
-rw-r--r--crates/ra_hir/src/ty/tests/coercion.rs103
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
16use std::borrow::Cow; 16use std::borrow::Cow;
17use std::iter::repeat; 17use std::iter::{repeat, repeat_with};
18use std::mem; 18use std::mem;
19use std::ops::Index; 19use std::ops::Index;
20use std::sync::Arc; 20use 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
818impl<T> A<T> { 824impl<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
2151fn clone<T>(x: &T) -> T { 2148fn clone<T>(x: &T) -> T {
2152 x 2149 *x
2153} 2150}
2154 2151
2155fn test() { 2152fn 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
3406fn test(s: Arc<S>) { 3403fn 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
3490fn test(s: Arc<S>) { 3487fn 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]
23fn infer_block_expr_type_mismatch() {
24 assert_snapshot!(
25 infer(r#"
26fn 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]
39fn coerce_places() {
40 assert_snapshot!(
41 infer(r#"
42struct S<T> { a: T }
43
44fn f<T>(_: &[T]) -> T { loop {} }
45fn g<T>(_: S<&[T]>) -> T { loop {} }
46
47fn gen<T>() -> *mut [T; 2] { loop {} }
48fn test1<U>() -> *mut [U] {
49 gen()
50}
51
52fn 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]
23fn infer_let_stmt_coerce() { 114fn 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