From 6a77ec7bbe6ddbf663dce9529d11d1bb56c5489a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:35:29 +0200 Subject: Rename ra_hir_ty -> hir_ty --- crates/ra_hir_ty/src/traits/chalk.rs | 586 ------------------- crates/ra_hir_ty/src/traits/chalk/interner.rs | 383 ------------- crates/ra_hir_ty/src/traits/chalk/mapping.rs | 787 -------------------------- crates/ra_hir_ty/src/traits/chalk/tls.rs | 358 ------------ 4 files changed, 2114 deletions(-) delete mode 100644 crates/ra_hir_ty/src/traits/chalk.rs delete mode 100644 crates/ra_hir_ty/src/traits/chalk/interner.rs delete mode 100644 crates/ra_hir_ty/src/traits/chalk/mapping.rs delete mode 100644 crates/ra_hir_ty/src/traits/chalk/tls.rs (limited to 'crates/ra_hir_ty/src/traits') diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs deleted file mode 100644 index b33653417..000000000 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ /dev/null @@ -1,586 +0,0 @@ -//! Conversion code from/to Chalk. -use std::sync::Arc; - -use log::debug; - -use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; -use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; - -use base_db::{salsa::InternKey, CrateId}; -use hir_def::{ - lang_item::{lang_attr, LangItemTarget}, - AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, -}; - -use super::ChalkContext; -use crate::{ - db::HirDatabase, - display::HirDisplay, - method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, - utils::generics, - CallableDefId, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor, -}; -use mapping::{ - convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, -}; - -pub use self::interner::*; - -pub(super) mod tls; -mod interner; -mod mapping; - -pub(super) trait ToChalk { - type Chalk; - fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; - fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; -} - -pub(super) fn from_chalk(db: &dyn HirDatabase, chalk: ChalkT) -> T -where - T: ToChalk, -{ - T::from_chalk(db, chalk) -} - -impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { - fn associated_ty_data(&self, id: AssocTypeId) -> Arc { - self.db.associated_ty_data(id) - } - fn trait_datum(&self, trait_id: TraitId) -> Arc { - self.db.trait_datum(self.krate, trait_id) - } - fn adt_datum(&self, struct_id: AdtId) -> Arc { - self.db.struct_datum(self.krate, struct_id) - } - fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr { - rust_ir::AdtRepr { repr_c: false, repr_packed: false } - } - fn impl_datum(&self, impl_id: ImplId) -> Arc { - self.db.impl_datum(self.krate, impl_id) - } - - fn fn_def_datum( - &self, - fn_def_id: chalk_ir::FnDefId, - ) -> Arc> { - self.db.fn_def_datum(self.krate, fn_def_id) - } - - fn impls_for_trait( - &self, - trait_id: TraitId, - parameters: &[GenericArg], - binders: &CanonicalVarKinds, - ) -> Vec { - debug!("impls_for_trait {:?}", trait_id); - let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); - - let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); - - fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds) -> Option { - if let Ty::Bound(bv) = ty { - let binders = binders.as_slice(&Interner); - if bv.debruijn == DebruijnIndex::INNERMOST { - if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { - return Some(tk); - } - } - } - None - } - - let self_ty_fp = TyFingerprint::for_impl(&ty); - let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { - Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS, - Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS, - _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), - }; - - // Note: Since we're using impls_for_trait, only impls where the trait - // can be resolved should ever reach Chalk. `impl_datum` relies on that - // and will panic if the trait can't be resolved. - let in_deps = self.db.trait_impls_in_deps(self.krate); - let in_self = self.db.trait_impls_in_crate(self.krate); - let impl_maps = [in_deps, in_self]; - - let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); - - let result: Vec<_> = if fps.is_empty() { - debug!("Unrestricted search for {:?} impls...", trait_); - impl_maps - .iter() - .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk)) - .collect() - } else { - impl_maps - .iter() - .flat_map(|crate_impl_defs| { - fps.iter().flat_map(move |fp| { - crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) - }) - }) - .collect() - }; - - debug!("impls_for_trait returned {} impls", result.len()); - result - } - fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: AdtId) -> bool { - debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id); - false // FIXME - } - fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc { - self.db.associated_ty_value(self.krate, id) - } - - fn custom_clauses(&self) -> Vec> { - vec![] - } - fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec { - // We don't do coherence checking (yet) - unimplemented!() - } - fn interner(&self) -> &Interner { - &Interner - } - fn well_known_trait_id( - &self, - well_known_trait: rust_ir::WellKnownTrait, - ) -> Option> { - let lang_attr = lang_attr_from_well_known_trait(well_known_trait); - let trait_ = match self.db.lang_item(self.krate, lang_attr.into()) { - Some(LangItemTarget::TraitId(trait_)) => trait_, - _ => return None, - }; - Some(trait_.to_chalk(self.db)) - } - - fn program_clauses_for_env( - &self, - environment: &chalk_ir::Environment, - ) -> chalk_ir::ProgramClauses { - self.db.program_clauses_for_chalk_env(self.krate, environment.clone()) - } - - fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId) -> Arc { - let interned_id = crate::db::InternedOpaqueTyId::from(id); - let full_id = self.db.lookup_intern_impl_trait_id(interned_id); - let (func, idx) = match full_id { - crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx), - }; - let datas = - self.db.return_type_impl_traits(func).expect("impl trait id without impl traits"); - let data = &datas.value.impl_traits[idx as usize]; - let bound = OpaqueTyDatumBound { - bounds: make_binders( - data.bounds - .value - .iter() - .cloned() - .filter(|b| !b.is_error()) - .map(|b| b.to_chalk(self.db)) - .collect(), - 1, - ), - where_clauses: make_binders(vec![], 0), - }; - let num_vars = datas.num_binders; - Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) }) - } - - fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId) -> chalk_ir::Ty { - // FIXME: actually provide the hidden type; it is relevant for auto traits - Ty::Unknown.to_chalk(self.db) - } - - fn is_object_safe(&self, _trait_id: chalk_ir::TraitId) -> bool { - // FIXME: implement actual object safety - true - } - - fn closure_kind( - &self, - _closure_id: chalk_ir::ClosureId, - _substs: &chalk_ir::Substitution, - ) -> rust_ir::ClosureKind { - // Fn is the closure kind that implements all three traits - rust_ir::ClosureKind::Fn - } - fn closure_inputs_and_output( - &self, - _closure_id: chalk_ir::ClosureId, - substs: &chalk_ir::Substitution, - ) -> chalk_ir::Binders> { - let sig_ty: Ty = - from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); - let sig = FnSig::from_fn_ptr_substs( - &sig_ty.substs().expect("first closure param should be fn ptr"), - false, - ); - let io = rust_ir::FnDefInputsAndOutputDatum { - argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), - return_type: sig.ret().clone().to_chalk(self.db), - }; - make_binders(io.shifted_in(&Interner), 0) - } - fn closure_upvars( - &self, - _closure_id: chalk_ir::ClosureId, - _substs: &chalk_ir::Substitution, - ) -> chalk_ir::Binders> { - let ty = Ty::unit().to_chalk(self.db); - make_binders(ty, 0) - } - fn closure_fn_substitution( - &self, - _closure_id: chalk_ir::ClosureId, - _substs: &chalk_ir::Substitution, - ) -> chalk_ir::Substitution { - Substs::empty().to_chalk(self.db) - } - - fn trait_name(&self, _trait_id: chalk_ir::TraitId) -> String { - unimplemented!() - } - fn adt_name(&self, _struct_id: chalk_ir::AdtId) -> String { - unimplemented!() - } - fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId) -> String { - unimplemented!() - } - fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId) -> String { - unimplemented!() - } - fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId) -> String { - unimplemented!() - } -} - -pub(crate) fn program_clauses_for_chalk_env_query( - db: &dyn HirDatabase, - krate: CrateId, - environment: chalk_ir::Environment, -) -> chalk_ir::ProgramClauses { - chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment) -} - -pub(crate) fn associated_ty_data_query( - db: &dyn HirDatabase, - id: AssocTypeId, -) -> Arc { - debug!("associated_ty_data {:?}", id); - let type_alias: TypeAliasId = from_chalk(db, id); - let trait_ = match type_alias.lookup(db.upcast()).container { - AssocContainerId::TraitId(t) => t, - _ => panic!("associated type not in trait"), - }; - - // Lower bounds -- we could/should maybe move this to a separate query in `lower` - let type_alias_data = db.type_alias_data(type_alias); - let generic_params = generics(db.upcast(), type_alias.into()); - let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); - let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); - let ctx = crate::TyLoweringContext::new(db, &resolver) - .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); - let self_ty = Ty::Bound(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)); - let bounds = type_alias_data - .bounds - .iter() - .flat_map(|bound| GenericPredicate::from_type_bound(&ctx, bound, self_ty.clone())) - .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty)) - .map(|bound| make_binders(bound.shifted_in(&Interner), 0)) - .collect(); - - let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars); - let bound_data = rust_ir::AssociatedTyDatumBound { bounds, where_clauses }; - let datum = AssociatedTyDatum { - trait_id: trait_.to_chalk(db), - id, - name: type_alias, - binders: make_binders(bound_data, generic_params.len()), - }; - Arc::new(datum) -} - -pub(crate) fn trait_datum_query( - db: &dyn HirDatabase, - krate: CrateId, - trait_id: TraitId, -) -> Arc { - debug!("trait_datum {:?}", trait_id); - let trait_: hir_def::TraitId = from_chalk(db, trait_id); - let trait_data = db.trait_data(trait_); - debug!("trait {:?} = {:?}", trait_id, trait_data.name); - let generic_params = generics(db.upcast(), trait_.into()); - let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); - let flags = rust_ir::TraitFlags { - auto: trait_data.auto, - upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate, - non_enumerable: true, - coinductive: false, // only relevant for Chalk testing - // FIXME: set these flags correctly - marker: false, - fundamental: false, - }; - let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); - let associated_ty_ids = - trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); - let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; - let well_known = - lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); - let trait_datum = TraitDatum { - id: trait_id, - binders: make_binders(trait_datum_bound, bound_vars.len()), - flags, - associated_ty_ids, - well_known, - }; - Arc::new(trait_datum) -} - -fn well_known_trait_from_lang_attr(name: &str) -> Option { - Some(match name { - "sized" => WellKnownTrait::Sized, - "copy" => WellKnownTrait::Copy, - "clone" => WellKnownTrait::Clone, - "drop" => WellKnownTrait::Drop, - "fn_once" => WellKnownTrait::FnOnce, - "fn_mut" => WellKnownTrait::FnMut, - "fn" => WellKnownTrait::Fn, - "unsize" => WellKnownTrait::Unsize, - _ => return None, - }) -} - -fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str { - match attr { - WellKnownTrait::Sized => "sized", - WellKnownTrait::Copy => "copy", - WellKnownTrait::Clone => "clone", - WellKnownTrait::Drop => "drop", - WellKnownTrait::FnOnce => "fn_once", - WellKnownTrait::FnMut => "fn_mut", - WellKnownTrait::Fn => "fn", - WellKnownTrait::Unsize => "unsize", - } -} - -pub(crate) fn struct_datum_query( - db: &dyn HirDatabase, - krate: CrateId, - struct_id: AdtId, -) -> Arc { - debug!("struct_datum {:?}", struct_id); - let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id)); - debug!("struct {:?} = {:?}", struct_id, type_ctor); - let num_params = type_ctor.num_ty_params(db); - let upstream = type_ctor.krate(db) != Some(krate); - let where_clauses = type_ctor - .as_generic_def() - .map(|generic_def| { - let generic_params = generics(db.upcast(), generic_def); - let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); - convert_where_clauses(db, generic_def, &bound_vars) - }) - .unwrap_or_else(Vec::new); - let flags = rust_ir::AdtFlags { - upstream, - // FIXME set fundamental and phantom_data flags correctly - fundamental: false, - phantom_data: false, - }; - // FIXME provide enum variants properly (for auto traits) - let variant = rust_ir::AdtVariantDatum { - fields: Vec::new(), // FIXME add fields (only relevant for auto traits), - }; - let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses }; - let struct_datum = StructDatum { - // FIXME set ADT kind - kind: rust_ir::AdtKind::Struct, - id: struct_id, - binders: make_binders(struct_datum_bound, num_params), - flags, - }; - Arc::new(struct_datum) -} - -pub(crate) fn impl_datum_query( - db: &dyn HirDatabase, - krate: CrateId, - impl_id: ImplId, -) -> Arc { - let _p = profile::span("impl_datum"); - debug!("impl_datum {:?}", impl_id); - let impl_: hir_def::ImplId = from_chalk(db, impl_id); - impl_def_datum(db, krate, impl_id, impl_) -} - -fn impl_def_datum( - db: &dyn HirDatabase, - krate: CrateId, - chalk_id: ImplId, - impl_id: hir_def::ImplId, -) -> Arc { - let trait_ref = db - .impl_trait(impl_id) - // ImplIds for impls where the trait ref can't be resolved should never reach Chalk - .expect("invalid impl passed to Chalk") - .value; - let impl_data = db.impl_data(impl_id); - - let generic_params = generics(db.upcast(), impl_id.into()); - let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); - let trait_ = trait_ref.trait_; - let impl_type = if impl_id.lookup(db.upcast()).container.module(db.upcast()).krate == krate { - rust_ir::ImplType::Local - } else { - rust_ir::ImplType::External - }; - let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars); - let negative = impl_data.is_negative; - debug!( - "impl {:?}: {}{} where {:?}", - chalk_id, - if negative { "!" } else { "" }, - trait_ref.display(db), - where_clauses - ); - let trait_ref = trait_ref.to_chalk(db); - - let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive }; - - let impl_datum_bound = rust_ir::ImplDatumBound { trait_ref, where_clauses }; - let trait_data = db.trait_data(trait_); - let associated_ty_value_ids = impl_data - .items - .iter() - .filter_map(|item| match item { - AssocItemId::TypeAliasId(type_alias) => Some(*type_alias), - _ => None, - }) - .filter(|&type_alias| { - // don't include associated types that don't exist in the trait - let name = &db.type_alias_data(type_alias).name; - trait_data.associated_type_by_name(name).is_some() - }) - .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db)) - .collect(); - debug!("impl_datum: {:?}", impl_datum_bound); - let impl_datum = ImplDatum { - binders: make_binders(impl_datum_bound, bound_vars.len()), - impl_type, - polarity, - associated_ty_value_ids, - }; - Arc::new(impl_datum) -} - -pub(crate) fn associated_ty_value_query( - db: &dyn HirDatabase, - krate: CrateId, - id: AssociatedTyValueId, -) -> Arc { - let type_alias: TypeAliasAsValue = from_chalk(db, id); - type_alias_associated_ty_value(db, krate, type_alias.0) -} - -fn type_alias_associated_ty_value( - db: &dyn HirDatabase, - _krate: CrateId, - type_alias: TypeAliasId, -) -> Arc { - let type_alias_data = db.type_alias_data(type_alias); - let impl_id = match type_alias.lookup(db.upcast()).container { - AssocContainerId::ImplId(it) => it, - _ => panic!("assoc ty value should be in impl"), - }; - - let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved - - let assoc_ty = db - .trait_data(trait_ref.trait_) - .associated_type_by_name(&type_alias_data.name) - .expect("assoc ty value should not exist"); // validated when building the impl data as well - let ty = db.ty(type_alias.into()); - let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; - let value = rust_ir::AssociatedTyValue { - impl_id: impl_id.to_chalk(db), - associated_ty_id: assoc_ty.to_chalk(db), - value: make_binders(value_bound, ty.num_binders), - }; - Arc::new(value) -} - -pub(crate) fn fn_def_datum_query( - db: &dyn HirDatabase, - _krate: CrateId, - fn_def_id: FnDefId, -) -> Arc { - let callable_def: CallableDefId = from_chalk(db, fn_def_id); - let generic_params = generics(db.upcast(), callable_def.into()); - let sig = db.callable_item_signature(callable_def); - let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); - let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); - let bound = rust_ir::FnDefDatumBound { - // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway - inputs_and_output: make_binders( - rust_ir::FnDefInputsAndOutputDatum { - argument_types: sig - .value - .params() - .iter() - .map(|ty| ty.clone().to_chalk(db)) - .collect(), - return_type: sig.value.ret().clone().to_chalk(db), - } - .shifted_in(&Interner), - 0, - ), - where_clauses, - }; - let datum = FnDefDatum { - id: fn_def_id, - abi: (), - safety: chalk_ir::Safety::Safe, - variadic: sig.value.is_varargs, - binders: make_binders(bound, sig.num_binders), - }; - Arc::new(datum) -} - -impl From for crate::db::InternedCallableDefId { - fn from(fn_def_id: FnDefId) -> Self { - InternKey::from_intern_id(fn_def_id.0) - } -} - -impl From for FnDefId { - fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { - chalk_ir::FnDefId(callable_def_id.as_intern_id()) - } -} - -impl From for crate::db::InternedOpaqueTyId { - fn from(id: OpaqueTyId) -> Self { - InternKey::from_intern_id(id.0) - } -} - -impl From for OpaqueTyId { - fn from(id: crate::db::InternedOpaqueTyId) -> Self { - chalk_ir::OpaqueTyId(id.as_intern_id()) - } -} - -impl From> for crate::db::ClosureId { - fn from(id: chalk_ir::ClosureId) -> Self { - Self::from_intern_id(id.0) - } -} - -impl From for chalk_ir::ClosureId { - fn from(id: crate::db::ClosureId) -> Self { - chalk_ir::ClosureId(id.as_intern_id()) - } -} diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs deleted file mode 100644 index fc0f9c201..000000000 --- a/crates/ra_hir_ty/src/traits/chalk/interner.rs +++ /dev/null @@ -1,383 +0,0 @@ -//! Implementation of the Chalk `Interner` trait, which allows customizing the -//! representation of the various objects Chalk deals with (types, goals etc.). - -use super::tls; -use base_db::salsa::InternId; -use chalk_ir::{GenericArg, Goal, GoalData}; -use hir_def::TypeAliasId; -use std::{fmt, sync::Arc}; - -#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct Interner; - -pub type AssocTypeId = chalk_ir::AssocTypeId; -pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum; -pub type TraitId = chalk_ir::TraitId; -pub type TraitDatum = chalk_solve::rust_ir::TraitDatum; -pub type AdtId = chalk_ir::AdtId; -pub type StructDatum = chalk_solve::rust_ir::AdtDatum; -pub type ImplId = chalk_ir::ImplId; -pub type ImplDatum = chalk_solve::rust_ir::ImplDatum; -pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId; -pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue; -pub type FnDefId = chalk_ir::FnDefId; -pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum; -pub type OpaqueTyId = chalk_ir::OpaqueTyId; -pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum; - -impl chalk_ir::interner::Interner for Interner { - type InternedType = Box>; // FIXME use Arc? - type InternedLifetime = chalk_ir::LifetimeData; - type InternedConst = Arc>; - type InternedConcreteConst = (); - type InternedGenericArg = chalk_ir::GenericArgData; - type InternedGoal = Arc>; - type InternedGoals = Vec>; - type InternedSubstitution = Vec>; - type InternedProgramClause = chalk_ir::ProgramClauseData; - type InternedProgramClauses = Arc<[chalk_ir::ProgramClause]>; - type InternedQuantifiedWhereClauses = Vec>; - type InternedVariableKinds = Vec>; - type InternedCanonicalVarKinds = Vec>; - type InternedConstraints = Vec>>; - type DefId = InternId; - type InternedAdtId = hir_def::AdtId; - type Identifier = TypeAliasId; - type FnAbi = (); - - fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) - } - - fn debug_trait_id(type_kind_id: TraitId, fmt: &mut fmt::Formatter<'_>) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt))) - } - - fn debug_assoc_type_id(id: AssocTypeId, fmt: &mut fmt::Formatter<'_>) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt))) - } - - fn debug_alias( - alias: &chalk_ir::AliasTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt))) - } - - fn debug_projection_ty( - proj: &chalk_ir::ProjectionTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt))) - } - - fn debug_opaque_ty( - opaque_ty: &chalk_ir::OpaqueTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt))) - } - - fn debug_opaque_ty_id( - opaque_ty_id: chalk_ir::OpaqueTyId, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt))) - } - - fn debug_ty(ty: &chalk_ir::Ty, fmt: &mut fmt::Formatter<'_>) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt))) - } - - fn debug_lifetime( - lifetime: &chalk_ir::Lifetime, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt))) - } - - fn debug_generic_arg( - parameter: &GenericArg, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt))) - } - - fn debug_goal(goal: &Goal, fmt: &mut fmt::Formatter<'_>) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_goal(goal, fmt))) - } - - fn debug_goals( - goals: &chalk_ir::Goals, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_goals(goals, fmt))) - } - - fn debug_program_clause_implication( - pci: &chalk_ir::ProgramClauseImplication, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt))) - } - - fn debug_application_ty( - application_ty: &chalk_ir::ApplicationTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_application_ty(application_ty, fmt))) - } - - fn debug_substitution( - substitution: &chalk_ir::Substitution, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_substitution(substitution, fmt))) - } - - fn debug_separator_trait_ref( - separator_trait_ref: &chalk_ir::SeparatorTraitRef, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| { - Some(prog?.debug_separator_trait_ref(separator_trait_ref, fmt)) - }) - } - - fn debug_fn_def_id( - fn_def_id: chalk_ir::FnDefId, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt))) - } - fn debug_const( - constant: &chalk_ir::Const, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_const(constant, fmt))) - } - fn debug_variable_kinds( - variable_kinds: &chalk_ir::VariableKinds, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_variable_kinds(variable_kinds, fmt))) - } - fn debug_variable_kinds_with_angles( - variable_kinds: &chalk_ir::VariableKinds, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| { - Some(prog?.debug_variable_kinds_with_angles(variable_kinds, fmt)) - }) - } - fn debug_canonical_var_kinds( - canonical_var_kinds: &chalk_ir::CanonicalVarKinds, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| { - Some(prog?.debug_canonical_var_kinds(canonical_var_kinds, fmt)) - }) - } - fn debug_program_clause( - clause: &chalk_ir::ProgramClause, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_program_clause(clause, fmt))) - } - fn debug_program_clauses( - clauses: &chalk_ir::ProgramClauses, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_program_clauses(clauses, fmt))) - } - fn debug_quantified_where_clauses( - clauses: &chalk_ir::QuantifiedWhereClauses, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt))) - } - - fn intern_ty(&self, ty: chalk_ir::TyData) -> Box> { - Box::new(ty) - } - - fn ty_data<'a>(&self, ty: &'a Box>) -> &'a chalk_ir::TyData { - ty - } - - fn intern_lifetime( - &self, - lifetime: chalk_ir::LifetimeData, - ) -> chalk_ir::LifetimeData { - lifetime - } - - fn lifetime_data<'a>( - &self, - lifetime: &'a chalk_ir::LifetimeData, - ) -> &'a chalk_ir::LifetimeData { - lifetime - } - - fn intern_const(&self, constant: chalk_ir::ConstData) -> Arc> { - Arc::new(constant) - } - - fn const_data<'a>( - &self, - constant: &'a Arc>, - ) -> &'a chalk_ir::ConstData { - constant - } - - fn const_eq(&self, _ty: &Box>, _c1: &(), _c2: &()) -> bool { - true - } - - fn intern_generic_arg( - &self, - parameter: chalk_ir::GenericArgData, - ) -> chalk_ir::GenericArgData { - parameter - } - - fn generic_arg_data<'a>( - &self, - parameter: &'a chalk_ir::GenericArgData, - ) -> &'a chalk_ir::GenericArgData { - parameter - } - - fn intern_goal(&self, goal: GoalData) -> Arc> { - Arc::new(goal) - } - - fn intern_goals( - &self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect() - } - - fn goal_data<'a>(&self, goal: &'a Arc>) -> &'a GoalData { - goal - } - - fn goals_data<'a>(&self, goals: &'a Vec>) -> &'a [Goal] { - goals - } - - fn intern_substitution( - &self, - data: impl IntoIterator, E>>, - ) -> Result>, E> { - data.into_iter().collect() - } - - fn substitution_data<'a>( - &self, - substitution: &'a Vec>, - ) -> &'a [GenericArg] { - substitution - } - - fn intern_program_clause( - &self, - data: chalk_ir::ProgramClauseData, - ) -> chalk_ir::ProgramClauseData { - data - } - - fn program_clause_data<'a>( - &self, - clause: &'a chalk_ir::ProgramClauseData, - ) -> &'a chalk_ir::ProgramClauseData { - clause - } - - fn intern_program_clauses( - &self, - data: impl IntoIterator, E>>, - ) -> Result]>, E> { - data.into_iter().collect() - } - - fn program_clauses_data<'a>( - &self, - clauses: &'a Arc<[chalk_ir::ProgramClause]>, - ) -> &'a [chalk_ir::ProgramClause] { - &clauses - } - - fn intern_quantified_where_clauses( - &self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect() - } - - fn quantified_where_clauses_data<'a>( - &self, - clauses: &'a Self::InternedQuantifiedWhereClauses, - ) -> &'a [chalk_ir::QuantifiedWhereClause] { - clauses - } - - fn intern_generic_arg_kinds( - &self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect() - } - - fn variable_kinds_data<'a>( - &self, - parameter_kinds: &'a Self::InternedVariableKinds, - ) -> &'a [chalk_ir::VariableKind] { - ¶meter_kinds - } - - fn intern_canonical_var_kinds( - &self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect() - } - - fn canonical_var_kinds_data<'a>( - &self, - canonical_var_kinds: &'a Self::InternedCanonicalVarKinds, - ) -> &'a [chalk_ir::CanonicalVarKind] { - &canonical_var_kinds - } - - fn intern_constraints( - &self, - data: impl IntoIterator>, E>>, - ) -> Result { - data.into_iter().collect() - } - - fn constraints_data<'a>( - &self, - constraints: &'a Self::InternedConstraints, - ) -> &'a [chalk_ir::InEnvironment>] { - constraints - } - fn debug_closure_id( - _fn_def_id: chalk_ir::ClosureId, - _fmt: &mut fmt::Formatter<'_>, - ) -> Option { - None - } - fn debug_constraints( - _clauses: &chalk_ir::Constraints, - _fmt: &mut fmt::Formatter<'_>, - ) -> Option { - None - } -} - -impl chalk_ir::interner::HasInterner for Interner { - type Interner = Self; -} diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs deleted file mode 100644 index fe62f3fa7..000000000 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ /dev/null @@ -1,787 +0,0 @@ -//! This module contains the implementations of the `ToChalk` trait, which -//! handles conversion between our data types and their corresponding types in -//! Chalk (in both directions); plus some helper functions for more specialized -//! conversions. - -use chalk_ir::{ - cast::Cast, fold::shift::Shift, interner::HasInterner, PlaceholderIndex, Scalar, TypeName, - UniverseIndex, -}; -use chalk_solve::rust_ir; - -use base_db::salsa::InternKey; -use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, TypeAliasId}; - -use crate::{ - db::HirDatabase, - primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, - traits::{Canonical, Obligation}, - ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, - ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, -}; - -use super::interner::*; -use super::*; - -impl ToChalk for Ty { - type Chalk = chalk_ir::Ty; - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { - match self { - Ty::Apply(apply_ty) => match apply_ty.ctor { - TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), - TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), - TypeCtor::FnPtr { num_args: _, is_varargs } => { - let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); - chalk_ir::TyData::Function(chalk_ir::FnPointer { - num_binders: 0, - abi: (), - safety: chalk_ir::Safety::Safe, - variadic: is_varargs, - substitution, - }) - .intern(&Interner) - } - _ => { - let name = apply_ty.ctor.to_chalk(db); - let substitution = apply_ty.parameters.to_chalk(db); - chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) - } - }, - Ty::Projection(proj_ty) => { - let associated_ty_id = proj_ty.associated_ty.to_chalk(db); - let substitution = proj_ty.parameters.to_chalk(db); - chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id, - substitution, - }) - .cast(&Interner) - .intern(&Interner) - } - Ty::Placeholder(id) => { - let interned_id = db.intern_type_param_id(id); - PlaceholderIndex { - ui: UniverseIndex::ROOT, - idx: interned_id.as_intern_id().as_usize(), - } - .to_ty::(&Interner) - } - Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), - Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), - Ty::Dyn(predicates) => { - let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( - &Interner, - predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), - ); - let bounded_ty = chalk_ir::DynTy { - bounds: make_binders(where_clauses, 1), - lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner), - }; - chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) - } - Ty::Opaque(opaque_ty) => { - let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); - let substitution = opaque_ty.parameters.to_chalk(db); - chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { - opaque_ty_id, - substitution, - })) - .intern(&Interner) - } - Ty::Unknown => { - let substitution = chalk_ir::Substitution::empty(&Interner); - let name = TypeName::Error; - chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) - } - } - } - fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty) -> Self { - match chalk.data(&Interner).clone() { - chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { - TypeName::Error => Ty::Unknown, - TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), - TypeName::Array => array_from_chalk(db, apply_ty.substitution), - _ => { - let ctor = from_chalk(db, apply_ty.name); - let parameters = from_chalk(db, apply_ty.substitution); - Ty::Apply(ApplicationTy { ctor, parameters }) - } - }, - chalk_ir::TyData::Placeholder(idx) => { - assert_eq!(idx.ui, UniverseIndex::ROOT); - let interned_id = crate::db::GlobalTypeParamId::from_intern_id( - crate::salsa::InternId::from(idx.idx), - ); - Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) - } - chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { - let associated_ty = from_chalk(db, proj.associated_ty_id); - let parameters = from_chalk(db, proj.substitution); - Ty::Projection(ProjectionTy { associated_ty, parameters }) - } - chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { - let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); - let parameters = from_chalk(db, opaque_ty.substitution); - Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) - } - chalk_ir::TyData::Function(chalk_ir::FnPointer { - num_binders, - variadic, - substitution, - .. - }) => { - assert_eq!(num_binders, 0); - let parameters: Substs = from_chalk( - db, - substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), - ); - Ty::Apply(ApplicationTy { - ctor: TypeCtor::FnPtr { - num_args: (parameters.len() - 1) as u16, - is_varargs: variadic, - }, - parameters, - }) - } - chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), - chalk_ir::TyData::InferenceVar(_iv, _kind) => Ty::Unknown, - chalk_ir::TyData::Dyn(where_clauses) => { - assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); - let predicates = where_clauses - .bounds - .skip_binders() - .iter(&Interner) - .map(|c| from_chalk(db, c.clone())) - .collect(); - Ty::Dyn(predicates) - } - } - } -} - -const FAKE_PLACEHOLDER: PlaceholderIndex = - PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; - -/// We currently don't model lifetimes, but Chalk does. So, we have to insert a -/// fake lifetime here, because Chalks built-in logic may expect it to be there. -fn ref_to_chalk( - db: &dyn HirDatabase, - mutability: Mutability, - subst: Substs, -) -> chalk_ir::Ty { - let arg = subst[0].clone().to_chalk(db); - let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner); - chalk_ir::ApplicationTy { - name: TypeName::Ref(mutability.to_chalk(db)), - substitution: chalk_ir::Substitution::from_iter( - &Interner, - vec![lifetime.cast(&Interner), arg.cast(&Interner)], - ), - } - .intern(&Interner) -} - -/// Here we remove the lifetime from the type we got from Chalk. -fn ref_from_chalk( - db: &dyn HirDatabase, - mutability: chalk_ir::Mutability, - subst: chalk_ir::Substitution, -) -> Ty { - let tys = subst - .iter(&Interner) - .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone()))) - .collect(); - Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) -} - -/// We currently don't model constants, but Chalk does. So, we have to insert a -/// fake constant here, because Chalks built-in logic may expect it to be there. -fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty { - let arg = subst[0].clone().to_chalk(db); - let usize_ty = chalk_ir::ApplicationTy { - name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)), - substitution: chalk_ir::Substitution::empty(&Interner), - } - .intern(&Interner); - let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty); - chalk_ir::ApplicationTy { - name: TypeName::Array, - substitution: chalk_ir::Substitution::from_iter( - &Interner, - vec![arg.cast(&Interner), const_.cast(&Interner)], - ), - } - .intern(&Interner) -} - -/// Here we remove the const from the type we got from Chalk. -fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution) -> Ty { - let tys = subst - .iter(&Interner) - .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone()))) - .collect(); - Ty::apply(TypeCtor::Array, Substs(tys)) -} - -impl ToChalk for Substs { - type Chalk = chalk_ir::Substitution; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution { - chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) - } - - fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution) -> Substs { - let tys = parameters - .iter(&Interner) - .map(|p| match p.ty(&Interner) { - Some(ty) => from_chalk(db, ty.clone()), - None => unimplemented!(), - }) - .collect(); - Substs(tys) - } -} - -impl ToChalk for TraitRef { - type Chalk = chalk_ir::TraitRef; - - fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef { - let trait_id = self.trait_.to_chalk(db); - let substitution = self.substs.to_chalk(db); - chalk_ir::TraitRef { trait_id, substitution } - } - - fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { - let trait_ = from_chalk(db, trait_ref.trait_id); - let substs = from_chalk(db, trait_ref.substitution); - TraitRef { trait_, substs } - } -} - -impl ToChalk for hir_def::TraitId { - type Chalk = TraitId; - - fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId { - chalk_ir::TraitId(self.as_intern_id()) - } - - fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId { - InternKey::from_intern_id(trait_id.0) - } -} - -impl ToChalk for OpaqueTyId { - type Chalk = chalk_ir::OpaqueTyId; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId { - db.intern_impl_trait_id(self).into() - } - - fn from_chalk( - db: &dyn HirDatabase, - opaque_ty_id: chalk_ir::OpaqueTyId, - ) -> OpaqueTyId { - db.lookup_intern_impl_trait_id(opaque_ty_id.into()) - } -} - -impl ToChalk for TypeCtor { - type Chalk = TypeName; - - fn to_chalk(self, db: &dyn HirDatabase) -> TypeName { - match self { - TypeCtor::AssociatedType(type_alias) => { - let type_id = type_alias.to_chalk(db); - TypeName::AssociatedType(type_id) - } - - TypeCtor::OpaqueType(impl_trait_id) => { - let id = impl_trait_id.to_chalk(db); - TypeName::OpaqueType(id) - } - - TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), - TypeCtor::Char => TypeName::Scalar(Scalar::Char), - TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)), - TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => { - TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) - } - TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => { - TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) - } - - TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), - TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), - TypeCtor::Slice => TypeName::Slice, - TypeCtor::Array => TypeName::Array, - TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), - TypeCtor::Str => TypeName::Str, - TypeCtor::FnDef(callable_def) => { - let id = callable_def.to_chalk(db); - TypeName::FnDef(id) - } - TypeCtor::Never => TypeName::Never, - - TypeCtor::Closure { def, expr } => { - let closure_id = db.intern_closure((def, expr)); - TypeName::Closure(closure_id.into()) - } - - TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)), - - TypeCtor::FnPtr { .. } => { - // This should not be reached, since Chalk doesn't represent - // function pointers with TypeName - unreachable!() - } - } - } - - fn from_chalk(db: &dyn HirDatabase, type_name: TypeName) -> TypeCtor { - match type_name { - TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0), - TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), - TypeName::OpaqueType(opaque_type_id) => { - TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) - } - - TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, - TypeName::Scalar(Scalar::Char) => TypeCtor::Char, - TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy { - signedness: Signedness::Signed, - bitness: bitness_from_chalk_int(int_ty), - }), - TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy { - signedness: Signedness::Unsigned, - bitness: bitness_from_chalk_uint(uint_ty), - }), - TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { - TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) - } - TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { - TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) - } - TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, - TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), - TypeName::Slice => TypeCtor::Slice, - TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)), - TypeName::Str => TypeCtor::Str, - TypeName::Never => TypeCtor::Never, - - TypeName::FnDef(fn_def_id) => { - let callable_def = from_chalk(db, fn_def_id); - TypeCtor::FnDef(callable_def) - } - TypeName::Array => TypeCtor::Array, - - TypeName::Closure(id) => { - let id: crate::db::ClosureId = id.into(); - let (def, expr) = db.lookup_intern_closure(id); - TypeCtor::Closure { def, expr } - } - - TypeName::Error => { - // this should not be reached, since we don't represent TypeName::Error with TypeCtor - unreachable!() - } - } - } -} - -fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { - use chalk_ir::UintTy; - - match uint_ty { - UintTy::Usize => IntBitness::Xsize, - UintTy::U8 => IntBitness::X8, - UintTy::U16 => IntBitness::X16, - UintTy::U32 => IntBitness::X32, - UintTy::U64 => IntBitness::X64, - UintTy::U128 => IntBitness::X128, - } -} - -fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness { - use chalk_ir::IntTy; - - match int_ty { - IntTy::Isize => IntBitness::Xsize, - IntTy::I8 => IntBitness::X8, - IntTy::I16 => IntBitness::X16, - IntTy::I32 => IntBitness::X32, - IntTy::I64 => IntBitness::X64, - IntTy::I128 => IntBitness::X128, - } -} - -fn int_ty_to_chalk(int_ty: IntTy) -> Scalar { - use chalk_ir::{IntTy, UintTy}; - - match int_ty.signedness { - Signedness::Signed => Scalar::Int(match int_ty.bitness { - IntBitness::Xsize => IntTy::Isize, - IntBitness::X8 => IntTy::I8, - IntBitness::X16 => IntTy::I16, - IntBitness::X32 => IntTy::I32, - IntBitness::X64 => IntTy::I64, - IntBitness::X128 => IntTy::I128, - }), - Signedness::Unsigned => Scalar::Uint(match int_ty.bitness { - IntBitness::Xsize => UintTy::Usize, - IntBitness::X8 => UintTy::U8, - IntBitness::X16 => UintTy::U16, - IntBitness::X32 => UintTy::U32, - IntBitness::X64 => UintTy::U64, - IntBitness::X128 => UintTy::U128, - }), - } -} - -impl ToChalk for Mutability { - type Chalk = chalk_ir::Mutability; - fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { - match self { - Mutability::Shared => chalk_ir::Mutability::Not, - Mutability::Mut => chalk_ir::Mutability::Mut, - } - } - fn from_chalk(_db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { - match chalk { - chalk_ir::Mutability::Mut => Mutability::Mut, - chalk_ir::Mutability::Not => Mutability::Shared, - } - } -} - -impl ToChalk for hir_def::ImplId { - type Chalk = ImplId; - - fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId { - chalk_ir::ImplId(self.as_intern_id()) - } - - fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId { - InternKey::from_intern_id(impl_id.0) - } -} - -impl ToChalk for CallableDefId { - type Chalk = FnDefId; - - fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { - db.intern_callable_def(self).into() - } - - fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { - db.lookup_intern_callable_def(fn_def_id.into()) - } -} - -impl ToChalk for TypeAliasId { - type Chalk = AssocTypeId; - - fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId { - chalk_ir::AssocTypeId(self.as_intern_id()) - } - - fn from_chalk(_db: &dyn HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId { - InternKey::from_intern_id(type_alias_id.0) - } -} - -pub struct TypeAliasAsValue(pub TypeAliasId); - -impl ToChalk for TypeAliasAsValue { - type Chalk = AssociatedTyValueId; - - fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId { - rust_ir::AssociatedTyValueId(self.0.as_intern_id()) - } - - fn from_chalk( - _db: &dyn HirDatabase, - assoc_ty_value_id: AssociatedTyValueId, - ) -> TypeAliasAsValue { - TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) - } -} - -impl ToChalk for GenericPredicate { - type Chalk = chalk_ir::QuantifiedWhereClause; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause { - match self { - GenericPredicate::Implemented(trait_ref) => { - let chalk_trait_ref = trait_ref.to_chalk(db); - let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner); - make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0) - } - GenericPredicate::Projection(projection_pred) => { - let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner); - let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner); - let alias = chalk_ir::AliasTy::Projection(projection); - make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0) - } - GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), - } - } - - fn from_chalk( - db: &dyn HirDatabase, - where_clause: chalk_ir::QuantifiedWhereClause, - ) -> GenericPredicate { - // we don't produce any where clauses with binders and can't currently deal with them - match where_clause - .skip_binders() - .shifted_out(&Interner) - .expect("unexpected bound vars in where clause") - { - chalk_ir::WhereClause::Implemented(tr) => { - GenericPredicate::Implemented(from_chalk(db, tr)) - } - chalk_ir::WhereClause::AliasEq(projection_eq) => { - let projection_ty = from_chalk( - db, - match projection_eq.alias { - chalk_ir::AliasTy::Projection(p) => p, - _ => unimplemented!(), - }, - ); - let ty = from_chalk(db, projection_eq.ty); - GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty }) - } - - chalk_ir::WhereClause::LifetimeOutlives(_) => { - // we shouldn't get these from Chalk - panic!("encountered LifetimeOutlives from Chalk") - } - - chalk_ir::WhereClause::TypeOutlives(_) => { - // we shouldn't get these from Chalk - panic!("encountered TypeOutlives from Chalk") - } - } - } -} - -impl ToChalk for ProjectionTy { - type Chalk = chalk_ir::ProjectionTy; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy { - chalk_ir::ProjectionTy { - associated_ty_id: self.associated_ty.to_chalk(db), - substitution: self.parameters.to_chalk(db), - } - } - - fn from_chalk( - db: &dyn HirDatabase, - projection_ty: chalk_ir::ProjectionTy, - ) -> ProjectionTy { - ProjectionTy { - associated_ty: from_chalk(db, projection_ty.associated_ty_id), - parameters: from_chalk(db, projection_ty.substitution), - } - } -} - -impl ToChalk for ProjectionPredicate { - type Chalk = chalk_ir::AliasEq; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq { - chalk_ir::AliasEq { - alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)), - ty: self.ty.to_chalk(db), - } - } - - fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq) -> Self { - unimplemented!() - } -} - -impl ToChalk for Obligation { - type Chalk = chalk_ir::DomainGoal; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal { - match self { - Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), - Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner), - } - } - - fn from_chalk(_db: &dyn HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { - unimplemented!() - } -} - -impl ToChalk for Canonical -where - T: ToChalk, - T::Chalk: HasInterner, -{ - type Chalk = chalk_ir::Canonical; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical { - let kinds = self - .kinds - .iter() - .map(|k| match k { - TyKind::General => chalk_ir::TyKind::General, - TyKind::Integer => chalk_ir::TyKind::Integer, - TyKind::Float => chalk_ir::TyKind::Float, - }) - .map(|tk| { - chalk_ir::CanonicalVarKind::new( - chalk_ir::VariableKind::Ty(tk), - chalk_ir::UniverseIndex::ROOT, - ) - }); - let value = self.value.to_chalk(db); - chalk_ir::Canonical { - value, - binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds), - } - } - - fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical) -> Canonical { - let kinds = canonical - .binders - .iter(&Interner) - .map(|k| match k.kind { - chalk_ir::VariableKind::Ty(tk) => match tk { - chalk_ir::TyKind::General => TyKind::General, - chalk_ir::TyKind::Integer => TyKind::Integer, - chalk_ir::TyKind::Float => TyKind::Float, - }, - chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), - chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), - }) - .collect(); - Canonical { kinds, value: from_chalk(db, canonical.value) } - } -} - -impl ToChalk for Arc { - type Chalk = chalk_ir::Environment; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Environment { - let mut clauses = Vec::new(); - for pred in &self.predicates { - if pred.is_error() { - // for env, we just ignore errors - continue; - } - let program_clause: chalk_ir::ProgramClause = - pred.clone().to_chalk(db).cast(&Interner); - clauses.push(program_clause.into_from_env_clause(&Interner)); - } - chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses) - } - - fn from_chalk( - _db: &dyn HirDatabase, - _env: chalk_ir::Environment, - ) -> Arc { - unimplemented!() - } -} - -impl ToChalk for InEnvironment -where - T::Chalk: chalk_ir::interner::HasInterner, -{ - type Chalk = chalk_ir::InEnvironment; - - fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment { - chalk_ir::InEnvironment { - environment: self.environment.to_chalk(db), - goal: self.value.to_chalk(db), - } - } - - fn from_chalk( - db: &dyn HirDatabase, - in_env: chalk_ir::InEnvironment, - ) -> InEnvironment { - InEnvironment { - environment: from_chalk(db, in_env.environment), - value: from_chalk(db, in_env.goal), - } - } -} - -pub(super) fn make_binders(value: T, num_vars: usize) -> chalk_ir::Binders -where - T: HasInterner, -{ - chalk_ir::Binders::new( - chalk_ir::VariableKinds::from_iter( - &Interner, - std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), - ), - value, - ) -} - -pub(super) fn convert_where_clauses( - db: &dyn HirDatabase, - def: GenericDefId, - substs: &Substs, -) -> Vec> { - let generic_predicates = db.generic_predicates(def); - let mut result = Vec::with_capacity(generic_predicates.len()); - for pred in generic_predicates.iter() { - if pred.value.is_error() { - // skip errored predicates completely - continue; - } - result.push(pred.clone().subst(substs).to_chalk(db)); - } - result -} - -pub(super) fn generic_predicate_to_inline_bound( - db: &dyn HirDatabase, - pred: &GenericPredicate, - self_ty: &Ty, -) -> Option> { - // An InlineBound is like a GenericPredicate, except the self type is left out. - // We don't have a special type for this, but Chalk does. - match pred { - GenericPredicate::Implemented(trait_ref) => { - if &trait_ref.substs[0] != self_ty { - // we can only convert predicates back to type bounds if they - // have the expected self type - return None; - } - let args_no_self = trait_ref.substs[1..] - .iter() - .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) - .collect(); - let trait_bound = - rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self }; - Some(rust_ir::InlineBound::TraitBound(trait_bound)) - } - GenericPredicate::Projection(proj) => { - if &proj.projection_ty.parameters[0] != self_ty { - return None; - } - let trait_ = match proj.projection_ty.associated_ty.lookup(db.upcast()).container { - AssocContainerId::TraitId(t) => t, - _ => panic!("associated type not in trait"), - }; - let args_no_self = proj.projection_ty.parameters[1..] - .iter() - .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) - .collect(); - let alias_eq_bound = rust_ir::AliasEqBound { - value: proj.ty.clone().to_chalk(db), - trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, - associated_ty_id: proj.projection_ty.associated_ty.to_chalk(db), - parameters: Vec::new(), // FIXME we don't support generic associated types yet - }; - Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) - } - GenericPredicate::Error => None, - } -} diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs deleted file mode 100644 index db915625c..000000000 --- a/crates/ra_hir_ty/src/traits/chalk/tls.rs +++ /dev/null @@ -1,358 +0,0 @@ -//! Implementation of Chalk debug helper functions using TLS. -use std::fmt; - -use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; -use itertools::Itertools; - -use super::{from_chalk, Interner}; -use crate::{db::HirDatabase, CallableDefId, TypeCtor}; -use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; - -pub use unsafe_tls::{set_current_program, with_current_program}; - -pub struct DebugContext<'a>(&'a dyn HirDatabase); - -impl DebugContext<'_> { - pub fn debug_struct_id( - &self, - id: super::AdtId, - f: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - let type_ctor: TypeCtor = from_chalk(self.0, TypeName::Adt(id)); - match type_ctor { - TypeCtor::Bool => write!(f, "bool")?, - TypeCtor::Char => write!(f, "char")?, - TypeCtor::Int(t) => write!(f, "{}", t)?, - TypeCtor::Float(t) => write!(f, "{}", t)?, - TypeCtor::Str => write!(f, "str")?, - TypeCtor::Slice => write!(f, "slice")?, - TypeCtor::Array => write!(f, "array")?, - TypeCtor::RawPtr(m) => write!(f, "*{}", m.as_keyword_for_ptr())?, - TypeCtor::Ref(m) => write!(f, "&{}", m.as_keyword_for_ref())?, - TypeCtor::Never => write!(f, "!")?, - TypeCtor::Tuple { .. } => { - write!(f, "()")?; - } - TypeCtor::FnPtr { .. } => { - write!(f, "fn")?; - } - TypeCtor::FnDef(def) => { - let name = match def { - CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(), - CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(), - CallableDefId::EnumVariantId(e) => { - let enum_data = self.0.enum_data(e.parent); - enum_data.variants[e.local_id].name.clone() - } - }; - match def { - CallableDefId::FunctionId(_) => write!(f, "{{fn {}}}", name)?, - CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => { - write!(f, "{{ctor {}}}", name)? - } - } - } - TypeCtor::Adt(def_id) => { - let name = match def_id { - AdtId::StructId(it) => self.0.struct_data(it).name.clone(), - AdtId::UnionId(it) => self.0.union_data(it).name.clone(), - AdtId::EnumId(it) => self.0.enum_data(it).name.clone(), - }; - write!(f, "{}", name)?; - } - TypeCtor::AssociatedType(type_alias) => { - let trait_ = match type_alias.lookup(self.0.upcast()).container { - AssocContainerId::TraitId(it) => it, - _ => panic!("not an associated type"), - }; - let trait_name = self.0.trait_data(trait_).name.clone(); - let name = self.0.type_alias_data(type_alias).name.clone(); - write!(f, "{}::{}", trait_name, name)?; - } - TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { - crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { - write!(f, "{{impl trait {} of {:?}}}", idx, func)?; - } - }, - TypeCtor::Closure { def, expr } => { - write!(f, "{{closure {:?} in ", expr.into_raw())?; - match def { - DefWithBodyId::FunctionId(func) => { - write!(f, "fn {}", self.0.function_data(func).name)? - } - DefWithBodyId::StaticId(s) => { - if let Some(name) = self.0.static_data(s).name.as_ref() { - write!(f, "body of static {}", name)?; - } else { - write!(f, "body of unnamed static {:?}", s)?; - } - } - DefWithBodyId::ConstId(c) => { - if let Some(name) = self.0.const_data(c).name.as_ref() { - write!(f, "body of const {}", name)?; - } else { - write!(f, "body of unnamed const {:?}", c)?; - } - } - }; - write!(f, "}}")?; - } - } - Ok(()) - } - - pub fn debug_trait_id( - &self, - id: super::TraitId, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - let trait_: hir_def::TraitId = from_chalk(self.0, id); - let trait_data = self.0.trait_data(trait_); - write!(fmt, "{}", trait_data.name) - } - - pub fn debug_assoc_type_id( - &self, - id: super::AssocTypeId, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - let type_alias: TypeAliasId = from_chalk(self.0, id); - let type_alias_data = self.0.type_alias_data(type_alias); - let trait_ = match type_alias.lookup(self.0.upcast()).container { - AssocContainerId::TraitId(t) => t, - _ => panic!("associated type not in trait"), - }; - let trait_data = self.0.trait_data(trait_); - write!(fmt, "{}::{}", trait_data.name, type_alias_data.name) - } - - pub fn debug_opaque_ty_id( - &self, - opaque_ty_id: chalk_ir::OpaqueTyId, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish() - } - - pub fn debug_alias( - &self, - alias_ty: &AliasTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - match alias_ty { - AliasTy::Projection(projection_ty) => self.debug_projection_ty(projection_ty, fmt), - AliasTy::Opaque(opaque_ty) => self.debug_opaque_ty(opaque_ty, fmt), - } - } - - pub fn debug_projection_ty( - &self, - projection_ty: &chalk_ir::ProjectionTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - let type_alias: TypeAliasId = from_chalk(self.0, projection_ty.associated_ty_id); - let type_alias_data = self.0.type_alias_data(type_alias); - let trait_ = match type_alias.lookup(self.0.upcast()).container { - AssocContainerId::TraitId(t) => t, - _ => panic!("associated type not in trait"), - }; - let trait_data = self.0.trait_data(trait_); - let params = projection_ty.substitution.as_slice(&Interner); - write!(fmt, "<{:?} as {}", ¶ms[0], trait_data.name,)?; - if params.len() > 1 { - write!( - fmt, - "<{}>", - ¶ms[1..].iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))), - )?; - } - write!(fmt, ">::{}", type_alias_data.name) - } - - pub fn debug_opaque_ty( - &self, - opaque_ty: &chalk_ir::OpaqueTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", opaque_ty.opaque_ty_id) - } - - pub fn debug_ty( - &self, - ty: &chalk_ir::Ty, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", ty.data(&Interner)) - } - - pub fn debug_lifetime( - &self, - lifetime: &Lifetime, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", lifetime.data(&Interner)) - } - - pub fn debug_generic_arg( - &self, - parameter: &GenericArg, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", parameter.data(&Interner).inner_debug()) - } - - pub fn debug_goal( - &self, - goal: &Goal, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - let goal_data = goal.data(&Interner); - write!(fmt, "{:?}", goal_data) - } - - pub fn debug_goals( - &self, - goals: &Goals, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", goals.debug(&Interner)) - } - - pub fn debug_program_clause_implication( - &self, - pci: &ProgramClauseImplication, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", pci.debug(&Interner)) - } - - pub fn debug_application_ty( - &self, - application_ty: &chalk_ir::ApplicationTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", application_ty.debug(&Interner)) - } - - pub fn debug_substitution( - &self, - substitution: &chalk_ir::Substitution, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", substitution.debug(&Interner)) - } - - pub fn debug_separator_trait_ref( - &self, - separator_trait_ref: &chalk_ir::SeparatorTraitRef, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - write!(fmt, "{:?}", separator_trait_ref.debug(&Interner)) - } - - pub fn debug_fn_def_id( - &self, - fn_def_id: chalk_ir::FnDefId, - fmt: &mut fmt::Formatter<'_>, - ) -> Result<(), fmt::Error> { - let def: CallableDefId = from_chalk(self.0, fn_def_id); - let name = match def { - CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(), - CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(), - CallableDefId::EnumVariantId(e) => { - let enum_data = self.0.enum_data(e.parent); - enum_data.variants[e.local_id].name.clone() - } - }; - match def { - CallableDefId::FunctionId(_) => write!(fmt, "{{fn {}}}", name), - CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => { - write!(fmt, "{{ctor {}}}", name) - } - } - } - - pub fn debug_const( - &self, - _constant: &chalk_ir::Const, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "const") - } - - pub fn debug_variable_kinds( - &self, - variable_kinds: &chalk_ir::VariableKinds, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "{:?}", variable_kinds.as_slice(&Interner)) - } - pub fn debug_variable_kinds_with_angles( - &self, - variable_kinds: &chalk_ir::VariableKinds, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "{:?}", variable_kinds.inner_debug(&Interner)) - } - pub fn debug_canonical_var_kinds( - &self, - canonical_var_kinds: &chalk_ir::CanonicalVarKinds, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "{:?}", canonical_var_kinds.as_slice(&Interner)) - } - pub fn debug_program_clause( - &self, - clause: &chalk_ir::ProgramClause, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "{:?}", clause.data(&Interner)) - } - pub fn debug_program_clauses( - &self, - clauses: &chalk_ir::ProgramClauses, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "{:?}", clauses.as_slice(&Interner)) - } - pub fn debug_quantified_where_clauses( - &self, - clauses: &chalk_ir::QuantifiedWhereClauses, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(fmt, "{:?}", clauses.as_slice(&Interner)) - } -} - -mod unsafe_tls { - use super::DebugContext; - use crate::db::HirDatabase; - use scoped_tls::scoped_thread_local; - - scoped_thread_local!(static PROGRAM: DebugContext); - - pub fn with_current_program( - op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R, - ) -> R { - if PROGRAM.is_set() { - PROGRAM.with(|prog| op(Some(prog))) - } else { - op(None) - } - } - - pub fn set_current_program(p: &dyn HirDatabase, op: OP) -> R - where - OP: FnOnce() -> R, - { - let ctx = DebugContext(p); - // we're transmuting the lifetime in the DebugContext to static. This is - // fine because we only keep the reference for the lifetime of this - // function, *and* the only way to access the context is through - // `with_current_program`, which hides the lifetime through the `for` - // type. - let static_p: &DebugContext<'static> = - unsafe { std::mem::transmute::<&DebugContext, &DebugContext<'static>>(&ctx) }; - PROGRAM.set(static_p, || op()) - } -} -- cgit v1.2.3