diff options
| author | Josh Mcguigan <[email protected]> | 2021-03-16 15:45:46 +0000 |
|---|---|---|
| committer | Josh Mcguigan <[email protected]> | 2021-03-26 16:11:50 +0000 |
| commit | 957939292ec9038f139bd10e093e9673609eea04 (patch) | |
| tree | 5babed3a488b43ea561874be3bda36198ccb421b /crates/ide_completion/src | |
| parent | 20e32fc946010f8c46728d6cb8bab1b96b3f48b9 (diff) | |
completion relevance consider if types can be unified
Diffstat (limited to 'crates/ide_completion/src')
| -rw-r--r-- | crates/ide_completion/src/render.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index 9ce49074f..12453f889 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs | |||
| @@ -314,7 +314,8 @@ fn compute_exact_type_match(ctx: &CompletionContext, completion_ty: &hir::Type) | |||
| 314 | Some(expected_type) => { | 314 | Some(expected_type) => { |
| 315 | // We don't ever consider unit type to be an exact type match, since | 315 | // We don't ever consider unit type to be an exact type match, since |
| 316 | // nearly always this is not meaningful to the user. | 316 | // nearly always this is not meaningful to the user. |
| 317 | completion_ty == expected_type && !expected_type.is_unit() | 317 | (completion_ty == expected_type || expected_type.could_unify_with(completion_ty)) |
| 318 | && !expected_type.is_unit() | ||
| 318 | } | 319 | } |
| 319 | None => false, | 320 | None => false, |
| 320 | } | 321 | } |
| @@ -1353,4 +1354,34 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } | |||
| 1353 | "#]], | 1354 | "#]], |
| 1354 | ); | 1355 | ); |
| 1355 | } | 1356 | } |
| 1357 | |||
| 1358 | #[test] | ||
| 1359 | fn generic_enum() { | ||
| 1360 | check_relevance( | ||
| 1361 | r#" | ||
| 1362 | enum Foo<T> { A(T), B } | ||
| 1363 | // bar() should not be an exact type match | ||
| 1364 | // because the generic parameters are different | ||
| 1365 | fn bar() -> Foo<u8> { Foo::B } | ||
| 1366 | // FIXME baz() should be an exact type match | ||
| 1367 | // because the types could unify, but it currently | ||
| 1368 | // is not. This is due to the T here being | ||
| 1369 | // TyKind::Placeholder rather than TyKind::Missing. | ||
| 1370 | fn baz<T>() -> Foo<T> { Foo::B } | ||
| 1371 | fn foo() { | ||
| 1372 | let foo: Foo<u32> = Foo::B; | ||
| 1373 | let _: Foo<u32> = f$0; | ||
| 1374 | } | ||
| 1375 | "#, | ||
| 1376 | expect![[r#" | ||
| 1377 | ev Foo::A(…) [type] | ||
| 1378 | ev Foo::B [type] | ||
| 1379 | lc foo [type+local] | ||
| 1380 | en Foo [] | ||
| 1381 | fn baz() [] | ||
| 1382 | fn bar() [] | ||
| 1383 | fn foo() [] | ||
| 1384 | "#]], | ||
| 1385 | ); | ||
| 1386 | } | ||
| 1356 | } | 1387 | } |
