use crate::{
method_resolution::{InherentImpls, TraitImpls},
traits::chalk,
- Binders, CallableDefId, FnDefId, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig,
+ Binders, CallableDefId, FnDefId, GenericPredicate, ImplTraitId, InferenceResult, PolyFnSig,
ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
};
use hir_expand::name::Name;
#[salsa::interned]
fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId;
#[salsa::interned]
- fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId;
+ fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
#[salsa::interned]
fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
use crate::{
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
- CallableSig, GenericPredicate, Interner, Lifetime, Obligation, OpaqueTy, OpaqueTyId,
+ CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind,
};
)?;
}
+ // FIXME: all this just to decide whether to use parentheses...
let datas;
let predicates = match t.interned(&Interner) {
TyKind::Dyn(predicates) if predicates.len() > 1 => {
Cow::Borrowed(predicates.as_ref())
}
- &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
- opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx),
- ref parameters,
- })) => {
- datas =
- f.db.return_type_impl_traits(func).expect("impl trait id without data");
- let data = (*datas)
- .as_ref()
- .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
- let bounds = data.subst(parameters);
- Cow::Owned(bounds.value)
+ &TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, ref parameters })) => {
+ let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into());
+ if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
+ datas =
+ f.db.return_type_impl_traits(func)
+ .expect("impl trait id without data");
+ let data = (*datas)
+ .as_ref()
+ .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
+ let bounds = data.subst(parameters);
+ Cow::Owned(bounds.value)
+ } else {
+ Cow::Borrowed(&[][..])
+ }
}
_ => Cow::Borrowed(&[][..]),
};
write!(f, "{}", type_alias.name)?;
}
TyKind::OpaqueType(opaque_ty_id, parameters) => {
- match opaque_ty_id {
- &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
+ let impl_trait_id = f.db.lookup_intern_impl_trait_id((*opaque_ty_id).into());
+ match impl_trait_id {
+ ImplTraitId::ReturnTypeImplTrait(func, idx) => {
let datas =
f.db.return_type_impl_traits(func).expect("impl trait id without data");
let data = (*datas)
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
}
- OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
+ ImplTraitId::AsyncBlockTypeImplTrait(..) => {
write!(f, "impl Future<Output = ")?;
parameters[0].hir_fmt(f)?;
write!(f, ">")?;
}
TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
- match opaque_ty.opaque_ty_id {
- OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
+ let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into());
+ match impl_trait_id {
+ ImplTraitId::ReturnTypeImplTrait(func, idx) => {
let datas =
f.db.return_type_impl_traits(func).expect("impl trait id without data");
let data = (*datas)
let bounds = data.subst(&opaque_ty.parameters);
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
}
- OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
+ ImplTraitId::AsyncBlockTypeImplTrait(..) => {
write!(f, "{{async block}}")?;
}
};
to_assoc_type_id,
traits::{chalk::from_chalk, FnTrait, InEnvironment},
utils::{generics, variant_data, Generics},
- AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, OpaqueTyId, Rawness,
- Scalar, Substs, TraitRef, Ty, TyKind,
+ AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs,
+ TraitRef, Ty, TyKind,
};
use super::{
// Use the first type parameter as the output type of future.
// existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
let inner_ty = self.infer_expr(*body, &Expectation::none());
- let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
+ let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
+ let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner)
}
Expr::Loop { body, label } => {
pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
pub type FnDefId = chalk_ir::FnDefId<Interner>;
pub type ClosureId = chalk_ir::ClosureId<Interner>;
+pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
match self.interned(&Interner) {
TyKind::OpaqueType(opaque_ty_id, ..) => {
- match opaque_ty_id {
- OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
+ match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
+ ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
let krate = def.module(db.upcast()).krate();
if let Some(future_trait) = db
.lang_item(krate, "future_trait".into())
None
}
}
- OpaqueTyId::ReturnTypeImplTrait(..) => None,
+ ImplTraitId::ReturnTypeImplTrait(..) => None,
}
}
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
- let predicates = match opaque_ty.opaque_ty_id {
- OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
+ let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
+ {
+ ImplTraitId::ReturnTypeImplTrait(func, idx) => {
db.return_type_impl_traits(func).map(|it| {
let data = (*it)
.as_ref()
})
}
// It always has an parameter for Future::Output type.
- OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(),
+ ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
};
predicates.map(|it| it.value)
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
-pub enum OpaqueTyId {
+pub enum ImplTraitId {
ReturnTypeImplTrait(hir_def::FunctionId, u16),
AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
}
make_mut_slice, variant_data,
},
AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
- OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
+ ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
};
Some(GenericDefId::FunctionId(f)) => f,
_ => panic!("opaque impl trait lowering in non-function"),
};
- let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx);
+ let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
+ let opaque_ty_id = ctx.db.intern_impl_trait_id(impl_trait_id).into();
let generics = generics(ctx.db.upcast(), func.into());
let parameters = Substs::bound_vars(&generics, ctx.in_binders);
- TyKind::Alias(AliasTy::Opaque(OpaqueTy {
- opaque_ty_id: impl_trait_id,
- parameters,
- }))
- .intern(&Interner)
+ TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, parameters }))
+ .intern(&Interner)
}
ImplTraitLoweringMode::Param => {
let idx = ctx.impl_trait_counter.get();
}
fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
- let interned_id = crate::db::InternedOpaqueTyId::from(id);
- let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
+ let full_id = self.db.lookup_intern_impl_trait_id(id.into());
let bound = match full_id {
- crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
+ crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
let datas = self
.db
.return_type_impl_traits(func)
let num_vars = datas.num_binders;
make_binders(bound, num_vars)
}
- crate::OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
+ crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
if let Some((future_trait, future_output)) = self
.db
.lang_item(self.krate, "future_trait".into())
primitive::UintTy,
traits::{Canonical, Obligation},
AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy,
- OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty,
+ ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty,
};
use super::interner::*;
chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
}
- TyKind::OpaqueType(impl_trait_id, substs) => {
- let id = impl_trait_id.to_chalk(db);
+ TyKind::OpaqueType(id, substs) => {
let substitution = substs.to_chalk(db);
chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
}
chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
}
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
- let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
+ let opaque_ty_id = opaque_ty.opaque_ty_id;
let substitution = opaque_ty.parameters.to_chalk(db);
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
opaque_ty_id,
TyKind::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters }))
}
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
- let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
+ let opaque_ty_id = opaque_ty.opaque_ty_id;
let parameters = from_chalk(db, opaque_ty.substitution);
- TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }))
+ TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, parameters }))
}
chalk_ir::TyKind::Function(chalk_ir::FnPointer {
num_binders,
}
chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
- TyKind::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst))
+ TyKind::OpaqueType(opaque_type_id, from_chalk(db, subst))
}
chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar),
}
}
-impl ToChalk for OpaqueTyId {
- type Chalk = chalk_ir::OpaqueTyId<Interner>;
-
- fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> {
- db.intern_impl_trait_id(self).into()
- }
-
- fn from_chalk(
- db: &dyn HirDatabase,
- opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
- ) -> OpaqueTyId {
- db.lookup_intern_impl_trait_id(opaque_ty_id.into())
- }
-}
-
impl ToChalk for hir_def::ImplId {
type Chalk = ImplId;