From a0aeb6e7ad7385811a4bb75577513339c9a9ed91 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 24 Sep 2019 19:04:53 +0200 Subject: Make the closure_1 test work --- crates/ra_hir/src/ty/infer.rs | 5 ++++ crates/ra_hir/src/ty/tests.rs | 54 +++++++++++++++++++++--------------------- crates/ra_hir/src/ty/traits.rs | 8 +++++++ 3 files changed, 40 insertions(+), 27 deletions(-) (limited to 'crates/ra_hir') 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> { sig_ty, ); + // Eagerly try to relate the closure type with the expected + // type, otherwise we often won't have enough information to + // infer the body. + self.coerce(&closure_ty, &expected.ty); + self.infer_expr(*body, &Expectation::has_type(ret_ty)); closure_ty } 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>(x: T, y: impl Trait) { [296; 299) 'get': fn get(T) -> ::Type [296; 302) 'get(x)': {unknown} [300; 301) 'x': T - [308; 312) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U + [308; 312) 'get2': fn get2<{unknown}, T>(T) -> U [308; 315) 'get2(x)': {unknown} [313; 314) 'x': T [321; 324) 'get': fn get>(T) -> ::Type [321; 327) 'get(y)': {unknown} [325; 326) 'y': impl Trait - [333; 337) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U + [333; 337) 'get2': fn get2<{unknown}, impl Trait>(T) -> U [333; 340) 'get2(y)': {unknown} [338; 339) 'y': impl Trait [346; 349) 'get': fn get>(T) -> ::Type @@ -3997,7 +3997,7 @@ trait FnOnce { enum Option { Some(T), None } impl Option { - fn map U>(self, f: F) -> U {} + fn map U>(self, f: F) -> Option {} } fn test() { @@ -4010,30 +4010,30 @@ fn test() { @r###" [148; 152) 'self': Option [154; 155) 'f': F - [165; 167) '{}': () - [181; 300) '{ ... 1); }': () - [191; 192) 'x': Option - [195; 207) 'Option::Some': Some(T) -> Option - [195; 213) 'Option...(1u32)': Option - [208; 212) '1u32': u32 - [219; 220) 'x': Option - [219; 235) 'x.map(...v + 1)': {unknown} - [225; 234) '|v| v + 1': |u32| -> i32 - [226; 227) 'v': u32 - [229; 230) 'v': u32 - [229; 234) 'v + 1': i32 - [233; 234) '1': i32 - [241; 242) 'x': Option - [241; 257) 'x.map(... 1u64)': {unknown} - [247; 256) '|_v| 1u64': |u32| -> u64 - [248; 250) '_v': u32 - [252; 256) '1u64': u64 - [267; 268) 'y': Option - [284; 285) 'x': Option - [284; 297) 'x.map(|_v| 1)': Option - [290; 296) '|_v| 1': |u32| -> i32 - [291; 293) '_v': u32 - [295; 296) '1': i32 + [173; 175) '{}': () + [189; 308) '{ ... 1); }': () + [199; 200) 'x': Option + [203; 215) 'Option::Some': Some(T) -> Option + [203; 221) 'Option...(1u32)': Option + [216; 220) '1u32': u32 + [227; 228) 'x': Option + [227; 243) 'x.map(...v + 1)': Option + [233; 242) '|v| v + 1': |u32| -> u32 + [234; 235) 'v': u32 + [237; 238) 'v': u32 + [237; 242) 'v + 1': u32 + [241; 242) '1': u32 + [249; 250) 'x': Option + [249; 265) 'x.map(... 1u64)': Option + [255; 264) '|_v| 1u64': |u32| -> u64 + [256; 258) '_v': u32 + [260; 264) '1u64': u64 + [275; 276) 'y': Option + [292; 293) 'x': Option + [292; 305) 'x.map(|_v| 1)': Option + [298; 304) '|_v| 1': |u32| -> i64 + [299; 301) '_v': u32 + [303; 304) '1': i64 "### ); } 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( ) -> Option { let _p = profile("trait_solve_query"); debug!("trait_solve_query({})", goal.value.value.display(db)); + + if let Obligation::Projection(pred) = &goal.value.value { + if let Ty::Bound(_) = &pred.projection_ty.parameters[0] { + // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible + return Some(Solution::Ambig(Guidance::Unknown)); + } + } + let canonical = goal.to_chalk(db).cast(); // We currently don't deal with universes (I think / hope they're not yet // relevant for our use cases?) -- cgit v1.2.3