mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 01:38:13 +00:00
Merge #8445
8445: `hir_ty` cleanup r=flodiebold a=flodiebold Move lots of things around within `hir_ty`. Most notably, all the Chalk-related stuff moves from within `traits/` to the top-level, since Chalk isn't purely a "traits thing" anymore. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
972e1f4b8c
14 changed files with 353 additions and 359 deletions
|
@ -1,16 +0,0 @@
|
|||
//! Implementations of the Chalk `Cast` trait for our types.
|
||||
|
||||
use chalk_ir::interner::HasInterner;
|
||||
|
||||
use crate::{CallableSig, ReturnTypeImplTraits};
|
||||
|
||||
macro_rules! has_interner {
|
||||
($t:ty) => {
|
||||
impl HasInterner for $t {
|
||||
type Interner = crate::Interner;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
has_interner!(CallableSig);
|
||||
has_interner!(ReturnTypeImplTraits);
|
|
@ -1,50 +1,47 @@
|
|||
//! Conversion code from/to Chalk.
|
||||
//! The implementation of `RustIrDatabase` for Chalk, which provides information
|
||||
//! about the code that Chalk needs.
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::debug;
|
||||
|
||||
use chalk_ir::{fold::shift::Shift, CanonicalVarKinds};
|
||||
use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds};
|
||||
use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
|
||||
|
||||
use base_db::{salsa::InternKey, CrateId};
|
||||
use base_db::CrateId;
|
||||
use hir_def::{
|
||||
lang_item::{lang_attr, LangItemTarget},
|
||||
AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId,
|
||||
AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId,
|
||||
};
|
||||
use hir_expand::name::name;
|
||||
|
||||
use super::ChalkContext;
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
display::HirDisplay,
|
||||
from_assoc_type_id, make_only_type_binders,
|
||||
from_assoc_type_id, from_chalk_trait_id, make_only_type_binders,
|
||||
mapping::{from_chalk, ToChalk, TypeAliasAsValue},
|
||||
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
|
||||
to_assoc_type_id, to_chalk_trait_id,
|
||||
traits::ChalkContext,
|
||||
utils::generics,
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
|
||||
TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy,
|
||||
ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder,
|
||||
TyExt, TyKind, WhereClause,
|
||||
};
|
||||
use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, TypeAliasAsValue};
|
||||
|
||||
pub use self::interner::Interner;
|
||||
pub(crate) use self::interner::*;
|
||||
pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
|
||||
pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
|
||||
pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>;
|
||||
pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>;
|
||||
pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
|
||||
|
||||
pub(super) mod tls;
|
||||
mod interner;
|
||||
mod mapping;
|
||||
|
||||
pub(crate) trait ToChalk {
|
||||
type Chalk;
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
|
||||
fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
|
||||
}
|
||||
|
||||
pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
|
||||
where
|
||||
T: ToChalk<Chalk = ChalkT>,
|
||||
{
|
||||
T::from_chalk(db, chalk)
|
||||
}
|
||||
pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
|
||||
pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
|
||||
pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
|
||||
pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
|
||||
pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
|
||||
pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
|
||||
pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
|
||||
pub(crate) type Variances = chalk_ir::Variances<Interner>;
|
||||
|
||||
impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
||||
fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
|
||||
|
@ -82,7 +79,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
|||
binders: &CanonicalVarKinds<Interner>,
|
||||
) -> Vec<ImplId> {
|
||||
debug!("impls_for_trait {:?}", trait_id);
|
||||
let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
|
||||
let trait_: hir_def::TraitId = from_chalk_trait_id(trait_id);
|
||||
|
||||
let ty: Ty = parameters[0].assert_ty_ref(&Interner).clone();
|
||||
|
||||
|
@ -164,7 +161,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
|||
Some(LangItemTarget::TraitId(trait_)) => trait_,
|
||||
_ => return None,
|
||||
};
|
||||
Some(trait_.to_chalk(self.db))
|
||||
Some(to_chalk_trait_id(trait_))
|
||||
}
|
||||
|
||||
fn program_clauses_for_env(
|
||||
|
@ -311,7 +308,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
|||
}
|
||||
|
||||
fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
|
||||
let id = from_chalk(self.db, trait_id);
|
||||
let id = from_chalk_trait_id(trait_id);
|
||||
self.db.trait_data(id).name.to_string()
|
||||
}
|
||||
fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String {
|
||||
|
@ -416,7 +413,7 @@ pub(crate) fn trait_datum_query(
|
|||
trait_id: TraitId,
|
||||
) -> Arc<TraitDatum> {
|
||||
debug!("trait_datum {:?}", trait_id);
|
||||
let trait_: hir_def::TraitId = from_chalk(db, trait_id);
|
||||
let trait_ = from_chalk_trait_id(trait_id);
|
||||
let trait_data = db.trait_data(trait_);
|
||||
debug!("trait {:?} = {:?}", trait_id, trait_data.name);
|
||||
let generic_params = generics(db.upcast(), trait_.into());
|
||||
|
@ -679,38 +676,65 @@ pub(crate) fn adt_variance_query(
|
|||
)
|
||||
}
|
||||
|
||||
impl From<FnDefId> for crate::db::InternedCallableDefId {
|
||||
fn from(fn_def_id: FnDefId) -> Self {
|
||||
InternKey::from_intern_id(fn_def_id.0)
|
||||
pub(super) fn convert_where_clauses(
|
||||
db: &dyn HirDatabase,
|
||||
def: GenericDefId,
|
||||
substs: &Substitution,
|
||||
) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
|
||||
let generic_predicates = db.generic_predicates(def);
|
||||
let mut result = Vec::with_capacity(generic_predicates.len());
|
||||
for pred in generic_predicates.iter() {
|
||||
result.push(pred.clone().substitute(&Interner, substs));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedCallableDefId> for FnDefId {
|
||||
fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
|
||||
chalk_ir::FnDefId(callable_def_id.as_intern_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
|
||||
fn from(id: OpaqueTyId) -> Self {
|
||||
InternKey::from_intern_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
|
||||
fn from(id: crate::db::InternedOpaqueTyId) -> Self {
|
||||
chalk_ir::OpaqueTyId(id.as_intern_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
|
||||
fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
|
||||
Self::from_intern_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
|
||||
fn from(id: crate::db::InternedClosureId) -> Self {
|
||||
chalk_ir::ClosureId(id.as_intern_id())
|
||||
pub(super) fn generic_predicate_to_inline_bound(
|
||||
db: &dyn HirDatabase,
|
||||
pred: &QuantifiedWhereClause,
|
||||
self_ty: &Ty,
|
||||
) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
|
||||
// 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.
|
||||
let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE);
|
||||
let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
|
||||
match pred {
|
||||
WhereClause::Implemented(trait_ref) => {
|
||||
if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in {
|
||||
// we can only convert predicates back to type bounds if they
|
||||
// have the expected self type
|
||||
return None;
|
||||
}
|
||||
let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..]
|
||||
.iter()
|
||||
.map(|ty| ty.clone().cast(&Interner))
|
||||
.collect();
|
||||
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
|
||||
Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
|
||||
}
|
||||
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
|
||||
if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in {
|
||||
return None;
|
||||
}
|
||||
let trait_ = projection_ty.trait_(db);
|
||||
let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..]
|
||||
.iter()
|
||||
.map(|ty| ty.clone().cast(&Interner))
|
||||
.collect();
|
||||
let alias_eq_bound = rust_ir::AliasEqBound {
|
||||
value: ty.clone(),
|
||||
trait_bound: rust_ir::TraitBound {
|
||||
trait_id: to_chalk_trait_id(trait_),
|
||||
args_no_self,
|
||||
},
|
||||
associated_ty_id: projection_ty.associated_ty_id,
|
||||
parameters: Vec::new(), // FIXME we don't support generic associated types yet
|
||||
};
|
||||
Some(chalk_ir::Binders::new(
|
||||
binders,
|
||||
rust_ir::InlineBound::AliasEqBound(alias_eq_bound),
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
//! FIXME: write short doc here
|
||||
//! The home of `HirDatabase`, which is the Salsa database containing all the
|
||||
//! type inference-related queries.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -10,9 +11,9 @@ use hir_def::{
|
|||
use la_arena::ArenaMap;
|
||||
|
||||
use crate::{
|
||||
chalk_db,
|
||||
method_resolution::{InherentImpls, TraitImpls},
|
||||
traits::chalk,
|
||||
Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig,
|
||||
Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, Interner, PolyFnSig,
|
||||
QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
|
@ -94,33 +95,38 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
|||
#[salsa::interned]
|
||||
fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
|
||||
|
||||
#[salsa::invoke(chalk::associated_ty_data_query)]
|
||||
fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>;
|
||||
#[salsa::invoke(chalk_db::associated_ty_data_query)]
|
||||
fn associated_ty_data(&self, id: chalk_db::AssocTypeId) -> Arc<chalk_db::AssociatedTyDatum>;
|
||||
|
||||
#[salsa::invoke(chalk::trait_datum_query)]
|
||||
fn trait_datum(&self, krate: CrateId, trait_id: chalk::TraitId) -> Arc<chalk::TraitDatum>;
|
||||
#[salsa::invoke(chalk_db::trait_datum_query)]
|
||||
fn trait_datum(&self, krate: CrateId, trait_id: chalk_db::TraitId)
|
||||
-> Arc<chalk_db::TraitDatum>;
|
||||
|
||||
#[salsa::invoke(chalk::struct_datum_query)]
|
||||
fn struct_datum(&self, krate: CrateId, struct_id: chalk::AdtId) -> Arc<chalk::StructDatum>;
|
||||
#[salsa::invoke(chalk_db::struct_datum_query)]
|
||||
fn struct_datum(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
struct_id: chalk_db::AdtId,
|
||||
) -> Arc<chalk_db::StructDatum>;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::impl_datum_query)]
|
||||
fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
|
||||
#[salsa::invoke(chalk_db::impl_datum_query)]
|
||||
fn impl_datum(&self, krate: CrateId, impl_id: chalk_db::ImplId) -> Arc<chalk_db::ImplDatum>;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::fn_def_datum_query)]
|
||||
fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>;
|
||||
#[salsa::invoke(chalk_db::fn_def_datum_query)]
|
||||
fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk_db::FnDefDatum>;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::fn_def_variance_query)]
|
||||
fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances;
|
||||
#[salsa::invoke(chalk_db::fn_def_variance_query)]
|
||||
fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk_db::Variances;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::adt_variance_query)]
|
||||
fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances;
|
||||
#[salsa::invoke(chalk_db::adt_variance_query)]
|
||||
fn adt_variance(&self, krate: CrateId, adt_id: chalk_db::AdtId) -> chalk_db::Variances;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::associated_ty_value_query)]
|
||||
#[salsa::invoke(chalk_db::associated_ty_value_query)]
|
||||
fn associated_ty_value(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
id: chalk::AssociatedTyValueId,
|
||||
) -> Arc<chalk::AssociatedTyValue>;
|
||||
id: chalk_db::AssociatedTyValueId,
|
||||
) -> Arc<chalk_db::AssociatedTyValue>;
|
||||
|
||||
#[salsa::invoke(crate::traits::trait_solve_query)]
|
||||
fn trait_solve(
|
||||
|
@ -129,12 +135,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
|||
goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
|
||||
) -> Option<crate::Solution>;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
|
||||
#[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)]
|
||||
fn program_clauses_for_chalk_env(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
env: chalk_ir::Environment<chalk::Interner>,
|
||||
) -> chalk_ir::ProgramClauses<chalk::Interner>;
|
||||
env: chalk_ir::Environment<Interner>,
|
||||
) -> chalk_ir::ProgramClauses<Interner>;
|
||||
}
|
||||
|
||||
fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! FIXME: write short doc here
|
||||
//! Type inference-based diagnostics.
|
||||
mod expr;
|
||||
mod match_check;
|
||||
mod unsafe_check;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
//! FIXME: write short doc here
|
||||
//! The `HirDisplay` trait, which serves two purposes: Turning various bits from
|
||||
//! HIR back into source code, and just displaying them for debugging/testing
|
||||
//! purposes.
|
||||
|
||||
use std::{
|
||||
array,
|
||||
|
@ -20,11 +22,11 @@ use hir_expand::name::Name;
|
|||
|
||||
use crate::{
|
||||
const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id,
|
||||
from_placeholder_idx, lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id,
|
||||
traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId,
|
||||
CallableSig, Const, ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime,
|
||||
LifetimeData, LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt,
|
||||
QuantifiedWhereClause, Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause,
|
||||
from_placeholder_idx, lt_from_placeholder_idx, mapping::from_chalk, primitive, subst_prefix,
|
||||
to_assoc_type_id, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, Const,
|
||||
ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData,
|
||||
LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause,
|
||||
Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
pub struct HirFormatter<'a> {
|
||||
|
|
|
@ -17,10 +17,11 @@ use syntax::ast::RangeOp;
|
|||
use crate::{
|
||||
autoderef, dummy_usize_const,
|
||||
lower::lower_to_chalk_mutability,
|
||||
mapping::from_chalk,
|
||||
method_resolution, op,
|
||||
primitive::{self, UintTy},
|
||||
static_lifetime, to_chalk_trait_id,
|
||||
traits::{chalk::from_chalk, FnTrait},
|
||||
traits::FnTrait,
|
||||
utils::{generics, Generics},
|
||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
|
||||
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
//! 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 crate::GenericArg;
|
||||
use crate::{chalk_db, tls, GenericArg};
|
||||
use base_db::salsa::InternId;
|
||||
use chalk_ir::{Goal, GoalData};
|
||||
use hir_def::{
|
||||
|
@ -15,21 +14,6 @@ use std::{fmt, sync::Arc};
|
|||
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
|
||||
pub struct Interner;
|
||||
|
||||
pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
|
||||
pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
|
||||
pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
|
||||
pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
|
||||
pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
|
||||
pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>;
|
||||
pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
|
||||
pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>;
|
||||
pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
|
||||
pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
|
||||
pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
|
||||
pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
|
||||
pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
|
||||
pub(crate) type Variances = chalk_ir::Variances<Interner>;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||
pub struct InternedWrapper<T>(T);
|
||||
|
||||
|
@ -76,15 +60,24 @@ impl chalk_ir::interner::Interner for Interner {
|
|||
type Identifier = TypeAliasId;
|
||||
type FnAbi = ();
|
||||
|
||||
fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
fn debug_adt_id(
|
||||
type_kind_id: chalk_db::AdtId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
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<fmt::Result> {
|
||||
fn debug_trait_id(
|
||||
type_kind_id: chalk_db::TraitId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
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<fmt::Result> {
|
||||
fn debug_assoc_type_id(
|
||||
id: chalk_db::AssocTypeId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
|
||||
}
|
||||
|
||||
|
@ -419,3 +412,12 @@ impl chalk_ir::interner::Interner for Interner {
|
|||
impl chalk_ir::interner::HasInterner for Interner {
|
||||
type Interner = Self;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! has_interner {
|
||||
($t:ty) => {
|
||||
impl HasInterner for $t {
|
||||
type Interner = crate::Interner;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -7,21 +7,23 @@ macro_rules! eprintln {
|
|||
}
|
||||
|
||||
mod autoderef;
|
||||
pub mod primitive;
|
||||
pub mod traits;
|
||||
pub mod method_resolution;
|
||||
mod op;
|
||||
mod lower;
|
||||
pub(crate) mod infer;
|
||||
pub(crate) mod utils;
|
||||
mod chalk_cast;
|
||||
mod chalk_ext;
|
||||
mod builder;
|
||||
mod chalk_db;
|
||||
mod chalk_ext;
|
||||
mod infer;
|
||||
mod interner;
|
||||
mod lower;
|
||||
mod mapping;
|
||||
mod op;
|
||||
mod tls;
|
||||
mod utils;
|
||||
mod walk;
|
||||
|
||||
pub mod display;
|
||||
pub mod db;
|
||||
pub mod diagnostics;
|
||||
pub mod display;
|
||||
pub mod method_resolution;
|
||||
pub mod primitive;
|
||||
pub mod traits;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -30,16 +32,12 @@ mod test_db;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use base_db::salsa;
|
||||
use chalk_ir::{
|
||||
fold::{Fold, Shift},
|
||||
interner::HasInterner,
|
||||
UintTy,
|
||||
};
|
||||
use hir_def::{
|
||||
expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId,
|
||||
TypeParamId,
|
||||
};
|
||||
use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId};
|
||||
|
||||
use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
|
||||
|
||||
|
@ -47,11 +45,17 @@ pub use autoderef::autoderef;
|
|||
pub use builder::TyBuilder;
|
||||
pub use chalk_ext::*;
|
||||
pub use infer::{could_unify, InferenceResult};
|
||||
pub use interner::Interner;
|
||||
pub use lower::{
|
||||
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
|
||||
TyDefId, TyLoweringContext, ValueTyDefId,
|
||||
};
|
||||
pub use traits::{chalk::Interner, TraitEnvironment};
|
||||
pub use mapping::{
|
||||
const_from_placeholder_idx, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
|
||||
from_placeholder_idx, lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
|
||||
to_foreign_def_id, to_placeholder_idx,
|
||||
};
|
||||
pub use traits::TraitEnvironment;
|
||||
pub use walk::TypeWalk;
|
||||
|
||||
pub use chalk_ir::{
|
||||
|
@ -94,6 +98,10 @@ pub type ConstValue = chalk_ir::ConstValue<Interner>;
|
|||
pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
|
||||
|
||||
pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
|
||||
pub type TraitRef = chalk_ir::TraitRef<Interner>;
|
||||
pub type QuantifiedWhereClause = Binders<WhereClause>;
|
||||
pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
|
||||
pub type Canonical<T> = chalk_ir::Canonical<T>;
|
||||
|
||||
pub type FnSig = chalk_ir::FnSig<Interner>;
|
||||
|
||||
|
@ -118,14 +126,14 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
|
|||
generics(db.upcast(), id.parent).param_idx(id)
|
||||
}
|
||||
|
||||
pub fn wrap_empty_binders<T>(value: T) -> Binders<T>
|
||||
pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
|
||||
where
|
||||
T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>,
|
||||
{
|
||||
Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE))
|
||||
}
|
||||
|
||||
pub fn make_only_type_binders<T: HasInterner<Interner = Interner>>(
|
||||
pub(crate) fn make_only_type_binders<T: HasInterner<Interner = Interner>>(
|
||||
num_vars: usize,
|
||||
value: T,
|
||||
) -> Binders<T> {
|
||||
|
@ -153,14 +161,6 @@ pub fn make_canonical<T: HasInterner<Interner = Interner>>(
|
|||
Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
|
||||
}
|
||||
|
||||
pub type TraitRef = chalk_ir::TraitRef<Interner>;
|
||||
|
||||
pub type QuantifiedWhereClause = Binders<WhereClause>;
|
||||
|
||||
pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
|
||||
|
||||
pub type Canonical<T> = chalk_ir::Canonical<T>;
|
||||
|
||||
/// A function signature as seen by type inference: Several parameter types and
|
||||
/// one return type.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -169,6 +169,8 @@ pub struct CallableSig {
|
|||
is_varargs: bool,
|
||||
}
|
||||
|
||||
has_interner!(CallableSig);
|
||||
|
||||
/// A polymorphic function signature.
|
||||
pub type PolyFnSig = Binders<CallableSig>;
|
||||
|
||||
|
@ -232,61 +234,13 @@ pub struct ReturnTypeImplTraits {
|
|||
pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
|
||||
}
|
||||
|
||||
has_interner!(ReturnTypeImplTraits);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub(crate) struct ReturnTypeImplTrait {
|
||||
pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
|
||||
}
|
||||
|
||||
pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
|
||||
chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
|
||||
}
|
||||
|
||||
pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
|
||||
salsa::InternKey::from_intern_id(id.0)
|
||||
}
|
||||
|
||||
pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
|
||||
chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
|
||||
}
|
||||
|
||||
pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
|
||||
salsa::InternKey::from_intern_id(id.0)
|
||||
}
|
||||
|
||||
pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
|
||||
db.lookup_intern_type_param_id(interned_id)
|
||||
}
|
||||
|
||||
pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex {
|
||||
let interned_id = db.intern_type_param_id(id);
|
||||
PlaceholderIndex {
|
||||
ui: chalk_ir::UniverseIndex::ROOT,
|
||||
idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
|
||||
db.lookup_intern_lifetime_param_id(interned_id)
|
||||
}
|
||||
|
||||
pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
|
||||
db.lookup_intern_const_param_id(interned_id)
|
||||
}
|
||||
|
||||
pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
|
||||
chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
|
||||
}
|
||||
|
||||
pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
|
||||
salsa::InternKey::from_intern_id(id.0)
|
||||
}
|
||||
|
||||
pub fn static_lifetime() -> Lifetime {
|
||||
LifetimeData::Static.intern(&Interner)
|
||||
}
|
||||
|
|
|
@ -27,13 +27,14 @@ use stdx::impl_from;
|
|||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
|
||||
traits::chalk::{Interner, ToChalk},
|
||||
dummy_usize_const,
|
||||
mapping::ToChalk,
|
||||
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
|
||||
utils::{
|
||||
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
|
||||
},
|
||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
|
||||
FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
|
||||
FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
|
||||
QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
|
||||
TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
|
||||
};
|
||||
|
|
154
crates/hir_ty/src/mapping.rs
Normal file
154
crates/hir_ty/src/mapping.rs
Normal file
|
@ -0,0 +1,154 @@
|
|||
//! 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_solve::rust_ir;
|
||||
|
||||
use base_db::salsa::{self, InternKey};
|
||||
use hir_def::{ConstParamId, LifetimeParamId, TraitId, TypeAliasId, TypeParamId};
|
||||
|
||||
use crate::{
|
||||
chalk_db, db::HirDatabase, AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId,
|
||||
Interner, OpaqueTyId, PlaceholderIndex,
|
||||
};
|
||||
|
||||
pub(crate) trait ToChalk {
|
||||
type Chalk;
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
|
||||
fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
|
||||
}
|
||||
|
||||
pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
|
||||
where
|
||||
T: ToChalk<Chalk = ChalkT>,
|
||||
{
|
||||
T::from_chalk(db, chalk)
|
||||
}
|
||||
|
||||
impl ToChalk for hir_def::ImplId {
|
||||
type Chalk = chalk_db::ImplId;
|
||||
|
||||
fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::ImplId {
|
||||
chalk_ir::ImplId(self.as_intern_id())
|
||||
}
|
||||
|
||||
fn from_chalk(_db: &dyn HirDatabase, impl_id: chalk_db::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())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
|
||||
|
||||
impl ToChalk for TypeAliasAsValue {
|
||||
type Chalk = chalk_db::AssociatedTyValueId;
|
||||
|
||||
fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::AssociatedTyValueId {
|
||||
rust_ir::AssociatedTyValueId(self.0.as_intern_id())
|
||||
}
|
||||
|
||||
fn from_chalk(
|
||||
_db: &dyn HirDatabase,
|
||||
assoc_ty_value_id: chalk_db::AssociatedTyValueId,
|
||||
) -> TypeAliasAsValue {
|
||||
TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FnDefId> for crate::db::InternedCallableDefId {
|
||||
fn from(fn_def_id: FnDefId) -> Self {
|
||||
InternKey::from_intern_id(fn_def_id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedCallableDefId> for FnDefId {
|
||||
fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
|
||||
chalk_ir::FnDefId(callable_def_id.as_intern_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
|
||||
fn from(id: OpaqueTyId) -> Self {
|
||||
InternKey::from_intern_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
|
||||
fn from(id: crate::db::InternedOpaqueTyId) -> Self {
|
||||
chalk_ir::OpaqueTyId(id.as_intern_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
|
||||
fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
|
||||
Self::from_intern_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
|
||||
fn from(id: crate::db::InternedClosureId) -> Self {
|
||||
chalk_ir::ClosureId(id.as_intern_id())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
|
||||
chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
|
||||
}
|
||||
|
||||
pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
|
||||
salsa::InternKey::from_intern_id(id.0)
|
||||
}
|
||||
|
||||
pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
|
||||
chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
|
||||
}
|
||||
|
||||
pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
|
||||
salsa::InternKey::from_intern_id(id.0)
|
||||
}
|
||||
|
||||
pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
|
||||
db.lookup_intern_type_param_id(interned_id)
|
||||
}
|
||||
|
||||
pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex {
|
||||
let interned_id = db.intern_type_param_id(id);
|
||||
PlaceholderIndex {
|
||||
ui: chalk_ir::UniverseIndex::ROOT,
|
||||
idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
|
||||
db.lookup_intern_lifetime_param_id(interned_id)
|
||||
}
|
||||
|
||||
pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
|
||||
db.lookup_intern_const_param_id(interned_id)
|
||||
}
|
||||
|
||||
pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
|
||||
chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
|
||||
}
|
||||
|
||||
pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
|
||||
salsa::InternKey::from_intern_id(id.0)
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
//! Defines primitive types, which have a couple of peculiarities:
|
||||
//!
|
||||
//! * during type inference, they can be uncertain (ie, `let x = 92;`)
|
||||
//! * they don't belong to any particular crate.
|
||||
//! A few helper functions for dealing with primitives.
|
||||
|
||||
pub use chalk_ir::{FloatTy, IntTy, UintTy};
|
||||
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
|
||||
|
|
|
@ -4,8 +4,10 @@ use std::fmt;
|
|||
use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::{from_chalk, Interner};
|
||||
use crate::{db::HirDatabase, from_assoc_type_id, CallableDefId};
|
||||
use crate::{
|
||||
chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk,
|
||||
CallableDefId, Interner,
|
||||
};
|
||||
use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
|
||||
|
||||
pub(crate) use unsafe_tls::{set_current_program, with_current_program};
|
||||
|
@ -15,7 +17,7 @@ pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase);
|
|||
impl DebugContext<'_> {
|
||||
pub(crate) fn debug_struct_id(
|
||||
&self,
|
||||
id: super::AdtId,
|
||||
id: chalk_db::AdtId,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let name = match id.0 {
|
||||
|
@ -28,17 +30,17 @@ impl DebugContext<'_> {
|
|||
|
||||
pub(crate) fn debug_trait_id(
|
||||
&self,
|
||||
id: super::TraitId,
|
||||
id: chalk_db::TraitId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let trait_: hir_def::TraitId = from_chalk(self.0, id);
|
||||
let trait_: hir_def::TraitId = from_chalk_trait_id(id);
|
||||
let trait_data = self.0.trait_data(trait_);
|
||||
write!(fmt, "{}", trait_data.name)
|
||||
}
|
||||
|
||||
pub(crate) fn debug_assoc_type_id(
|
||||
&self,
|
||||
id: super::AssocTypeId,
|
||||
id: chalk_db::AssocTypeId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let type_alias: TypeAliasId = from_assoc_type_id(id);
|
|
@ -1,28 +1,26 @@
|
|||
//! Trait solving using Chalk.
|
||||
|
||||
use std::env::var;
|
||||
|
||||
use base_db::CrateId;
|
||||
use chalk_ir::cast::Cast;
|
||||
use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver};
|
||||
|
||||
use base_db::CrateId;
|
||||
use hir_def::{lang_item::LangItemTarget, TraitId};
|
||||
use stdx::panic_context;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment,
|
||||
Solution, TraitRefExt, Ty, TyKind, WhereClause,
|
||||
Interner, Solution, TraitRefExt, Ty, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
use self::chalk::Interner;
|
||||
|
||||
pub(crate) mod chalk;
|
||||
|
||||
/// This controls how much 'time' we give the Chalk solver before giving up.
|
||||
const CHALK_SOLVER_FUEL: i32 = 100;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct ChalkContext<'a> {
|
||||
db: &'a dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
pub(crate) struct ChalkContext<'a> {
|
||||
pub(crate) db: &'a dyn HirDatabase,
|
||||
pub(crate) krate: CrateId,
|
||||
}
|
||||
|
||||
fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
|
||||
|
@ -148,7 +146,7 @@ fn solve(
|
|||
// don't set the TLS for Chalk unless Chalk debugging is active, to make
|
||||
// extra sure we only use it for debugging
|
||||
let solution =
|
||||
if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() };
|
||||
if is_chalk_debug() { crate::tls::set_current_program(db, solve) } else { solve() };
|
||||
|
||||
solution
|
||||
}
|
||||
|
|
|
@ -1,131 +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;
|
||||
use chalk_solve::rust_ir;
|
||||
|
||||
use base_db::salsa::InternKey;
|
||||
use hir_def::{GenericDefId, TypeAliasId};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, AliasTy, CallableDefId, ProjectionTyExt, QuantifiedWhereClause, Substitution,
|
||||
Ty, WhereClause,
|
||||
};
|
||||
|
||||
use super::interner::*;
|
||||
use super::*;
|
||||
|
||||
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 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())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TypeAliasAsValue(pub(crate) 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))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn convert_where_clauses(
|
||||
db: &dyn HirDatabase,
|
||||
def: GenericDefId,
|
||||
substs: &Substitution,
|
||||
) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
|
||||
let generic_predicates = db.generic_predicates(def);
|
||||
let mut result = Vec::with_capacity(generic_predicates.len());
|
||||
for pred in generic_predicates.iter() {
|
||||
result.push(pred.clone().substitute(&Interner, substs));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub(super) fn generic_predicate_to_inline_bound(
|
||||
db: &dyn HirDatabase,
|
||||
pred: &QuantifiedWhereClause,
|
||||
self_ty: &Ty,
|
||||
) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
|
||||
// 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.
|
||||
let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE);
|
||||
let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
|
||||
match pred {
|
||||
WhereClause::Implemented(trait_ref) => {
|
||||
if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in {
|
||||
// we can only convert predicates back to type bounds if they
|
||||
// have the expected self type
|
||||
return None;
|
||||
}
|
||||
let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..]
|
||||
.iter()
|
||||
.map(|ty| ty.clone().cast(&Interner))
|
||||
.collect();
|
||||
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
|
||||
Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
|
||||
}
|
||||
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
|
||||
if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in {
|
||||
return None;
|
||||
}
|
||||
let trait_ = projection_ty.trait_(db);
|
||||
let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..]
|
||||
.iter()
|
||||
.map(|ty| ty.clone().cast(&Interner))
|
||||
.collect();
|
||||
let alias_eq_bound = rust_ir::AliasEqBound {
|
||||
value: ty.clone(),
|
||||
trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
|
||||
associated_ty_id: projection_ty.associated_ty_id,
|
||||
parameters: Vec::new(), // FIXME we don't support generic associated types yet
|
||||
};
|
||||
Some(chalk_ir::Binders::new(
|
||||
binders,
|
||||
rust_ir::InlineBound::AliasEqBound(alias_eq_bound),
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue