diff options
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 8 |
3 files changed, 40 insertions, 27 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c04f2a0c4..4784fad85 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -909,6 +909,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
909 | sig_ty, | 909 | sig_ty, |
910 | ); | 910 | ); |
911 | 911 | ||
912 | // Eagerly try to relate the closure type with the expected | ||
913 | // type, otherwise we often won't have enough information to | ||
914 | // infer the body. | ||
915 | self.coerce(&closure_ty, &expected.ty); | ||
916 | |||
912 | self.infer_expr(*body, &Expectation::has_type(ret_ty)); | 917 | self.infer_expr(*body, &Expectation::has_type(ret_ty)); |
913 | closure_ty | 918 | closure_ty |
914 | } | 919 | } |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 13090f89d..112b3d73f 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3800,13 +3800,13 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { | |||
3800 | [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type | 3800 | [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type |
3801 | [296; 302) 'get(x)': {unknown} | 3801 | [296; 302) 'get(x)': {unknown} |
3802 | [300; 301) 'x': T | 3802 | [300; 301) 'x': T |
3803 | [308; 312) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U | 3803 | [308; 312) 'get2': fn get2<{unknown}, T>(T) -> U |
3804 | [308; 315) 'get2(x)': {unknown} | 3804 | [308; 315) 'get2(x)': {unknown} |
3805 | [313; 314) 'x': T | 3805 | [313; 314) 'x': T |
3806 | [321; 324) 'get': fn get<impl Trait<Type = i64>>(T) -> <T as Trait>::Type | 3806 | [321; 324) 'get': fn get<impl Trait<Type = i64>>(T) -> <T as Trait>::Type |
3807 | [321; 327) 'get(y)': {unknown} | 3807 | [321; 327) 'get(y)': {unknown} |
3808 | [325; 326) 'y': impl Trait<Type = i64> | 3808 | [325; 326) 'y': impl Trait<Type = i64> |
3809 | [333; 337) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U | 3809 | [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(T) -> U |
3810 | [333; 340) 'get2(y)': {unknown} | 3810 | [333; 340) 'get2(y)': {unknown} |
3811 | [338; 339) 'y': impl Trait<Type = i64> | 3811 | [338; 339) 'y': impl Trait<Type = i64> |
3812 | [346; 349) 'get': fn get<S<u64>>(T) -> <T as Trait>::Type | 3812 | [346; 349) 'get': fn get<S<u64>>(T) -> <T as Trait>::Type |
@@ -3997,7 +3997,7 @@ trait FnOnce<Args> { | |||
3997 | 3997 | ||
3998 | enum Option<T> { Some(T), None } | 3998 | enum Option<T> { Some(T), None } |
3999 | impl<T> Option<T> { | 3999 | impl<T> Option<T> { |
4000 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> U {} | 4000 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} |
4001 | } | 4001 | } |
4002 | 4002 | ||
4003 | fn test() { | 4003 | fn test() { |
@@ -4010,30 +4010,30 @@ fn test() { | |||
4010 | @r###" | 4010 | @r###" |
4011 | [148; 152) 'self': Option<T> | 4011 | [148; 152) 'self': Option<T> |
4012 | [154; 155) 'f': F | 4012 | [154; 155) 'f': F |
4013 | [165; 167) '{}': () | 4013 | [173; 175) '{}': () |
4014 | [181; 300) '{ ... 1); }': () | 4014 | [189; 308) '{ ... 1); }': () |
4015 | [191; 192) 'x': Option<u32> | 4015 | [199; 200) 'x': Option<u32> |
4016 | [195; 207) 'Option::Some': Some<u32>(T) -> Option<T> | 4016 | [203; 215) 'Option::Some': Some<u32>(T) -> Option<T> |
4017 | [195; 213) 'Option...(1u32)': Option<u32> | 4017 | [203; 221) 'Option...(1u32)': Option<u32> |
4018 | [208; 212) '1u32': u32 | 4018 | [216; 220) '1u32': u32 |
4019 | [219; 220) 'x': Option<u32> | 4019 | [227; 228) 'x': Option<u32> |
4020 | [219; 235) 'x.map(...v + 1)': {unknown} | 4020 | [227; 243) 'x.map(...v + 1)': Option<u32> |
4021 | [225; 234) '|v| v + 1': |u32| -> i32 | 4021 | [233; 242) '|v| v + 1': |u32| -> u32 |
4022 | [226; 227) 'v': u32 | 4022 | [234; 235) 'v': u32 |
4023 | [229; 230) 'v': u32 | 4023 | [237; 238) 'v': u32 |
4024 | [229; 234) 'v + 1': i32 | 4024 | [237; 242) 'v + 1': u32 |
4025 | [233; 234) '1': i32 | 4025 | [241; 242) '1': u32 |
4026 | [241; 242) 'x': Option<u32> | 4026 | [249; 250) 'x': Option<u32> |
4027 | [241; 257) 'x.map(... 1u64)': {unknown} | 4027 | [249; 265) 'x.map(... 1u64)': Option<u64> |
4028 | [247; 256) '|_v| 1u64': |u32| -> u64 | 4028 | [255; 264) '|_v| 1u64': |u32| -> u64 |
4029 | [248; 250) '_v': u32 | 4029 | [256; 258) '_v': u32 |
4030 | [252; 256) '1u64': u64 | 4030 | [260; 264) '1u64': u64 |
4031 | [267; 268) 'y': Option<i64> | 4031 | [275; 276) 'y': Option<i64> |
4032 | [284; 285) 'x': Option<u32> | 4032 | [292; 293) 'x': Option<u32> |
4033 | [284; 297) 'x.map(|_v| 1)': Option<i64> | 4033 | [292; 305) 'x.map(|_v| 1)': Option<i64> |
4034 | [290; 296) '|_v| 1': |u32| -> i32 | 4034 | [298; 304) '|_v| 1': |u32| -> i64 |
4035 | [291; 293) '_v': u32 | 4035 | [299; 301) '_v': u32 |
4036 | [295; 296) '1': i32 | 4036 | [303; 304) '1': i64 |
4037 | "### | 4037 | "### |
4038 | ); | 4038 | ); |
4039 | } | 4039 | } |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 8e256341d..d11dab294 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -173,6 +173,14 @@ pub(crate) fn trait_solve_query( | |||
173 | ) -> Option<Solution> { | 173 | ) -> Option<Solution> { |
174 | let _p = profile("trait_solve_query"); | 174 | let _p = profile("trait_solve_query"); |
175 | debug!("trait_solve_query({})", goal.value.value.display(db)); | 175 | debug!("trait_solve_query({})", goal.value.value.display(db)); |
176 | |||
177 | if let Obligation::Projection(pred) = &goal.value.value { | ||
178 | if let Ty::Bound(_) = &pred.projection_ty.parameters[0] { | ||
179 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible | ||
180 | return Some(Solution::Ambig(Guidance::Unknown)); | ||
181 | } | ||
182 | } | ||
183 | |||
176 | let canonical = goal.to_chalk(db).cast(); | 184 | let canonical = goal.to_chalk(db).cast(); |
177 | // We currently don't deal with universes (I think / hope they're not yet | 185 | // We currently don't deal with universes (I think / hope they're not yet |
178 | // relevant for our use cases?) | 186 | // relevant for our use cases?) |