use std::sync::Arc;
use crate::rust_ir::{CoroutineDatum, CoroutineWitnessDatum};
use crate::{
rust_ir::{
AdtDatumBound, AdtKind, AdtVariantDatum, AssociatedTyDatumBound, FnDefDatumBound,
OpaqueTyDatumBound, TraitDatumBound,
},
RustIrDatabase,
};
use chalk_ir::{
interner::Interner, Binders, CanonicalVarKinds, CoroutineId, Substitution, Ty,
UnificationDatabase, VariableKinds, Variances,
};
#[derive(Debug)]
pub struct StubWrapper<'a, DB> {
db: &'a DB,
}
impl<'a, DB> StubWrapper<'a, DB> {
pub fn new(db: &'a DB) -> Self {
StubWrapper { db }
}
}
impl<I: Interner, DB: RustIrDatabase<I>> UnificationDatabase<I> for StubWrapper<'_, DB> {
fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I> {
self.db.unification_database().fn_def_variance(fn_def_id)
}
fn adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I> {
self.db.unification_database().adt_variance(adt_id)
}
}
impl<I: Interner, DB: RustIrDatabase<I>> RustIrDatabase<I> for StubWrapper<'_, DB> {
fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>> {
self.db.custom_clauses()
}
fn associated_ty_data(
&self,
ty: chalk_ir::AssocTypeId<I>,
) -> std::sync::Arc<crate::rust_ir::AssociatedTyDatum<I>> {
let mut v = (*self.db.associated_ty_data(ty)).clone();
v.binders = Binders::new(
v.binders.binders.clone(),
AssociatedTyDatumBound {
where_clauses: Vec::new(),
bounds: Vec::new(),
},
);
Arc::new(v)
}
fn trait_datum(
&self,
trait_id: chalk_ir::TraitId<I>,
) -> std::sync::Arc<crate::rust_ir::TraitDatum<I>> {
let mut v = (*self.db.trait_datum(trait_id)).clone();
v.binders = Binders::new(
v.binders.binders.clone(),
TraitDatumBound {
where_clauses: Vec::new(),
},
);
Arc::new(v)
}
fn adt_datum(&self, adt_id: chalk_ir::AdtId<I>) -> std::sync::Arc<crate::rust_ir::AdtDatum<I>> {
let mut v = (*self.db.adt_datum(adt_id)).clone();
let variants = match v.kind {
AdtKind::Struct | AdtKind::Union => vec![AdtVariantDatum { fields: vec![] }],
AdtKind::Enum => vec![],
};
v.binders = Binders::new(
v.binders.binders.clone(),
AdtDatumBound {
variants,
where_clauses: Vec::new(),
},
);
Arc::new(v)
}
fn adt_repr(&self, id: chalk_ir::AdtId<I>) -> std::sync::Arc<crate::rust_ir::AdtRepr<I>> {
self.db.adt_repr(id)
}
fn adt_size_align(&self, id: chalk_ir::AdtId<I>) -> Arc<crate::rust_ir::AdtSizeAlign> {
self.db.adt_size_align(id)
}
fn fn_def_datum(
&self,
fn_def_id: chalk_ir::FnDefId<I>,
) -> std::sync::Arc<crate::rust_ir::FnDefDatum<I>> {
let mut v = (*self.db.fn_def_datum(fn_def_id)).clone();
v.binders = Binders::new(
v.binders.binders.clone(),
FnDefDatumBound {
inputs_and_output: v.binders.skip_binders().inputs_and_output.clone(),
where_clauses: Vec::new(),
},
);
Arc::new(v)
}
fn impl_datum(
&self,
_impl_id: chalk_ir::ImplId<I>,
) -> std::sync::Arc<crate::rust_ir::ImplDatum<I>> {
unreachable!("impl items should never be stubbed")
}
fn associated_ty_value(
&self,
_id: crate::rust_ir::AssociatedTyValueId<I>,
) -> std::sync::Arc<crate::rust_ir::AssociatedTyValue<I>> {
unreachable!("associated type values should never be stubbed")
}
fn opaque_ty_data(
&self,
id: chalk_ir::OpaqueTyId<I>,
) -> std::sync::Arc<crate::rust_ir::OpaqueTyDatum<I>> {
let mut v = (*self.db.opaque_ty_data(id)).clone();
v.bound = Binders::new(
v.bound.binders,
OpaqueTyDatumBound {
bounds: Binders::new(VariableKinds::empty(self.db.interner()), Vec::new()),
where_clauses: Binders::new(VariableKinds::empty(self.db.interner()), Vec::new()),
},
);
Arc::new(v)
}
fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<I>) -> chalk_ir::Ty<I> {
chalk_ir::TyKind::Tuple(0, Substitution::empty(self.db.interner()))
.intern(self.db.interner())
}
fn impls_for_trait(
&self,
_trait_id: chalk_ir::TraitId<I>,
_parameters: &[chalk_ir::GenericArg<I>],
_binders: &CanonicalVarKinds<I>,
) -> Vec<chalk_ir::ImplId<I>> {
unimplemented!("stub display code should call this")
}
fn local_impls_to_coherence_check(
&self,
trait_id: chalk_ir::TraitId<I>,
) -> Vec<chalk_ir::ImplId<I>> {
self.db.local_impls_to_coherence_check(trait_id)
}
fn impl_provided_for(
&self,
_auto_trait_id: chalk_ir::TraitId<I>,
_ty: &chalk_ir::TyKind<I>,
) -> bool {
unimplemented!("stub display code should call this")
}
fn well_known_trait_id(
&self,
well_known_trait: crate::rust_ir::WellKnownTrait,
) -> Option<chalk_ir::TraitId<I>> {
self.db.well_known_trait_id(well_known_trait)
}
fn program_clauses_for_env(
&self,
environment: &chalk_ir::Environment<I>,
) -> chalk_ir::ProgramClauses<I> {
self.db.program_clauses_for_env(environment)
}
fn interner(&self) -> I {
self.db.interner()
}
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<I>) -> bool {
self.db.is_object_safe(trait_id)
}
fn closure_kind(
&self,
_closure_id: chalk_ir::ClosureId<I>,
_substs: &chalk_ir::Substitution<I>,
) -> crate::rust_ir::ClosureKind {
unimplemented!("cannot stub closures")
}
fn closure_inputs_and_output(
&self,
_closure_id: chalk_ir::ClosureId<I>,
_substs: &chalk_ir::Substitution<I>,
) -> chalk_ir::Binders<crate::rust_ir::FnDefInputsAndOutputDatum<I>> {
unimplemented!("cannot stub closures")
}
fn closure_upvars(
&self,
_closure_id: chalk_ir::ClosureId<I>,
_substs: &chalk_ir::Substitution<I>,
) -> chalk_ir::Binders<chalk_ir::Ty<I>> {
unimplemented!("cannot stub closures")
}
fn coroutine_datum(&self, _coroutine_id: CoroutineId<I>) -> Arc<CoroutineDatum<I>> {
unimplemented!("cannot stub coroutine")
}
fn coroutine_witness_datum(
&self,
_coroutine_id: CoroutineId<I>,
) -> Arc<CoroutineWitnessDatum<I>> {
unimplemented!("cannot stub coroutine witness")
}
fn closure_fn_substitution(
&self,
_closure_id: chalk_ir::ClosureId<I>,
_substs: &chalk_ir::Substitution<I>,
) -> chalk_ir::Substitution<I> {
unimplemented!("cannot stub closures")
}
fn unification_database(&self) -> &dyn UnificationDatabase<I> {
self
}
fn trait_name(&self, trait_id: chalk_ir::TraitId<I>) -> String {
self.db.trait_name(trait_id)
}
fn adt_name(&self, struct_id: chalk_ir::AdtId<I>) -> String {
self.db.adt_name(struct_id)
}
fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<I>) -> String {
self.db.assoc_type_name(assoc_ty_id)
}
fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<I>) -> String {
self.db.opaque_type_name(opaque_ty_id)
}
fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId<I>) -> String {
self.db.fn_def_name(fn_def_id)
}
fn discriminant_type(&self, ty: Ty<I>) -> Ty<I> {
self.db.discriminant_type(ty)
}
}