From 408f914bf4d6719ae68582ae43e2de9d3cb362b0 Mon Sep 17 00:00:00 2001 From: Josh Mcguigan Date: Fri, 17 Apr 2020 05:36:44 -0700 Subject: fix panic on ellipsis in pattern --- crates/ra_hir_ty/src/tests/regression.rs | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index d69115a2f..61284d672 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -484,3 +484,52 @@ fn main() { assert_eq!("()", super::type_at_pos(&db, pos)); } + +#[test] +fn issue_3999_slice() { + assert_snapshot!( + infer(r#" +fn foo(params: &[usize]) { + match params { + [ps @ .., _] => {} + } +} +"#), + @r###" + [8; 14) 'params': &[usize] + [26; 81) '{ ... } }': () + [32; 79) 'match ... }': () + [38; 44) 'params': &[usize] + [55; 67) '[ps @ .., _]': [usize] + [65; 66) '_': usize + [71; 73) '{}': () + "### + ); +} + +#[test] +fn issue_3999_struct() { + // rust-analyzer should not panic on seeing this malformed + // record pattern. + assert_snapshot!( + infer(r#" +struct Bar { + a: bool, +} +fn foo(b: Bar) { + match b { + Bar { a: .. } => {}, + } +} +"#), + @r###" + [36; 37) 'b': Bar + [44; 96) '{ ... } }': () + [50; 94) 'match ... }': () + [56; 57) 'b': Bar + [68; 81) 'Bar { a: .. }': Bar + [77; 79) '..': bool + [85; 87) '{}': () + "### + ); +} -- cgit v1.2.3 From fbd95785a6746a8bf100a0417b592f5fa35df882 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 17 Apr 2020 18:27:20 +0200 Subject: Add two more tests for associated types --- crates/ra_hir_ty/src/tests/traits.rs | 174 +++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 0a889f805..dc517fc4a 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -2204,3 +2204,177 @@ fn test(x: Box) { ); assert_eq!(t, "()"); } + +#[test] +fn string_to_owned() { + let t = type_at( + r#" +//- /main.rs +struct String {} +pub trait ToOwned { + type Owned; + fn to_owned(&self) -> Self::Owned; +} +impl ToOwned for str { + type Owned = String; +} +fn test() { + "foo".to_owned()<|>; +} +"#, + ); + assert_eq!(t, "String"); +} + +#[test] +fn iterator_chain() { + assert_snapshot!( + infer(r#" +//- /main.rs +#[lang = "fn_once"] +trait FnOnce { + type Output; +} +#[lang = "fn_mut"] +trait FnMut: FnOnce { } + +enum Option { Some(T), None } +use Option::*; + +pub trait Iterator { + type Item; + + fn filter_map(self, f: F) -> FilterMap + where + F: FnMut(Self::Item) -> Option, + { loop {} } + + fn for_each(self, f: F) + where + F: FnMut(Self::Item), + { loop {} } +} + +pub trait IntoIterator { + type Item; + type IntoIter: Iterator; + fn into_iter(self) -> Self::IntoIter; +} + +pub struct FilterMap { } +impl Iterator for FilterMap +where + F: FnMut(I::Item) -> Option, +{ + type Item = B; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +struct Vec {} +impl Vec { + fn new() -> Self { loop {} } +} + +impl IntoIterator for Vec { + type Item = T; + type IntoIter = IntoIter; +} + +pub struct IntoIter { } +impl Iterator for IntoIter { + type Item = T; +} + +fn main() { + Vec::::new().into_iter() + .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) + .for_each(|y| { y; }); +} +"#), + @r###" + [240; 244) 'self': Self + [246; 247) 'f': F + [331; 342) '{ loop {} }': FilterMap + [333; 340) 'loop {}': ! + [338; 340) '{}': () + [363; 367) 'self': Self + [369; 370) 'f': F + [419; 430) '{ loop {} }': () + [421; 428) 'loop {}': ! + [426; 428) '{}': () + [539; 543) 'self': Self + [868; 872) 'self': I + [879; 899) '{ ... }': I + [889; 893) 'self': I + [958; 969) '{ loop {} }': Vec + [960; 967) 'loop {}': ! + [965; 967) '{}': () + [1156; 1287) '{ ... }); }': () + [1162; 1177) 'Vec::::new': fn new() -> Vec + [1162; 1179) 'Vec::<...:new()': Vec + [1162; 1191) 'Vec::<...iter()': IntoIter + [1162; 1256) 'Vec::<...one })': FilterMap, |i32| -> Option> + [1162; 1284) 'Vec::<... y; })': () + [1210; 1255) '|x| if...None }': |i32| -> Option + [1211; 1212) 'x': i32 + [1214; 1255) 'if x >...None }': Option + [1217; 1218) 'x': i32 + [1217; 1222) 'x > 0': bool + [1221; 1222) '0': i32 + [1223; 1241) '{ Some...u32) }': Option + [1225; 1229) 'Some': Some(u32) -> Option + [1225; 1239) 'Some(x as u32)': Option + [1230; 1231) 'x': i32 + [1230; 1238) 'x as u32': u32 + [1247; 1255) '{ None }': Option + [1249; 1253) 'None': Option + [1273; 1283) '|y| { y; }': |u32| -> () + [1274; 1275) 'y': u32 + [1277; 1283) '{ y; }': () + [1279; 1280) 'y': u32 + "### + ); +} + +#[test] +fn nested_assoc() { + let t = type_at( + r#" +//- /main.rs +struct Bar; +struct Foo; + +trait A { + type OutputA; +} + +impl A for Bar { + type OutputA = Foo; +} + +trait B { + type Output; + fn foo() -> Self::Output; +} + +impl B for T { + type Output = T::OutputA; + fn foo() -> Self::Output { loop {} } +} + +fn main() { + Bar::foo()<|>; +} +"#, + ); + assert_eq!(t, "Foo"); +} -- cgit v1.2.3 From 6a7fc76b89dca4d1b4e3e50047183535aee98627 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 17 Apr 2020 19:41:37 +0200 Subject: Fix type equality for dyn Trait Fixes a lot of false type mismatches. (And as always when touching the unification code, I have to say I'm looking forward to replacing it by Chalk's...) --- crates/ra_hir_ty/src/tests/traits.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index dc517fc4a..f6e3e07cd 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -2378,3 +2378,27 @@ fn main() { ); assert_eq!(t, "Foo"); } + +#[test] +fn trait_object_no_coercion() { + assert_snapshot!( + infer_with_mismatches(r#" +trait Foo {} + +fn foo(x: &dyn Foo) {} + +fn test(x: &dyn Foo) { + foo(x); +} +"#, true), + @r###" + [22; 23) 'x': &dyn Foo + [35; 37) '{}': () + [47; 48) 'x': &dyn Foo + [60; 75) '{ foo(x); }': () + [66; 69) 'foo': fn foo(&dyn Foo) + [66; 72) 'foo(x)': () + [70; 71) 'x': &dyn Foo + "### + ); +} -- cgit v1.2.3 From d3cb9ea0bfb6c9e6c8b57a46feb1de696084d994 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 17 Apr 2020 22:48:29 +0200 Subject: Fix another crash from wrong binders Basically, if we had something like `dyn Trait` (where `T` is a type parameter) in an impl we lowered that to `dyn Trait<^0.0>`, when it should be `dyn Trait<^1.0>` because the `dyn` introduces a new binder. With one type parameter, that's just wrong, with two, it'll lead to crashes. --- crates/ra_hir_ty/src/tests/traits.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 0a889f805..36f53b264 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -1210,6 +1210,42 @@ fn test(x: dyn Trait, y: &dyn Trait) { ); } +#[test] +fn dyn_trait_in_impl() { + assert_snapshot!( + infer(r#" +trait Trait { + fn foo(&self) -> (T, U); +} +struct S {} +impl S { + fn bar(&self) -> &dyn Trait { loop {} } +} +trait Trait2 { + fn baz(&self) -> (T, U); +} +impl Trait2 for dyn Trait { } + +fn test(s: S) { + s.bar().baz(); +} +"#), + @r###" + [33; 37) 'self': &Self + [103; 107) 'self': &S + [129; 140) '{ loop {} }': &dyn Trait + [131; 138) 'loop {}': ! + [136; 138) '{}': () + [176; 180) 'self': &Self + [252; 253) 's': S + [268; 290) '{ ...z(); }': () + [274; 275) 's': S + [274; 281) 's.bar()': &dyn Trait + [274; 287) 's.bar().baz()': (u32, i32) + "### + ); +} + #[test] fn dyn_trait_bare() { assert_snapshot!( -- cgit v1.2.3