//! Contains a `LoggingIrDatabase` which returns stub versions of everything //! queried. use std::sync::Arc; use crate::rust_ir::{GeneratorDatum, GeneratorWitnessDatum}; use crate::{ rust_ir::{ AdtDatumBound, AdtKind, AdtVariantDatum, AssociatedTyDatumBound, FnDefDatumBound, OpaqueTyDatumBound, TraitDatumBound, }, RustIrDatabase, }; use chalk_ir::{ interner::Interner, Binders, CanonicalVarKinds, GeneratorId, 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> UnificationDatabase for StubWrapper<'_, DB> { fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId) -> Variances { self.db.unification_database().fn_def_variance(fn_def_id) } fn adt_variance(&self, adt_id: chalk_ir::AdtId) -> Variances { self.db.unification_database().adt_variance(adt_id) } } impl> RustIrDatabase for StubWrapper<'_, DB> { fn custom_clauses(&self) -> Vec> { self.db.custom_clauses() } fn associated_ty_data( &self, ty: chalk_ir::AssocTypeId, ) -> std::sync::Arc> { 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, ) -> std::sync::Arc> { 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) -> std::sync::Arc> { 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) -> std::sync::Arc> { self.db.adt_repr(id) } fn adt_size_align(&self, id: chalk_ir::AdtId) -> Arc { self.db.adt_size_align(id) } fn fn_def_datum( &self, fn_def_id: chalk_ir::FnDefId, ) -> std::sync::Arc> { 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, ) -> std::sync::Arc> { unreachable!("impl items should never be stubbed") } fn associated_ty_value( &self, _id: crate::rust_ir::AssociatedTyValueId, ) -> std::sync::Arc> { unreachable!("associated type values should never be stubbed") } fn opaque_ty_data( &self, id: chalk_ir::OpaqueTyId, ) -> std::sync::Arc> { 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) -> chalk_ir::Ty { // Return a unit since the particular hidden type doesn't matter (If it // did matter, it would have been recorded) chalk_ir::TyKind::Tuple(0, Substitution::empty(self.db.interner())) .intern(self.db.interner()) } fn impls_for_trait( &self, _trait_id: chalk_ir::TraitId, _parameters: &[chalk_ir::GenericArg], _binders: &CanonicalVarKinds, ) -> Vec> { // We panic here because the returned ids may not be collected, // resulting in unresolvable names. unimplemented!("stub display code should call this") } fn local_impls_to_coherence_check( &self, trait_id: chalk_ir::TraitId, ) -> Vec> { self.db.local_impls_to_coherence_check(trait_id) } fn impl_provided_for( &self, _auto_trait_id: chalk_ir::TraitId, _ty: &chalk_ir::TyKind, ) -> bool { // We panic here because the returned ids may not be collected, // resulting in unresolvable names. unimplemented!("stub display code should call this") } fn well_known_trait_id( &self, well_known_trait: crate::rust_ir::WellKnownTrait, ) -> Option> { self.db.well_known_trait_id(well_known_trait) } fn program_clauses_for_env( &self, environment: &chalk_ir::Environment, ) -> chalk_ir::ProgramClauses { self.db.program_clauses_for_env(environment) } fn interner(&self) -> I { self.db.interner() } fn is_object_safe(&self, trait_id: chalk_ir::TraitId) -> bool { self.db.is_object_safe(trait_id) } fn closure_kind( &self, _closure_id: chalk_ir::ClosureId, _substs: &chalk_ir::Substitution, ) -> crate::rust_ir::ClosureKind { unimplemented!("cannot stub closures") } fn closure_inputs_and_output( &self, _closure_id: chalk_ir::ClosureId, _substs: &chalk_ir::Substitution, ) -> chalk_ir::Binders> { unimplemented!("cannot stub closures") } fn closure_upvars( &self, _closure_id: chalk_ir::ClosureId, _substs: &chalk_ir::Substitution, ) -> chalk_ir::Binders> { unimplemented!("cannot stub closures") } fn generator_datum(&self, _generator_id: GeneratorId) -> Arc> { unimplemented!("cannot stub generator") } fn generator_witness_datum( &self, _generator_id: GeneratorId, ) -> Arc> { unimplemented!("cannot stub generator witness") } fn closure_fn_substitution( &self, _closure_id: chalk_ir::ClosureId, _substs: &chalk_ir::Substitution, ) -> chalk_ir::Substitution { unimplemented!("cannot stub closures") } fn unification_database(&self) -> &dyn UnificationDatabase { self } fn trait_name(&self, trait_id: chalk_ir::TraitId) -> String { self.db.trait_name(trait_id) } fn adt_name(&self, struct_id: chalk_ir::AdtId) -> String { self.db.adt_name(struct_id) } fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId) -> String { self.db.assoc_type_name(assoc_ty_id) } fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId) -> String { self.db.opaque_type_name(opaque_ty_id) } fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId) -> String { self.db.fn_def_name(fn_def_id) } fn discriminant_type(&self, ty: Ty) -> Ty { self.db.discriminant_type(ty) } }