From de39d221a15c0a146ed8adbdb1616692180948bb Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 21 Feb 2020 18:24:18 +0100 Subject: Implement unsize coercion using proper trait solving --- crates/ra_hir_ty/src/tests/coercion.rs | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 42330b269..aa2dfb5f0 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -548,3 +548,85 @@ impl S { "### ); } + +#[test] +fn coerce_unsize_array() { + assert_snapshot!( + infer_with_mismatches(r#" +#[lang = "unsize"] +pub trait Unsize {} +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +impl, U> CoerceUnsized<&U> for &T {} + +fn test() { + let f: &[usize] = &[1, 2, 3]; +} +"#, true), + @r###" + [162; 199) '{ ... 3]; }': () + [172; 173) 'f': &[usize] + [186; 196) '&[1, 2, 3]': &[usize; _] + [187; 196) '[1, 2, 3]': [usize; _] + [188; 189) '1': usize + [191; 192) '2': usize + [194; 195) '3': usize + "### + ); +} + +#[ignore] +#[test] +fn coerce_unsize_trait_object() { + assert_snapshot!( + infer_with_mismatches(r#" +#[lang = "unsize"] +pub trait Unsize {} +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +impl, U> CoerceUnsized<&U> for &T {} + +trait Foo {} +trait Bar: Foo {} +struct S; +impl Foo for S {} +impl Bar for S {} + +fn test() { + let obj: &dyn Bar = &S; + let obj: &dyn Foo = obj; +} +"#, true), + @r###" + "### + ); +} + +#[ignore] +#[test] +fn coerce_unsize_generic() { + // FIXME: Implement this + // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions + assert_snapshot!( + infer_with_mismatches(r#" +#[lang = "unsize"] +pub trait Unsize {} +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +impl, U> CoerceUnsized<&U> for &T {} + +struct Foo { t: T }; +struct Bar(Foo); + +fn test() { + let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; + let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); +} +"#, true), + @r###" + "### + ); +} -- cgit v1.2.3 From 0dfbbaf03b03618dcb7ba203ddc453533bb8d1b4 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 21 Feb 2020 19:05:27 +0100 Subject: Implement dyn Trait unsizing as well --- crates/ra_hir_ty/src/tests/coercion.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index aa2dfb5f0..b6fce9377 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -576,7 +576,6 @@ fn test() { ); } -#[ignore] #[test] fn coerce_unsize_trait_object() { assert_snapshot!( @@ -600,6 +599,13 @@ fn test() { } "#, true), @r###" + [240; 300) '{ ...obj; }': () + [250; 253) 'obj': &dyn Bar + [266; 268) '&S': &S + [267; 268) 'S': S + [278; 281) 'obj': &dyn Foo + [294; 297) 'obj': &dyn Bar + [294; 297): expected &dyn Foo, got &dyn Bar "### ); } -- cgit v1.2.3 From 2d5ab6324795e5fc36e4b61cb66737958dc67e7a Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 21 Feb 2020 21:49:02 +0100 Subject: Add &dyn Trait -> &dyn SuperTrait coercion, and fix &T -> &dyn Trait --- crates/ra_hir_ty/src/tests/coercion.rs | 40 ++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index b6fce9377..5594ed394 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -587,25 +587,37 @@ pub trait CoerceUnsized {} impl, U> CoerceUnsized<&U> for &T {} -trait Foo {} -trait Bar: Foo {} -struct S; -impl Foo for S {} -impl Bar for S {} +trait Foo {} +trait Bar: Foo {} +trait Baz: Bar {} + +struct S; +impl Foo for S {} +impl Bar for S {} +impl Baz for S {} fn test() { - let obj: &dyn Bar = &S; - let obj: &dyn Foo = obj; + let obj: &dyn Baz = &S; + let obj: &dyn Bar<_, _, _> = obj; + let obj: &dyn Foo<_, _> = obj; + let obj2: &dyn Baz = &S; + let _: &dyn Foo<_, _> = obj2; } "#, true), @r###" - [240; 300) '{ ...obj; }': () - [250; 253) 'obj': &dyn Bar - [266; 268) '&S': &S - [267; 268) 'S': S - [278; 281) 'obj': &dyn Foo - [294; 297) 'obj': &dyn Bar - [294; 297): expected &dyn Foo, got &dyn Bar + [388; 573) '{ ...bj2; }': () + [398; 401) 'obj': &dyn Baz + [423; 425) '&S': &S + [424; 425) 'S': S + [435; 438) 'obj': &dyn Bar + [460; 463) 'obj': &dyn Baz + [473; 476) 'obj': &dyn Foo + [495; 498) 'obj': &dyn Bar + [508; 512) 'obj2': &dyn Baz + [534; 536) '&S': &S + [535; 536) 'S': S + [546; 547) '_': &dyn Foo + [566; 570) 'obj2': &dyn Baz "### ); } -- cgit v1.2.3 From 3e106c77ff76c39be49444165eac805d32666e41 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 22 Feb 2020 13:14:39 +0100 Subject: Rework find_super_trait_path to protect against cycles --- crates/ra_hir_ty/src/tests/coercion.rs | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 5594ed394..60ad6e9be 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -622,6 +622,44 @@ fn test() { ); } +#[test] +fn coerce_unsize_super_trait_cycle() { + assert_snapshot!( + infer_with_mismatches(r#" +#[lang = "unsize"] +pub trait Unsize {} +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +impl, U> CoerceUnsized<&U> for &T {} + +trait A {} +trait B: C + A {} +trait C: B {} +trait D: C + +struct S; +impl A for S {} +impl B for S {} +impl C for S {} +impl D for S {} + +fn test() { + let obj: &dyn D = &S; + let obj: &dyn A = obj; +} +"#, true), + @r###" + [292; 348) '{ ...obj; }': () + [302; 305) 'obj': &dyn D + [316; 318) '&S': &S + [317; 318) 'S': S + [328; 331) 'obj': &dyn A + [342; 345) 'obj': &dyn D + "### + ); +} + #[ignore] #[test] fn coerce_unsize_generic() { -- cgit v1.2.3