diff --git a/chalk-integration/src/db.rs b/chalk-integration/src/db.rs index f865bd96f16..2202da811d8 100644 --- a/chalk-integration/src/db.rs +++ b/chalk-integration/src/db.rs @@ -9,7 +9,7 @@ use crate::{ use chalk_engine::forest::SubstitutionResult; use chalk_ir::{ AdtId, AssocTypeId, Canonical, ConstrainedSubst, Environment, FnDefId, GenericArg, Goal, - ImplId, InEnvironment, OpaqueTyId, ProgramClause, ProgramClauses, TraitId, UCanonical, + ImplId, InEnvironment, OpaqueTyId, ProgramClause, ProgramClauses, TraitId, Ty, UCanonical, }; use chalk_solve::rust_ir::{ AdtDatum, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, FnDefDatum, ImplDatum, @@ -97,6 +97,10 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().opaque_ty_data(id) } + fn hidden_opaque_type(&self, id: OpaqueTyId) -> Ty { + self.program_ir().unwrap().hidden_opaque_type(id) + } + fn adt_datum(&self, id: AdtId) -> Arc> { self.program_ir().unwrap().adt_datum(id) } diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index acface82538..f59d2045e05 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -365,6 +365,7 @@ impl LowerProgram for Program { let mut associated_ty_data = BTreeMap::new(); let mut associated_ty_values = BTreeMap::new(); let mut opaque_ty_data = BTreeMap::new(); + let mut hidden_opaque_types = BTreeMap::new(); let mut custom_clauses = Vec::new(); for (item, &raw_id) in self.items.iter().zip(&raw_ids) { let empty_env = Env { @@ -500,6 +501,7 @@ impl LowerProgram for Program { // So if we have `type Foo = impl Trait`, this would introduce `P1..Pn` let binders = empty_env.in_binders(variable_kinds, |env| { let hidden_ty = opaque_ty.ty.lower(&env)?; + hidden_opaque_types.insert(opaque_ty_id, Arc::new(hidden_ty)); // Introduce a variable to represent the hidden "self type". This will be used in the bounds. // So the `impl Trait` will be lowered to `exists { Self: Trait }`. @@ -530,7 +532,7 @@ impl LowerProgram for Program { }, )?; - Ok(OpaqueTyDatumBound { hidden_ty, bounds }) + Ok(OpaqueTyDatumBound { bounds }) })?; opaque_ty_data.insert( @@ -562,6 +564,7 @@ impl LowerProgram for Program { opaque_ty_ids, opaque_ty_kinds, opaque_ty_data, + hidden_opaque_types, custom_clauses, object_safe_traits, }; diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 2b1a2639e5c..db908dc72d1 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -56,6 +56,9 @@ pub struct Program { /// For each opaque type: pub opaque_ty_data: BTreeMap, Arc>>, + /// Stores the hidden types for opaque types + pub hidden_opaque_types: BTreeMap, Arc>>, + /// For each trait: pub trait_data: BTreeMap, Arc>>, @@ -336,6 +339,10 @@ impl RustIrDatabase for Program { self.opaque_ty_data[&id].clone() } + fn hidden_opaque_type(&self, id: OpaqueTyId) -> Ty { + (*self.hidden_opaque_types[&id]).clone() + } + fn adt_datum(&self, id: AdtId) -> Arc> { self.adt_data[&id].clone() } diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index fc0c55056b6..071eee82319 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -142,8 +142,9 @@ pub fn push_auto_trait_impls_opaque( 1 ); - let binders = opaque_ty_datum.bound.map_ref(|b| &b.hidden_ty); - builder.push_binders(&binders, |builder, hidden_ty| { + let hidden_ty = builder.db.hidden_opaque_type(opaque_id); + let binders = opaque_ty_datum.bound.clone(); + builder.push_binders(&binders, |builder, _| { let self_ty: Ty<_> = ApplicationTy { name: opaque_id.cast(interner), substitution: builder.substitution_in_scope(), diff --git a/chalk-solve/src/clauses/program_clauses.rs b/chalk-solve/src/clauses/program_clauses.rs index bf630a431a3..800f3a8fc94 100644 --- a/chalk-solve/src/clauses/program_clauses.rs +++ b/chalk-solve/src/clauses/program_clauses.rs @@ -151,7 +151,7 @@ impl ToProgramClauses for OpaqueTyDatum { DomainGoal::Holds( AliasEq { alias: alias.clone(), - ty: opaque_ty_bound.hidden_ty.clone(), + ty: builder.db.hidden_opaque_type(self.opaque_ty_id), } .cast(interner), ), diff --git a/chalk-solve/src/lib.rs b/chalk-solve/src/lib.rs index 62a9681993e..52994279068 100644 --- a/chalk-solve/src/lib.rs +++ b/chalk-solve/src/lib.rs @@ -51,6 +51,9 @@ pub trait RustIrDatabase: Debug { /// Returns the `OpaqueTyDatum` with the given id. fn opaque_ty_data(&self, id: OpaqueTyId) -> Arc>; + /// Returns the "hidden type" corresponding with the opaque type. + fn hidden_opaque_type(&self, id: OpaqueTyId) -> Ty; + /// Returns a list of potentially relevant impls for a given /// trait-id; we also supply the type parameters that we are /// trying to match (if known: these parameters may contain diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index 019911feb10..0388cd58077 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -544,9 +544,6 @@ pub struct OpaqueTyDatum { #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner)] pub struct OpaqueTyDatumBound { - /// The value for the "hidden type" for `opaque type Foo = ...` - pub hidden_ty: Ty, - /// Trait bounds for the opaque type. pub bounds: Binders>>, } diff --git a/tests/integration/panic.rs b/tests/integration/panic.rs index 045f0f74cdf..d6a3cc2ef23 100644 --- a/tests/integration/panic.rs +++ b/tests/integration/panic.rs @@ -121,6 +121,10 @@ impl RustIrDatabase for MockDatabase { unimplemented!() } + fn hidden_opaque_type(&self, id: OpaqueTyId) -> Ty { + unimplemented!() + } + fn adt_datum(&self, id: AdtId) -> Arc> { unimplemented!() }