primitive::UintTy,
to_assoc_type_id,
traits::{FnTrait, Solution, SolutionVariables},
- AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
- InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution,
- Ty, TyDefId, TyKind, TyVariableKind,
+ AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
+ GenericPredicate, InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty,
+ TyDefId, TyKind, TyVariableKind,
};
use itertools::Itertools;
use rustc_hash::FxHashSet;
.push(self.ty.value.clone())
.fill(args.iter().map(|t| t.ty.value.clone()))
.build();
- let predicate = ProjectionPredicate {
- projection_ty: ProjectionTy {
- associated_ty_id: to_assoc_type_id(alias.id),
- substitution: subst,
- },
- ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
- };
let goal = Canonical {
value: InEnvironment::new(
self.ty.environment.clone(),
- Obligation::Projection(predicate),
+ Obligation::AliasEq(AliasEq {
+ alias: AliasTy::Projection(ProjectionTy {
+ associated_ty_id: to_assoc_type_id(alias.id),
+ substitution: subst,
+ }),
+ ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
+ .intern(&Interner),
+ }),
),
kinds: Arc::new([TyVariableKind::General]),
};
to_assoc_type_id, to_chalk_trait_id,
traits::{InEnvironment, Solution},
utils::generics,
- BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
+ AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy,
+ Substitution, TraitRef, Ty, TyKind,
};
const AUTODEREF_RECURSION_LIMIT: usize = 10;
}
// Now do the assoc type projection
- let projection = super::traits::ProjectionPredicate {
- ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
- .intern(&Interner),
- projection_ty: super::ProjectionTy {
+ let projection = AliasEq {
+ alias: AliasTy::Projection(ProjectionTy {
associated_ty_id: to_assoc_type_id(target),
substitution: parameters,
- },
+ }),
+ ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
+ .intern(&Interner),
};
- let obligation = super::Obligation::Projection(projection);
+ let obligation = super::Obligation::AliasEq(projection);
let in_env = InEnvironment { value: obligation, environment: ty.environment };
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, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
- ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
+ to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
+ CallableDefId, CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation,
+ OpaqueTy, ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
};
pub struct HirFormatter<'a> {
}
}
+impl HirDisplay for OpaqueTy {
+ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
+ if f.should_truncate() {
+ return write!(f, "{}", TYPE_HINT_TRUNCATION);
+ }
+
+ self.substitution[0].hir_fmt(f)
+ }
+}
+
impl HirDisplay for Ty {
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
if f.should_truncate() {
}
}
}
- GenericPredicate::Projection(projection_pred) if is_fn_trait => {
+ GenericPredicate::AliasEq(alias_eq) if is_fn_trait => {
is_fn_trait = false;
write!(f, " -> ")?;
- projection_pred.ty.hir_fmt(f)?;
+ alias_eq.ty.hir_fmt(f)?;
}
- GenericPredicate::Projection(projection_pred) => {
+ GenericPredicate::AliasEq(AliasEq { ty, alias }) => {
// in types in actual Rust, these will always come
// after the corresponding Implemented predicate
if angle_open {
write!(f, "<")?;
angle_open = true;
}
- let type_alias = f.db.type_alias_data(from_assoc_type_id(
- projection_pred.projection_ty.associated_ty_id,
- ));
- write!(f, "{} = ", type_alias.name)?;
- projection_pred.ty.hir_fmt(f)?;
+ if let AliasTy::Projection(proj) = alias {
+ let type_alias =
+ f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id));
+ write!(f, "{} = ", type_alias.name)?;
+ }
+ ty.hir_fmt(f)?;
}
GenericPredicate::Error => {
if angle_open {
match self {
GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
- GenericPredicate::Projection(projection_pred) => {
+ GenericPredicate::AliasEq(AliasEq {
+ alias: AliasTy::Projection(projection_ty),
+ ty,
+ }) => {
write!(f, "<")?;
- projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
+ projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
write!(
f,
">::{} = ",
- f.db.type_alias_data(from_assoc_type_id(
- projection_pred.projection_ty.associated_ty_id
- ))
- .name,
+ f.db.type_alias_data(from_assoc_type_id(projection_ty.associated_ty_id)).name,
)?;
- projection_pred.ty.hir_fmt(f)?;
+ ty.hir_fmt(f)?;
}
- GenericPredicate::Error => write!(f, "{{error}}")?,
+ GenericPredicate::AliasEq(_) | GenericPredicate::Error => write!(f, "{{error}}")?,
}
Ok(())
}
tr.hir_fmt(f)?;
write!(f, ")")
}
- Obligation::Projection(proj) => {
+ Obligation::AliasEq(AliasEq { alias, ty }) => {
write!(f, "Normalize(")?;
- proj.projection_ty.hir_fmt(f)?;
+ match alias {
+ AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
+ AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
+ }
write!(f, " => ")?;
- proj.ty.hir_fmt(f)?;
+ ty.hir_fmt(f)?;
write!(f, ")")
}
}
use syntax::SmolStr;
use super::{
- traits::{Guidance, Obligation, ProjectionPredicate, Solution},
+ traits::{Guidance, Obligation, Solution},
InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
};
use crate::{
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
- to_assoc_type_id, to_chalk_trait_id, AliasTy, Interner, TyKind,
+ to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
};
pub(crate) use unify::unify;
.build();
let trait_ref =
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
- let projection = ProjectionPredicate {
- ty: ty.clone(),
- projection_ty: ProjectionTy {
+ let alias_eq = AliasEq {
+ alias: AliasTy::Projection(ProjectionTy {
associated_ty_id: to_assoc_type_id(res_assoc_ty),
substitution: substs,
- },
+ }),
+ ty: ty.clone(),
};
self.obligations.push(Obligation::Trait(trait_ref));
- self.obligations.push(Obligation::Projection(projection));
+ self.obligations.push(Obligation::AliasEq(alias_eq));
self.resolve_ty_as_possible(ty)
}
None => self.err_ty(),
fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
let var = self.table.new_type_var();
- let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() };
- let obligation = Obligation::Projection(predicate);
+ let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
+ let obligation = Obligation::AliasEq(alias_eq);
self.obligations.push(obligation);
var
}
use super::{InferenceContext, Obligation};
use crate::{
- BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar,
- Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
+ AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate,
+ InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
};
impl<'a> InferenceContext<'a> {
Obligation::Trait(tr) => {
Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
}
- Obligation::Projection(pr) => {
- Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST))
+ Obligation::AliasEq(alias_eq) => {
+ Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
}
};
self.into_canonicalized(InEnvironment {
{
self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1)
}
- (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
- if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
- {
- self.unify_substs(
- &proj1.projection_ty.substitution,
- &proj2.projection_ty.substitution,
- depth + 1,
- ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1)
+ (
+ GenericPredicate::AliasEq(AliasEq { alias: alias1, ty: ty1 }),
+ GenericPredicate::AliasEq(AliasEq { alias: alias2, ty: ty2 }),
+ ) => {
+ let (substitution1, substitution2) = match (alias1, alias2) {
+ (AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2))
+ if projection_ty1.associated_ty_id == projection_ty2.associated_ty_id =>
+ {
+ (&projection_ty1.substitution, &projection_ty2.substitution)
+ }
+ (AliasTy::Opaque(opaque1), AliasTy::Opaque(opaque2))
+ if opaque1.opaque_ty_id == opaque2.opaque_ty_id =>
+ {
+ (&opaque1.substitution, &opaque2.substitution)
+ }
+ _ => return false,
+ };
+ self.unify_substs(&substitution1, &substitution2, depth + 1)
+ && self.unify_inner(&ty1, &ty2, depth + 1)
}
_ => false,
}
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
TyDefId, TyLoweringContext, ValueTyDefId,
};
-pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
+pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
pub substitution: Substitution,
}
+impl TypeWalk for OpaqueTy {
+ fn walk(&self, f: &mut impl FnMut(&Ty)) {
+ self.substitution.walk(f);
+ }
+
+ fn walk_mut_binders(
+ &mut self,
+ f: &mut impl FnMut(&mut Ty, DebruijnIndex),
+ binders: DebruijnIndex,
+ ) {
+ self.substitution.walk_mut_binders(f, binders);
+ }
+}
+
/// A "projection" type corresponds to an (unnormalized)
/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
/// trait and all its parameters are fully known.
Opaque(OpaqueTy),
}
+impl TypeWalk for AliasTy {
+ fn walk(&self, f: &mut impl FnMut(&Ty)) {
+ match self {
+ AliasTy::Projection(it) => it.walk(f),
+ AliasTy::Opaque(it) => it.walk(f),
+ }
+ }
+
+ fn walk_mut_binders(
+ &mut self,
+ f: &mut impl FnMut(&mut Ty, DebruijnIndex),
+ binders: DebruijnIndex,
+ ) {
+ match self {
+ AliasTy::Projection(it) => it.walk_mut_binders(f, binders),
+ AliasTy::Opaque(it) => it.walk_mut_binders(f, binders),
+ }
+ }
+}
/// A type.
///
/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
/// The given trait needs to be implemented for its type parameters.
Implemented(TraitRef),
/// An associated type bindings like in `Iterator<Item = T>`.
- Projection(ProjectionPredicate),
+ AliasEq(AliasEq),
/// We couldn't resolve the trait reference. (If some type parameters can't
/// be resolved, they will just be Unknown).
Error,
pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
match self {
GenericPredicate::Implemented(tr) => Some(tr.clone()),
- GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)),
- GenericPredicate::Error => None,
+ GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
+ Some(proj.trait_ref(db))
+ }
+ GenericPredicate::AliasEq(_) | GenericPredicate::Error => None,
}
}
}
fn walk(&self, f: &mut impl FnMut(&Ty)) {
match self {
GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
- GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
+ GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f),
GenericPredicate::Error => {}
}
}
) {
match self {
GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
- GenericPredicate::Projection(projection_pred) => {
- projection_pred.walk_mut_binders(f, binders)
- }
+ GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
GenericPredicate::Error => {}
}
}
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
variant_data,
},
- AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
- ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
+ AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig,
+ GenericPredicate, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait,
ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
};
);
if let Some(type_ref) = &binding.type_ref {
let ty = self.lower_ty(type_ref);
- let projection_predicate =
- ProjectionPredicate { projection_ty: projection_ty.clone(), ty };
- preds.push(GenericPredicate::Projection(projection_predicate));
+ let alias_eq =
+ AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
+ preds.push(GenericPredicate::AliasEq(alias_eq));
}
for bound in &binding.bounds {
preds.extend(self.lower_type_bound(
use hir_def::{lang_item::LangItemTarget, TraitId};
use stdx::panic_context;
-use crate::{db::HirDatabase, DebruijnIndex, Substitution};
-
-use super::{
- Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk,
+use crate::{
+ db::HirDatabase, AliasTy, Canonical, DebruijnIndex, GenericPredicate, HirDisplay, Substitution,
+ TraitRef, Ty, TyKind, TypeWalk,
};
use self::chalk::{from_chalk, Interner, ToChalk};
/// Prove that a certain type implements a trait (the type is the `Self` type
/// parameter to the `TraitRef`).
Trait(TraitRef),
- Projection(ProjectionPredicate),
+ AliasEq(AliasEq),
}
impl Obligation {
pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> {
match predicate {
GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)),
- GenericPredicate::Projection(projection_pred) => {
- Some(Obligation::Projection(projection_pred))
- }
+ GenericPredicate::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)),
GenericPredicate::Error => None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct ProjectionPredicate {
- pub projection_ty: ProjectionTy,
+pub struct AliasEq {
+ pub alias: AliasTy,
pub ty: Ty,
}
-impl TypeWalk for ProjectionPredicate {
+impl TypeWalk for AliasEq {
fn walk(&self, f: &mut impl FnMut(&Ty)) {
- self.projection_ty.walk(f);
self.ty.walk(f);
+ match &self.alias {
+ AliasTy::Projection(projection_ty) => projection_ty.walk(f),
+ AliasTy::Opaque(opaque) => opaque.walk(f),
+ }
}
fn walk_mut_binders(
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
binders: DebruijnIndex,
) {
- self.projection_ty.walk_mut_binders(f, binders);
self.ty.walk_mut_binders(f, binders);
+ match &mut self.alias {
+ AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders),
+ AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders),
+ }
}
}
) -> Option<Solution> {
let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(),
- Obligation::Projection(_) => "projection".to_string(),
+ Obligation::AliasEq(_) => "alias_eq".to_string(),
});
log::info!("trait_solve_query({})", goal.value.value.display(db));
- if let Obligation::Projection(pred) = &goal.value.value {
- if let TyKind::BoundVar(_) = &pred.projection_ty.substitution[0].interned(&Interner) {
+ if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) =
+ &goal.value.value
+ {
+ if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
// Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
return Some(Solution::Ambig(Guidance::Unknown));
}
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
to_assoc_type_id, to_chalk_trait_id,
utils::generics,
- BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
- ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
+ AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId,
+ GenericPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
};
use mapping::{
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
.intern(&Interner),
),
});
- let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
- // The parameter of the opaque type.
- ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
- .intern(&Interner),
- projection_ty: ProjectionTy {
+ let proj_bound = GenericPredicate::AliasEq(AliasEq {
+ alias: AliasTy::Projection(ProjectionTy {
associated_ty_id: to_assoc_type_id(future_output),
// Self type as the first parameter.
substitution: Substitution::single(
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
.intern(&Interner),
),
- },
+ }),
+ // The parameter of the opaque type.
+ ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
+ .intern(&Interner),
});
let bound = OpaqueTyDatumBound {
bounds: make_binders(
from_assoc_type_id,
primitive::UintTy,
traits::{Canonical, Obligation},
- AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy,
- ProjectionPredicate, ProjectionTy, Scalar, Substitution, TraitRef, Ty,
+ AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, ProjectionTy,
+ Scalar, Substitution, TraitRef, Ty,
};
use super::interner::*;
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::AliasEq(alias_eq) => make_binders(
+ chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)),
+ 0,
+ ),
GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
}
}
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::AliasEq(alias_eq) => {
+ GenericPredicate::AliasEq(from_chalk(db, alias_eq))
}
chalk_ir::WhereClause::LifetimeOutlives(_) => {
}
}
}
+impl ToChalk for OpaqueTy {
+ type Chalk = chalk_ir::OpaqueTy<Interner>;
+
+ fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
+ chalk_ir::OpaqueTy {
+ opaque_ty_id: self.opaque_ty_id,
+ substitution: self.substitution.to_chalk(db),
+ }
+ }
+
+ fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
+ OpaqueTy {
+ opaque_ty_id: chalk.opaque_ty_id,
+ substitution: from_chalk(db, chalk.substitution),
+ }
+ }
+}
+
+impl ToChalk for AliasTy {
+ type Chalk = chalk_ir::AliasTy<Interner>;
+
+ fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
+ match self {
+ AliasTy::Projection(projection_ty) => {
+ chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db))
+ }
+ AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)),
+ }
+ }
+
+ fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
+ match chalk {
+ chalk_ir::AliasTy::Projection(projection_ty) => {
+ AliasTy::Projection(from_chalk(db, projection_ty))
+ }
+ chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)),
+ }
+ }
+}
-impl ToChalk for ProjectionPredicate {
+impl ToChalk for AliasEq {
type Chalk = chalk_ir::AliasEq<Interner>;
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
- chalk_ir::AliasEq {
- alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)),
- ty: self.ty.to_chalk(db),
- }
+ chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) }
}
- fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
- unimplemented!()
+ fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self {
+ AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) }
}
}
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
match self {
Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner),
- Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner),
+ Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner),
}
}
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
Some(rust_ir::InlineBound::TraitBound(trait_bound))
}
- GenericPredicate::Projection(proj) => {
- if &proj.projection_ty.substitution[0] != self_ty {
+ GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
+ if &projection_ty.substitution[0] != self_ty {
return None;
}
- let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty_id)
+ let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id)
.lookup(db.upcast())
.container
{
AssocContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
};
- let args_no_self = proj.projection_ty.substitution[1..]
+ let args_no_self = projection_ty.substitution[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),
+ value: 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_id,
+ associated_ty_id: projection_ty.associated_ty_id,
parameters: Vec::new(), // FIXME we don't support generic associated types yet
};
Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound))
}
- GenericPredicate::Error => None,
+ _ => None,
}
}