diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index 46c04b36837..4d2f0d8cefc 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -633,7 +633,10 @@ impl LowerWithEnv for ProjectionTy { substitution: trait_substitution, } = trait_ref.lower(env)?; let lookup = env.lookup_associated_ty(trait_id, name)?; - let mut args: Vec<_> = args + + let mut all_args: Vec<_> = trait_substitution.iter(interner).cloned().collect(); + + let args: Vec<_> = args .iter() .map(|a| a.lower(env)) .collect::>()?; @@ -656,11 +659,11 @@ impl LowerWithEnv for ProjectionTy { } } - args.extend(trait_substitution.iter(interner).cloned()); + all_args.extend(args.into_iter()); Ok(chalk_ir::ProjectionTy { associated_ty_id: lookup.id, - substitution: chalk_ir::Substitution::from_iter(interner, args), + substitution: chalk_ir::Substitution::from_iter(interner, all_args), }) } } @@ -1024,9 +1027,8 @@ pub fn lower_goal(goal: &Goal, program: &LoweredProgram) -> LowerResult; // } // ``` - let mut variable_kinds = assoc_ty_defn.all_parameters(); - variable_kinds.extend(trait_defn.all_parameters()); + let mut variable_kinds = trait_defn.all_parameters(); + variable_kinds.extend(assoc_ty_defn.all_parameters()); let binders = empty_env.in_binders(variable_kinds, |env| { Ok(rust_ir::AssociatedTyDatumBound { @@ -330,8 +330,8 @@ impl ProgramLowerer { // impl *and* those from the associated type // itself. As in the "trait" case above, we begin // with the parameters from the impl. - let mut variable_kinds = atv.all_parameters(); - variable_kinds.extend(impl_defn.all_parameters()); + let mut variable_kinds = impl_defn.all_parameters(); + variable_kinds.extend(atv.all_parameters()); let value = empty_env.in_binders(variable_kinds, |env| { Ok(rust_ir::AssociatedTyValueBound { diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index 1e6466ffaef..329c6b984d2 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -866,11 +866,9 @@ fn push_alias_alias_eq_clause( let (_, trait_args, assoc_args) = builder.db.split_projection(&projection_ty); let fresh_self_subst = Substitution::from_iter( interner, - assoc_args - .iter() - .cloned() - .chain(std::iter::once(intermediate_eq_ty.clone().cast(interner))) - .chain(trait_args[1..].iter().cloned()), + std::iter::once(intermediate_eq_ty.clone().cast(interner)) + .chain(trait_args[1..].iter().cloned()) + .chain(assoc_args.iter().cloned()), ); let fresh_alias = AliasTy::Projection(ProjectionTy { associated_ty_id: projection_ty.associated_ty_id, diff --git a/chalk-solve/src/split.rs b/chalk-solve/src/split.rs index bea24044db8..5a45a833d99 100644 --- a/chalk-solve/src/split.rs +++ b/chalk-solve/src/split.rs @@ -93,9 +93,8 @@ pub trait Split: RustIrDatabase { // the impl parameters are a suffix // // [ P0..Pn, Pn...Pm ] - // ^^^^^^^ impl parameters - let split_point = parameters.len() - impl_params_len; - let (other_params, impl_params) = parameters.split_at(split_point); + // ^^^^^^ impl parameters + let (impl_params, other_params) = parameters.split_at(impl_params_len); (impl_params, other_params) } @@ -144,9 +143,10 @@ pub trait Split: RustIrDatabase { // ` as Foo>::Item<'!a>` let projection_substitution = Substitution::from_iter( interner, - atv_parameters - .iter() - .chain(trait_ref.substitution.iter(interner)) + trait_ref + .substitution + .iter(interner) + .chain(atv_parameters.iter()) .cloned(), ); @@ -190,8 +190,8 @@ pub trait Split: RustIrDatabase { ) -> (&'p [P], &'p [P]) { let trait_datum = &self.trait_datum(associated_ty_datum.trait_id); let trait_num_params = trait_datum.binders.len(self.interner()); - let split_point = parameters.len() - trait_num_params; - let (other_params, trait_params) = parameters.split_at(split_point); + let split_point = trait_num_params; + let (trait_params, other_params) = parameters.split_at(split_point); (trait_params, other_params) } } diff --git a/tests/lowering/mod.rs b/tests/lowering/mod.rs index 628f7b2104e..7ddcba1fcc3 100644 --- a/tests/lowering/mod.rs +++ b/tests/lowering/mod.rs @@ -192,8 +192,8 @@ fn atc_accounting() { &r#"AssociatedTyValue { impl_id: ImplId(#2), associated_ty_id: (Iterable::Iter), - value: for AssociatedTyValueBound { - ty: Iter<'^0.0, ^0.1> + value: for AssociatedTyValueBound { + ty: Iter<'^0.1, ^0.0> }, }"# .replace(",\n", "\n"), diff --git a/tests/test/impls.rs b/tests/test/impls.rs index 5576c1d5900..aa15879dd9e 100644 --- a/tests/test/impls.rs +++ b/tests/test/impls.rs @@ -240,8 +240,7 @@ fn normalize_rev_infer_gat() { T: Combine = Either> } } yields { - // T is ?1 and U is ?0, so this is surprising, but correct! (See #126.) - expect![["Unique; substitution [?0 := B, ?1 := A]"]] + expect![["Unique; substitution [?0 := A, ?1 := B]"]] } } } diff --git a/tests/test/unify.rs b/tests/test/unify.rs index a4bfabdbb7d..6de70054910 100644 --- a/tests/test/unify.rs +++ b/tests/test/unify.rs @@ -367,9 +367,7 @@ fn mixed_indices_normalize_gat_application() { Normalize( as Foo>::T -> Either) } } yields { - // Our GAT parameter is mapped to ?0; all others appear left to right - // in our Normalize(...) goal. - expect![["Unique; for { substitution [?0 := ^0.0, ?1 := '^0.1, ?2 := ^0.2, ?3 := ^0.0, ?4 := ^0.2] }"]] + expect![["Unique; for { substitution [?0 := '^0.0, ?1 := ^0.1, ?2 := ^0.2, ?3 := ^0.2, ?4 := ^0.1] }"]] } } }