Use chalk_ir::AssocTypeId

This commit is contained in:
Florian Diebold 2021-03-13 17:36:07 +01:00
parent dfafcd926a
commit 19664e276a
10 changed files with 87 additions and 76 deletions

View File

@ -51,7 +51,7 @@
use hir_ty::{
autoderef,
display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
method_resolution,
method_resolution, to_assoc_type_id,
traits::{FnTrait, Solution, SolutionVariables},
AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs,
@ -1683,7 +1683,10 @@ pub fn normalize_trait_assoc_type(
.fill(args.iter().map(|t| t.ty.value.clone()))
.build();
let predicate = ProjectionPredicate {
projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
projection_ty: ProjectionTy {
associated_ty: to_assoc_type_id(alias.id),
parameters: subst,
},
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
};
let goal = Canonical {

View File

@ -12,6 +12,7 @@
use crate::{
db::HirDatabase,
to_assoc_type_id,
traits::{InEnvironment, Solution},
utils::generics,
BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind,
@ -83,7 +84,7 @@ fn deref_by_trait(
let projection = super::traits::ProjectionPredicate {
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
.intern(&Interner),
projection_ty: super::ProjectionTy { associated_ty: target, parameters },
projection_ty: super::ProjectionTy { associated_ty: to_assoc_type_id(target), parameters },
};
let obligation = super::Obligation::Projection(projection);

View File

@ -11,9 +11,9 @@
use hir_expand::name::Name;
use crate::{
db::HirDatabase, from_foreign_def_id, primitive, utils::generics, AdtId, AliasTy,
CallableDefId, CallableSig, GenericPredicate, Interner, Lifetime, Obligation, OpaqueTy,
OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind,
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, primitive, to_assoc_type_id,
utils::generics, AdtId, AliasTy, CallableDefId, CallableSig, GenericPredicate, Interner,
Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind,
};
pub struct HirFormatter<'a> {
@ -256,7 +256,7 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
f.write_joined(&self.parameters[1..], ", ")?;
write!(f, ">")?;
}
write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty)).name)?;
Ok(())
}
}
@ -467,13 +467,14 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
}
}
}
TyKind::AssociatedType(type_alias, parameters) => {
TyKind::AssociatedType(assoc_type_id, parameters) => {
let type_alias = from_assoc_type_id(*assoc_type_id);
let trait_ = match type_alias.lookup(f.db.upcast()).container {
AssocContainerId::TraitId(it) => it,
_ => panic!("not an associated type"),
};
let trait_ = f.db.trait_data(trait_);
let type_alias_data = f.db.type_alias_data(*type_alias);
let type_alias_data = f.db.type_alias_data(type_alias);
// Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
if f.display_target.is_test() {
@ -484,8 +485,10 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
write!(f, ">")?;
}
} else {
let projection_ty =
ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() };
let projection_ty = ProjectionTy {
associated_ty: to_assoc_type_id(type_alias),
parameters: parameters.clone(),
};
projection_ty.hir_fmt(f)?;
}
@ -697,7 +700,9 @@ fn write_bounds_like_dyn_trait(
write!(f, "<")?;
angle_open = true;
}
let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty);
let type_alias = f.db.type_alias_data(from_assoc_type_id(
projection_pred.projection_ty.associated_ty,
));
write!(f, "{} = ", type_alias.name)?;
projection_pred.ty.hir_fmt(f)?;
}
@ -768,7 +773,10 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
write!(
f,
">::{} = ",
f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
f.db.type_alias_data(from_assoc_type_id(
projection_pred.projection_ty.associated_ty
))
.name,
)?;
projection_pred.ty.hir_fmt(f)?;
}

View File

@ -42,7 +42,7 @@
};
use crate::{
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
AliasTy, Interner, TyKind,
to_assoc_type_id, AliasTy, Interner, TyKind,
};
pub(crate) use unify::unify;
@ -382,7 +382,10 @@ fn resolve_associated_type_with_params(
let trait_ref = TraitRef { trait_, substs: substs.clone() };
let projection = ProjectionPredicate {
ty: ty.clone(),
projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs },
projection_ty: ProjectionTy {
associated_ty: to_assoc_type_id(res_assoc_ty),
parameters: substs,
},
};
self.obligations.push(Obligation::Trait(trait_ref));
self.obligations.push(Obligation::Projection(projection));

View File

@ -18,6 +18,7 @@
lower::lower_to_chalk_mutability,
method_resolution, op,
primitive::{self, UintTy},
to_assoc_type_id,
traits::{FnTrait, InEnvironment},
utils::{generics, variant_data, Generics},
AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, OpaqueTyId, Rawness,
@ -97,8 +98,10 @@ fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Ve
});
if self.db.trait_solve(krate, goal.value).is_some() {
self.obligations.push(implements_fn_trait);
let output_proj_ty =
crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs };
let output_proj_ty = crate::ProjectionTy {
associated_ty: to_assoc_type_id(output_assoc_type),
parameters: substs,
};
let return_ty = self.normalize_projection_ty(output_proj_ty);
Some((arg_tys, return_ty))
} else {

View File

@ -52,6 +52,7 @@ macro_rules! eprintln {
pub use crate::traits::chalk::Interner;
pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum Lifetime {
@ -70,7 +71,7 @@ pub struct OpaqueTy {
/// trait and all its parameters are fully known.
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct ProjectionTy {
pub associated_ty: TypeAliasId,
pub associated_ty: AssocTypeId,
pub parameters: Substs,
}
@ -80,7 +81,7 @@ pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
}
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
match self.associated_ty.lookup(db.upcast()).container {
match from_assoc_type_id(self.associated_ty).lookup(db.upcast()).container {
AssocContainerId::TraitId(it) => it,
_ => panic!("projection ty without parent trait"),
}
@ -141,7 +142,7 @@ pub enum TyKind {
/// when we have tried to normalize a projection like `T::Item` but
/// couldn't find a better representation. In that case, we generate
/// an **application type** like `(Iterator::Item)<T>`.
AssociatedType(TypeAliasId, Substs),
AssociatedType(AssocTypeId, Substs),
/// a scalar type like `bool` or `u32`
Scalar(Scalar),
@ -706,7 +707,7 @@ pub fn as_generic_def(&self) -> Option<GenericDefId> {
match *self.interned(&Interner) {
TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
TyKind::FnDef(callable, ..) => Some(callable.into()),
TyKind::AssociatedType(type_alias, ..) => Some(type_alias.into()),
TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
_ => None,
}
@ -920,14 +921,15 @@ pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredi
pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
match self.interned(&Interner) {
TyKind::AssociatedType(type_alias_id, ..) => {
match type_alias_id.lookup(db.upcast()).container {
TyKind::AssociatedType(id, ..) => {
match from_assoc_type_id(*id).lookup(db.upcast()).container {
AssocContainerId::TraitId(trait_id) => Some(trait_id),
_ => None,
}
}
TyKind::Alias(AliasTy::Projection(projection_ty)) => {
match projection_ty.associated_ty.lookup(db.upcast()).container {
match from_assoc_type_id(projection_ty.associated_ty).lookup(db.upcast()).container
{
AssocContainerId::TraitId(trait_id) => Some(trait_id),
_ => None,
}
@ -1121,10 +1123,18 @@ pub(crate) struct ReturnTypeImplTrait {
pub(crate) bounds: Binders<Vec<GenericPredicate>>,
}
pub(crate) fn to_foreign_def_id(id: TypeAliasId) -> chalk_ir::ForeignDefId<Interner> {
pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
}
pub(crate) fn from_foreign_def_id(id: chalk_ir::ForeignDefId<Interner>) -> TypeAliasId {
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)
}

View File

@ -27,6 +27,7 @@
use crate::{
db::HirDatabase,
to_assoc_type_id,
traits::chalk::{Interner, ToChalk},
utils::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
@ -358,7 +359,7 @@ pub(crate) fn from_partly_resolved_hir_path(
Some((super_trait_ref, associated_ty)) => {
// FIXME handle type parameters on the segment
TyKind::Alias(AliasTy::Projection(ProjectionTy {
associated_ty,
associated_ty: to_assoc_type_id(associated_ty),
parameters: super_trait_ref.substs,
}))
.intern(&Interner)
@ -487,7 +488,7 @@ fn select_associated_type(
// FIXME handle type parameters on the segment
return Some(
TyKind::Alias(AliasTy::Projection(ProjectionTy {
associated_ty,
associated_ty: to_assoc_type_id(associated_ty),
parameters: substs,
}))
.intern(&Interner),
@ -753,7 +754,10 @@ fn assoc_type_bindings_from_type_bound<'a>(
None => return SmallVec::<[GenericPredicate; 1]>::new(),
Some(t) => t,
};
let projection_ty = ProjectionTy { associated_ty, parameters: super_trait_ref.substs };
let projection_ty = ProjectionTy {
associated_ty: to_assoc_type_id(associated_ty),
parameters: super_trait_ref.substs,
};
let mut preds = SmallVec::with_capacity(
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
);

View File

@ -17,14 +17,15 @@
use crate::{
db::HirDatabase,
display::HirDisplay,
from_assoc_type_id,
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
to_assoc_type_id,
utils::generics,
BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate,
ProjectionTy, Substs, TraitRef, Ty, TyKind,
};
use mapping::{
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType,
TypeAliasAsValue,
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
};
pub use self::interner::Interner;
@ -234,7 +235,7 @@ fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatu
ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
.intern(&Interner),
projection_ty: ProjectionTy {
associated_ty: future_output,
associated_ty: to_assoc_type_id(future_output),
// Self type as the first parameter.
parameters: Substs::single(
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
@ -383,7 +384,7 @@ pub(crate) fn associated_ty_data_query(
id: AssocTypeId,
) -> Arc<AssociatedTyDatum> {
debug!("associated_ty_data {:?}", id);
let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(db, id).0;
let type_alias: TypeAliasId = from_assoc_type_id(id);
let trait_ = match type_alias.lookup(db.upcast()).container {
AssocContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
@ -438,10 +439,8 @@ pub(crate) fn trait_datum_query(
fundamental: false,
};
let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
let associated_ty_ids = trait_data
.associated_types()
.map(|type_alias| TypeAliasAsAssocType(type_alias).to_chalk(db))
.collect();
let associated_ty_ids =
trait_data.associated_types().map(|type_alias| to_assoc_type_id(type_alias)).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));
@ -623,7 +622,7 @@ fn type_alias_associated_ty_value(
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: TypeAliasAsAssocType(assoc_ty).to_chalk(db),
associated_ty_id: to_assoc_type_id(assoc_ty),
value: make_binders(value_bound, ty.num_binders),
};
Arc::new(value)

View File

@ -14,6 +14,7 @@
use crate::{
db::HirDatabase,
from_assoc_type_id,
primitive::UintTy,
traits::{Canonical, Obligation},
AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy,
@ -38,9 +39,7 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
})
.intern(&Interner)
}
TyKind::AssociatedType(type_alias, substs) => {
let assoc_type = TypeAliasAsAssocType(type_alias);
let assoc_type_id = assoc_type.to_chalk(db);
TyKind::AssociatedType(assoc_type_id, substs) => {
let substitution = substs.to_chalk(db);
chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
}
@ -85,7 +84,7 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner)
}
TyKind::Alias(AliasTy::Projection(proj_ty)) => {
let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db);
let associated_ty_id = proj_ty.associated_ty;
let substitution = proj_ty.parameters.to_chalk(db);
chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
associated_ty_id,
@ -139,8 +138,7 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
TyKind::Placeholder(db.lookup_intern_type_param_id(interned_id))
}
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
let associated_ty =
from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
let associated_ty = proj.associated_ty_id;
let parameters = from_chalk(db, proj.substitution);
TyKind::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters }))
}
@ -180,10 +178,9 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
}
chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)),
chalk_ir::TyKind::AssociatedType(type_id, subst) => TyKind::AssociatedType(
from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0,
from_chalk(db, subst),
),
chalk_ir::TyKind::AssociatedType(type_id, subst) => {
TyKind::AssociatedType(type_id, from_chalk(db, subst))
}
chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
TyKind::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst))
@ -332,20 +329,6 @@ fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
}
}
pub(crate) struct TypeAliasAsAssocType(pub(crate) TypeAliasId);
impl ToChalk for TypeAliasAsAssocType {
type Chalk = AssocTypeId;
fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId {
chalk_ir::AssocTypeId(self.0.as_intern_id())
}
fn from_chalk(_db: &dyn HirDatabase, assoc_type_id: AssocTypeId) -> TypeAliasAsAssocType {
TypeAliasAsAssocType(InternKey::from_intern_id(assoc_type_id.0))
}
}
pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
impl ToChalk for TypeAliasAsValue {
@ -427,7 +410,7 @@ impl ToChalk for ProjectionTy {
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
chalk_ir::ProjectionTy {
associated_ty_id: TypeAliasAsAssocType(self.associated_ty).to_chalk(db),
associated_ty_id: self.associated_ty,
substitution: self.parameters.to_chalk(db),
}
}
@ -437,11 +420,7 @@ fn from_chalk(
projection_ty: chalk_ir::ProjectionTy<Interner>,
) -> ProjectionTy {
ProjectionTy {
associated_ty: from_chalk::<TypeAliasAsAssocType, _>(
db,
projection_ty.associated_ty_id,
)
.0,
associated_ty: projection_ty.associated_ty_id,
parameters: from_chalk(db, projection_ty.substitution),
}
}
@ -595,7 +574,10 @@ pub(super) fn generic_predicate_to_inline_bound(
if &proj.projection_ty.parameters[0] != self_ty {
return None;
}
let trait_ = match proj.projection_ty.associated_ty.lookup(db.upcast()).container {
let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty)
.lookup(db.upcast())
.container
{
AssocContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
};
@ -606,8 +588,7 @@ pub(super) fn generic_predicate_to_inline_bound(
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: TypeAliasAsAssocType(proj.projection_ty.associated_ty)
.to_chalk(db),
associated_ty_id: proj.projection_ty.associated_ty,
parameters: Vec::new(), // FIXME we don't support generic associated types yet
};
Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound))

View File

@ -4,8 +4,8 @@
use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
use itertools::Itertools;
use super::{from_chalk, Interner, TypeAliasAsAssocType};
use crate::{db::HirDatabase, CallableDefId};
use super::{from_chalk, Interner};
use crate::{db::HirDatabase, from_assoc_type_id, CallableDefId};
use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
pub(crate) use unsafe_tls::{set_current_program, with_current_program};
@ -41,7 +41,7 @@ pub(crate) fn debug_assoc_type_id(
id: super::AssocTypeId,
fmt: &mut fmt::Formatter<'_>,
) -> Result<(), fmt::Error> {
let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(self.0, id).0;
let type_alias: TypeAliasId = from_assoc_type_id(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,
@ -75,8 +75,7 @@ pub(crate) fn debug_projection_ty(
projection_ty: &chalk_ir::ProjectionTy<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Result<(), fmt::Error> {
let type_alias: TypeAliasId =
from_chalk::<TypeAliasAsAssocType, _>(self.0, projection_ty.associated_ty_id).0;
let type_alias = from_assoc_type_id(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,