From 5c794210bfb67c7aa021b405810342cd50e21262 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Fri, 28 Oct 2022 20:33:19 +0900 Subject: [PATCH 1/2] Replace expect test for GATs with `check_types` --- crates/hir-ty/src/tests/traits.rs | 92 ++++++++++--------------------- 1 file changed, 28 insertions(+), 64 deletions(-) diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index 7995f6446d07b..7d42b8b9bc8d8 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -3966,7 +3966,7 @@ fn g(t: &(dyn T + Send)) { #[test] fn gats_in_path() { - check_infer_with_mismatches( + check_types( r#" //- minicore: deref use core::ops::Deref; @@ -3976,32 +3976,22 @@ trait PointerFamily { fn f(p: P::Pointer) { let a = *p; + //^ i32 } fn g(p:

::Pointer) { let a = *p; + //^ i32 } "#, - expect![[r#" - 110..111 'p': PointerFamily::Pointer - 130..149 '{ ... *p; }': () - 140..141 'a': i32 - 144..146 '*p': i32 - 145..146 'p': PointerFamily::Pointer - 173..174 'p': PointerFamily::Pointer - 212..231 '{ ... *p; }': () - 222..223 'a': i32 - 226..228 '*p': i32 - 227..228 'p': PointerFamily::Pointer - "#]], ); } #[test] fn gats_with_impl_trait() { - // FIXME: the last function (`fn h()`) is not valid Rust as of this writing because you cannot - // specify the same associated type multiple times even if their arguments are different. - // Reconsider how to treat these invalid types. - check_infer_with_mismatches( + // FIXME: the last function (`fn i()`) is not valid Rust as of this writing because you cannot + // specify the same associated type multiple times even if their arguments are different (c.f. + // `fn h()`, which is valid). Reconsider how to treat these invalid types. + check_types( r#" //- minicore: deref use core::ops::Deref; @@ -4012,45 +4002,30 @@ trait Trait { } fn f(v: impl Trait) { - v.get::().deref(); - v.get::().deref(); + let a = v.get::().deref(); + //^ &i32 + let a = v.get::().deref(); + //^ &T } -fn g(v: impl Trait = &'a T>) { +fn g<'a, T: 'a>(v: impl Trait = &'a T>) { let a = v.get::(); + //^ &T let a = v.get::<()>(); + //^ Trait::Assoc<(), impl Trait = &T>> +} +fn h<'a>(v: impl Trait = &'a i32> + Trait = &'a i64>) { + let a = v.get::(); + //^ &i32 + let a = v.get::(); + //^ &i64 } -fn h(v: impl Trait = &'a i32, Assoc = &'a i64> { +fn i<'a>(v: impl Trait = &'a i32, Assoc = &'a i64>) { let a = v.get::(); + //^ &i32 let a = v.get::(); + //^ &i64 } "#, - expect![[r#" - 90..94 'self': &Self - 126..127 'v': impl Trait - 141..198 '{ ...f(); }': () - 147..148 'v': impl Trait - 147..161 'v.get::()': Trait::Assoc - 147..169 'v.get:...eref()': &i32 - 175..176 'v': impl Trait - 175..187 'v.get::()': Trait::Assoc - 175..195 'v.get:...eref()': &T - 207..208 'v': impl Trait = &T> - 240..296 '{ ...>(); }': () - 250..251 'a': &T - 254..255 'v': impl Trait = &T> - 254..266 'v.get::()': &T - 276..277 'a': Trait::Assoc<(), impl Trait = &T>> - 280..281 'v': impl Trait = &T> - 280..293 'v.get::<()>()': Trait::Assoc<(), impl Trait = &T>> - 302..303 'v': impl Trait = &i32, Assoc = &i64> - 360..419 '{ ...>(); }': () - 370..371 'a': &i32 - 374..375 'v': impl Trait = &i32, Assoc = &i64> - 374..388 'v.get::()': &i32 - 398..399 'a': &i64 - 402..403 'v': impl Trait = &i32, Assoc = &i64> - 402..416 'v.get::()': &i64 - "#]], ); } @@ -4086,7 +4061,7 @@ fn f<'a>(v: &dyn Trait = &'a i32>) { #[test] fn gats_in_associated_type_binding() { - check_infer_with_mismatches( + check_types( r#" trait Trait { type Assoc; @@ -4099,24 +4074,13 @@ where T: Trait = usize>, { let a = t.get::(); + //^ u32 let a = t.get::(); + //^ usize let a = t.get::<()>(); + //^ Trait::Assoc<(), T> } "#, - expect![[r#" - 48..52 'self': &Self - 84..85 't': T - 164..252 '{ ...>(); }': () - 174..175 'a': u32 - 178..179 't': T - 178..192 't.get::()': u32 - 202..203 'a': usize - 206..207 't': T - 206..222 't.get:...ize>()': usize - 232..233 'a': Trait::Assoc<(), T> - 236..237 't': T - 236..249 't.get::<()>()': Trait::Assoc<(), T> - "#]], - ) + ); } From e0f09cd00728fb5257d9e6e663de29875c6f0347 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Fri, 28 Oct 2022 21:17:16 +0900 Subject: [PATCH 2/2] Document the ordering constraint on `Binders` and `Substitution` --- crates/hir-ty/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 8458a4fe1cd15..42c3b58d5ada5 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -81,7 +81,20 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; pub type VariableKind = chalk_ir::VariableKind; pub type VariableKinds = chalk_ir::VariableKinds; pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds; +/// Represents generic parameters and an item bound by them. When the item has parent, the binders +/// also contain the generic parameters for its parent. See chalk's documentation for details. +/// +/// One thing to keep in mind when working with `Binders` (and `Substitution`s, which represent +/// generic arguments) in rust-analyzer is that the ordering within *is* significant - the generic +/// parameters/arguments for an item MUST come before those for its parent. This is to facilitate +/// the integration with chalk-solve, which mildly puts constraints as such. See #13335 for its +/// motivation in detail. pub type Binders = chalk_ir::Binders; +/// Interned list of generic arguments for an item. When an item has parent, the `Substitution` for +/// it contains generic arguments for both its parent and itself. See chalk's documentation for +/// details. +/// +/// See `Binders` for the constraint on the ordering. pub type Substitution = chalk_ir::Substitution; pub type GenericArg = chalk_ir::GenericArg; pub type GenericArgData = chalk_ir::GenericArgData;