From 019ec37db09d9f4bcb4a87fef4dde5b06b424d1e Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Thu, 16 Feb 2023 18:45:37 +0900 Subject: [PATCH 1/3] Fix projection substitution order considering GATs --- chalk-solve/src/clauses.rs | 11 ++++++----- tests/test/projection.rs | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index e3fdd351b7a..a0ede39df7c 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -820,13 +820,14 @@ fn push_alias_alias_eq_clause( // <::A as Z>::B == U :- ::B == U, ::A == T // } builder.push_binders(binders, |builder, bound_var| { + let (_, trait_args, assoc_args) = builder.db.split_projection(&projection_ty); let fresh_self_subst = Substitution::from_iter( interner, - std::iter::once(bound_var.clone().cast(interner)).chain( - projection_ty.substitution.as_slice(interner)[1..] - .iter() - .cloned(), - ), + assoc_args + .iter() + .cloned() + .chain(std::iter::once(bound_var.clone().cast(interner))) + .chain(trait_args[1..].iter().cloned()), ); let fresh_alias = AliasTy::Projection(ProjectionTy { associated_ty_id: projection_ty.associated_ty_id, diff --git a/tests/test/projection.rs b/tests/test/projection.rs index a98a660dfed..021aba29972 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -609,6 +609,30 @@ fn normalize_gat_with_higher_ranked_trait_bound() { } } +#[test] +fn gat_in_alias_in_alias_eq() { + test! { + program { + trait Foo { + type Rebind: Foo; + } + + struct S { } + impl Foo for S { + type Rebind = S; + } + } + + goal { + exists { + < as Foo>::Rebind as Foo>::Rebind: Foo + } + } yields { + expect![[r#"Unique"#]] + } + } +} + #[test] fn forall_projection() { test! { From 6ef68c9f5c8164a09d275a70fb1cc689eb2be0f7 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Thu, 16 Feb 2023 18:46:38 +0900 Subject: [PATCH 2/3] Unignore doctest for GATs --- chalk-solve/src/rust_ir.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index 935a29032da..62861876515 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -214,11 +214,10 @@ pub struct FnDefDatumBound { } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -// FIXME: unignore the doctest below when GATs hit stable. /// A rust intermediate representation (rust_ir) of a Trait Definition. For /// example, given the following rust code: /// -/// ```ignore +/// ``` /// use std::fmt::Debug; /// /// trait Foo From aa036e6c3b654dd7062aa0e4c2893118f4234bf0 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Thu, 16 Feb 2023 19:42:12 +0900 Subject: [PATCH 3/3] Update link to rustc's `TyKind` --- book/src/types/rust_types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/types/rust_types.md b/book/src/types/rust_types.md index d96c234f3b9..45359ff0d07 100644 --- a/book/src/types/rust_types.md +++ b/book/src/types/rust_types.md @@ -168,7 +168,7 @@ types. The intention is that, at least when transitioning, rustc would implement the `Interner` trait and would map from the [`TyKind`][Rustc-TyKind] enum to chalk's [`TyKind`] on the fly, when `data()` is invoked. -[Rustc-TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html +[Rustc-TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/sty/enum.TyKind.html | rustc type | chalk variant (and some notes) | | ------------- | ------------------ |