From 85c89d527eea97aef412a7565fd6903d37693c40 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Mar 2025 22:20:32 +0000 Subject: [PATCH 1/2] Compute associated type in impl from trait id without iterating through all AssociatedTyValues --- chalk-integration/src/db.rs | 13 +++++++++++++ chalk-integration/src/program.rs | 12 ++++++++++++ chalk-solve/src/clauses.rs | 4 +++- chalk-solve/src/display/stub.rs | 8 ++++++++ chalk-solve/src/lib.rs | 6 ++++++ chalk-solve/src/logging_db.rs | 16 ++++++++++++++++ tests/display/unique_names.rs | 7 +++++++ tests/integration/panic.rs | 8 ++++++++ 8 files changed, 73 insertions(+), 1 deletion(-) diff --git a/chalk-integration/src/db.rs b/chalk-integration/src/db.rs index b705343b8d8..22e3362e582 100644 --- a/chalk-integration/src/db.rs +++ b/chalk-integration/src/db.rs @@ -99,6 +99,19 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().impl_datum(id) } + fn associated_ty_from_impl( + &self, + impl_id: ImplId, + assoc_type_id: AssocTypeId, + ) -> Option> { + let ir = self.program_ir().unwrap(); + ir.impl_data[&impl_id] + .associated_ty_value_ids + .iter() + .copied() + .find(|id| ir.associated_ty_values[id].associated_ty_id == assoc_type_id) + } + fn associated_ty_value( &self, id: AssociatedTyValueId, diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 9e55350d6b6..01fd6e74ca7 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -398,6 +398,18 @@ impl RustIrDatabase for Program { self.impl_data[&id].clone() } + fn associated_ty_from_impl( + &self, + impl_id: ImplId, + assoc_type_id: AssocTypeId, + ) -> Option> { + self.impl_data[&impl_id] + .associated_ty_value_ids + .iter() + .copied() + .find(|id| self.associated_ty_values[id].associated_ty_id == assoc_type_id) + } + fn associated_ty_value( &self, id: AssociatedTyValueId, diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index fae04ff55f2..1e6466ffaef 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -639,6 +639,7 @@ pub fn program_clauses_that_could_match( builder, environment, trait_id, + proj.associated_ty_id, trait_parameters, binders, ); @@ -749,6 +750,7 @@ fn push_program_clauses_for_associated_type_values_in_impls_of( builder: &mut ClauseBuilder<'_, I>, environment: &Environment, trait_id: TraitId, + assoc_id: AssocTypeId, trait_parameters: &[GenericArg], binders: &CanonicalVarKinds, ) { @@ -763,7 +765,7 @@ fn push_program_clauses_for_associated_type_values_in_impls_of( debug!(?impl_id); - for &atv_id in &impl_datum.associated_ty_value_ids { + if let Some(atv_id) = builder.db.associated_ty_from_impl(impl_id, assoc_id) { let atv = builder.db.associated_ty_value(atv_id); debug!(?atv_id, ?atv); atv.to_program_clauses(builder, environment); diff --git a/chalk-solve/src/display/stub.rs b/chalk-solve/src/display/stub.rs index 0631e9c291f..2535eee9c5f 100644 --- a/chalk-solve/src/display/stub.rs +++ b/chalk-solve/src/display/stub.rs @@ -116,6 +116,14 @@ impl> RustIrDatabase for StubWrapper<'_, D unreachable!("impl items should never be stubbed") } + fn associated_ty_from_impl( + &self, + _impl_id: chalk_ir::ImplId, + _assoc_type_id: chalk_ir::AssocTypeId, + ) -> Option> { + unreachable!("should never reach projection if impl datum is not stubbed") + } + fn associated_ty_value( &self, _id: crate::rust_ir::AssociatedTyValueId, diff --git a/chalk-solve/src/lib.rs b/chalk-solve/src/lib.rs index e9077d2e605..e2c8f075f96 100644 --- a/chalk-solve/src/lib.rs +++ b/chalk-solve/src/lib.rs @@ -76,6 +76,12 @@ pub trait RustIrDatabase: Debug { /// Returns the datum for the impl with the given id. fn impl_datum(&self, impl_id: ImplId) -> Arc>; + fn associated_ty_from_impl( + &self, + impl_id: ImplId, + assoc_type_id: AssocTypeId, + ) -> Option>; + /// Returns the `AssociatedTyValue` with the given id. fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc>; diff --git a/chalk-solve/src/logging_db.rs b/chalk-solve/src/logging_db.rs index 14d4c21c188..83da075b7fc 100644 --- a/chalk-solve/src/logging_db.rs +++ b/chalk-solve/src/logging_db.rs @@ -171,6 +171,14 @@ where self.ws.db().hidden_opaque_type(id) } + fn associated_ty_from_impl( + &self, + impl_id: ImplId, + assoc_type_id: AssocTypeId, + ) -> Option> { + self.ws.db().associated_ty_from_impl(impl_id, assoc_type_id) + } + fn associated_ty_value( &self, id: crate::rust_ir::AssociatedTyValueId, @@ -434,6 +442,14 @@ where self.db.impl_datum(impl_id) } + fn associated_ty_from_impl( + &self, + impl_id: ImplId, + assoc_type_id: AssocTypeId, + ) -> Option> { + self.db.associated_ty_from_impl(impl_id, assoc_type_id) + } + fn associated_ty_value( &self, id: crate::rust_ir::AssociatedTyValueId, diff --git a/tests/display/unique_names.rs b/tests/display/unique_names.rs index d8545a98d42..f657f3f0455 100644 --- a/tests/display/unique_names.rs +++ b/tests/display/unique_names.rs @@ -94,6 +94,13 @@ where ) -> std::sync::Arc> { self.db.impl_datum(impl_id) } + fn associated_ty_from_impl( + &self, + impl_id: chalk_ir::ImplId, + assoc_type_id: chalk_ir::AssocTypeId, + ) -> Option> { + self.db.associated_ty_from_impl(impl_id, assoc_type_id) + } fn associated_ty_value( &self, id: chalk_solve::rust_ir::AssociatedTyValueId, diff --git a/tests/integration/panic.rs b/tests/integration/panic.rs index af9617a0d0e..2bd86c8dff4 100644 --- a/tests/integration/panic.rs +++ b/tests/integration/panic.rs @@ -118,6 +118,14 @@ impl RustIrDatabase for MockDatabase { }) } + fn associated_ty_from_impl( + &self, + _impl_id: ImplId, + _assoc_type_id: AssocTypeId, + ) -> Option> { + unimplemented!() + } + fn associated_ty_value( &self, id: AssociatedTyValueId, From 0048f3f0585d484b17fdfa3764cf329ef765767a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Mar 2025 22:44:39 +0000 Subject: [PATCH 2/2] Fix broken link in book --- book/src/clauses/coherence.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/clauses/coherence.md b/book/src/clauses/coherence.md index 096569f4cdf..40a368feada 100644 --- a/book/src/clauses/coherence.md +++ b/book/src/clauses/coherence.md @@ -19,7 +19,7 @@ To check for coherence, the Rust compiler completes two separate but related che - [Coherence - talk by withoutboats](https://www.youtube.com/watch?v=AI7SLCubTnk&t=43m19s) - [Little Orphan Impls](https://smallcultfollowing.com/babysteps/blog/2015/01/14/little-orphan-impls/) - [RFC 1023 Rebalancing Coherence](https://rust-lang.github.io/rfcs/1023-rebalancing-coherence.html) -- [Type classes: confluence, coherence and global uniqueness](http://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/) +- [Type classes: confluence, coherence and global uniqueness](https://web.archive.org/web/20250308110404/https://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/) ## Axioms & Properties of Coherence > Historical Note: We used to use the term “external” instead of “upstream”.