mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-24 21:05:12 +00:00
Merge #8117
8117: Turn Obligation into something similar to chalk_ir::DomainGoal r=flodiebold a=flodiebold This includes starting to make use of Chalk's `Cast` trait. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
4d67032bbb
@ -56,8 +56,8 @@ use hir_ty::{
|
||||
primitive::UintTy,
|
||||
to_assoc_type_id,
|
||||
traits::{FnTrait, Solution, SolutionVariables},
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
|
||||
InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind,
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex,
|
||||
InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind,
|
||||
TyVariableKind, WhereClause,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -1767,7 +1767,7 @@ impl Type {
|
||||
let goal = Canonical {
|
||||
value: hir_ty::InEnvironment::new(
|
||||
self.ty.environment.clone(),
|
||||
hir_ty::Obligation::Trait(trait_ref),
|
||||
trait_ref.cast(&Interner),
|
||||
),
|
||||
kinds: Arc::new([]),
|
||||
};
|
||||
@ -1789,14 +1789,15 @@ impl Type {
|
||||
let goal = Canonical {
|
||||
value: InEnvironment::new(
|
||||
self.ty.environment.clone(),
|
||||
Obligation::AliasEq(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),
|
||||
}),
|
||||
}
|
||||
.cast(&Interner),
|
||||
),
|
||||
kinds: Arc::new([TyVariableKind::General]),
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
use std::iter::successors;
|
||||
|
||||
use base_db::CrateId;
|
||||
use chalk_ir::cast::Cast;
|
||||
use hir_def::lang_item::LangItemTarget;
|
||||
use hir_expand::name::name;
|
||||
use log::{info, warn};
|
||||
@ -15,8 +16,8 @@ use crate::{
|
||||
to_assoc_type_id, to_chalk_trait_id,
|
||||
traits::{InEnvironment, Solution},
|
||||
utils::generics,
|
||||
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy,
|
||||
Substitution, TraitRef, Ty, TyKind,
|
||||
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution,
|
||||
TraitRef, Ty, TyKind,
|
||||
};
|
||||
|
||||
const AUTODEREF_RECURSION_LIMIT: usize = 10;
|
||||
@ -74,7 +75,7 @@ fn deref_by_trait(
|
||||
let implements_goal = Canonical {
|
||||
kinds: ty.value.kinds.clone(),
|
||||
value: InEnvironment {
|
||||
value: Obligation::Trait(trait_ref),
|
||||
value: trait_ref.cast(&Interner),
|
||||
environment: ty.environment.clone(),
|
||||
},
|
||||
};
|
||||
@ -92,7 +93,7 @@ fn deref_by_trait(
|
||||
.intern(&Interner),
|
||||
};
|
||||
|
||||
let obligation = super::Obligation::AliasEq(projection);
|
||||
let obligation = projection.cast(&Interner);
|
||||
|
||||
let in_env = InEnvironment { value: obligation, environment: ty.environment };
|
||||
|
||||
|
53
crates/hir_ty/src/chalk_cast.rs
Normal file
53
crates/hir_ty/src/chalk_cast.rs
Normal file
@ -0,0 +1,53 @@
|
||||
//! Implementations of the Chalk `Cast` trait for our types.
|
||||
|
||||
use chalk_ir::{
|
||||
cast::{Cast, CastTo},
|
||||
interner::HasInterner,
|
||||
};
|
||||
|
||||
use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
|
||||
|
||||
macro_rules! has_interner {
|
||||
($t:ty) => {
|
||||
impl HasInterner for $t {
|
||||
type Interner = crate::Interner;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
has_interner!(WhereClause);
|
||||
has_interner!(DomainGoal);
|
||||
|
||||
impl CastTo<WhereClause> for TraitRef {
|
||||
fn cast_to(self, _interner: &Interner) -> WhereClause {
|
||||
WhereClause::Implemented(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl CastTo<WhereClause> for AliasEq {
|
||||
fn cast_to(self, _interner: &Interner) -> WhereClause {
|
||||
WhereClause::AliasEq(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl CastTo<DomainGoal> for WhereClause {
|
||||
fn cast_to(self, _interner: &Interner) -> DomainGoal {
|
||||
DomainGoal::Holds(self)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! transitive_impl {
|
||||
($a:ty, $b:ty, $c:ty) => {
|
||||
impl CastTo<$c> for $a {
|
||||
fn cast_to(self, interner: &Interner) -> $c {
|
||||
self.cast::<$b>(interner).cast(interner)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// In Chalk, these can be done as blanket impls, but that doesn't work here
|
||||
// because of coherence
|
||||
|
||||
transitive_impl!(TraitRef, WhereClause, DomainGoal);
|
||||
transitive_impl!(AliasEq, WhereClause, DomainGoal);
|
@ -119,7 +119,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||
fn trait_solve(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>,
|
||||
goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
|
||||
) -> Option<crate::traits::Solution>;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
|
||||
|
@ -19,7 +19,7 @@ use hir_expand::name::Name;
|
||||
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, AliasEq, AliasTy,
|
||||
CallableDefId, CallableSig, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
|
||||
CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
|
||||
ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
@ -805,22 +805,12 @@ impl HirDisplay for Lifetime {
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for Obligation {
|
||||
impl HirDisplay for DomainGoal {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
Obligation::Trait(tr) => {
|
||||
write!(f, "Implements(")?;
|
||||
tr.hir_fmt(f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
Obligation::AliasEq(AliasEq { alias, ty }) => {
|
||||
write!(f, "Normalize(")?;
|
||||
match alias {
|
||||
AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
|
||||
AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
|
||||
}
|
||||
write!(f, " => ")?;
|
||||
ty.hir_fmt(f)?;
|
||||
DomainGoal::Holds(wc) => {
|
||||
write!(f, "Holds(")?;
|
||||
wc.hir_fmt(f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use std::mem;
|
||||
use std::ops::Index;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chalk_ir::Mutability;
|
||||
use chalk_ir::{cast::Cast, Mutability};
|
||||
use hir_def::{
|
||||
body::Body,
|
||||
data::{ConstData, FunctionData, StaticData},
|
||||
@ -37,7 +37,7 @@ use stdx::impl_from;
|
||||
use syntax::SmolStr;
|
||||
|
||||
use super::{
|
||||
traits::{Guidance, Obligation, Solution},
|
||||
traits::{DomainGoal, Guidance, Solution},
|
||||
InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
|
||||
};
|
||||
use crate::{
|
||||
@ -204,7 +204,7 @@ struct InferenceContext<'a> {
|
||||
resolver: Resolver,
|
||||
table: unify::InferenceTable,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
obligations: Vec<Obligation>,
|
||||
obligations: Vec<DomainGoal>,
|
||||
result: InferenceResult,
|
||||
/// The return type of the function being inferred, or the closure if we're
|
||||
/// currently within one.
|
||||
@ -403,8 +403,8 @@ impl<'a> InferenceContext<'a> {
|
||||
}),
|
||||
ty: ty.clone(),
|
||||
};
|
||||
self.obligations.push(Obligation::Trait(trait_ref));
|
||||
self.obligations.push(Obligation::AliasEq(alias_eq));
|
||||
self.obligations.push(trait_ref.cast(&Interner));
|
||||
self.obligations.push(alias_eq.cast(&Interner));
|
||||
self.resolve_ty_as_possible(ty)
|
||||
}
|
||||
None => self.err_ty(),
|
||||
@ -430,7 +430,7 @@ impl<'a> InferenceContext<'a> {
|
||||
fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
|
||||
let var = self.table.new_type_var();
|
||||
let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
|
||||
let obligation = Obligation::AliasEq(alias_eq);
|
||||
let obligation = alias_eq.cast(&Interner);
|
||||
self.obligations.push(obligation);
|
||||
var
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
//!
|
||||
//! See: https://doc.rust-lang.org/nomicon/coercions.html
|
||||
|
||||
use chalk_ir::{Mutability, TyVariableKind};
|
||||
use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
|
||||
use hir_def::lang_item::LangItemTarget;
|
||||
|
||||
use crate::{
|
||||
autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef,
|
||||
Ty, TyKind,
|
||||
autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind,
|
||||
};
|
||||
|
||||
use super::{InEnvironment, InferenceContext};
|
||||
@ -143,7 +142,7 @@ impl<'a> InferenceContext<'a> {
|
||||
.build();
|
||||
let trait_ref =
|
||||
TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
|
||||
let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref));
|
||||
let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner));
|
||||
|
||||
let canonicalizer = self.canonicalizer();
|
||||
let canonicalized = canonicalizer.canonicalize_obligation(goal);
|
||||
|
@ -3,7 +3,7 @@
|
||||
use std::iter::{repeat, repeat_with};
|
||||
use std::{mem, sync::Arc};
|
||||
|
||||
use chalk_ir::{Mutability, TyVariableKind};
|
||||
use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
|
||||
use hir_def::{
|
||||
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
|
||||
path::{GenericArg, GenericArgs},
|
||||
@ -21,7 +21,7 @@ use crate::{
|
||||
to_assoc_type_id, to_chalk_trait_id,
|
||||
traits::{chalk::from_chalk, FnTrait, InEnvironment},
|
||||
utils::{generics, variant_data, Generics},
|
||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
|
||||
AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar,
|
||||
Substitution, TraitRef, Ty, TyKind,
|
||||
};
|
||||
|
||||
@ -90,10 +90,9 @@ impl<'a> InferenceContext<'a> {
|
||||
Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
|
||||
|
||||
let trait_env = Arc::clone(&self.trait_env);
|
||||
let implements_fn_trait = Obligation::Trait(TraitRef {
|
||||
trait_id: to_chalk_trait_id(fn_once_trait),
|
||||
substitution: substs.clone(),
|
||||
});
|
||||
let implements_fn_trait: DomainGoal =
|
||||
TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
|
||||
.cast(&Interner);
|
||||
let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
|
||||
value: implements_fn_trait.clone(),
|
||||
environment: trait_env,
|
||||
@ -938,22 +937,20 @@ impl<'a> InferenceContext<'a> {
|
||||
let generic_predicates = self.db.generic_predicates(def.into());
|
||||
for predicate in generic_predicates.iter() {
|
||||
let predicate = predicate.clone().subst(parameters);
|
||||
if let Some(obligation) = Obligation::from_predicate(predicate) {
|
||||
self.obligations.push(obligation);
|
||||
}
|
||||
self.obligations.push(predicate.cast(&Interner));
|
||||
}
|
||||
// add obligation for trait implementation, if this is a trait method
|
||||
match def {
|
||||
CallableDefId::FunctionId(f) => {
|
||||
if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
|
||||
{
|
||||
// construct a TraitDef
|
||||
// construct a TraitRef
|
||||
let substs =
|
||||
parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
|
||||
self.obligations.push(Obligation::Trait(TraitRef {
|
||||
trait_id: to_chalk_trait_id(trait_),
|
||||
substitution: substs,
|
||||
}));
|
||||
self.obligations.push(
|
||||
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
|
||||
.cast(&Interner),
|
||||
);
|
||||
}
|
||||
}
|
||||
CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use std::iter;
|
||||
|
||||
use chalk_ir::cast::Cast;
|
||||
use hir_def::{
|
||||
path::{Path, PathSegment},
|
||||
resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||
@ -256,10 +257,13 @@ impl<'a> InferenceContext<'a> {
|
||||
.push(ty.clone())
|
||||
.fill(std::iter::repeat_with(|| self.table.new_type_var()))
|
||||
.build();
|
||||
self.obligations.push(super::Obligation::Trait(TraitRef {
|
||||
trait_id: to_chalk_trait_id(trait_),
|
||||
substitution: trait_substs.clone(),
|
||||
}));
|
||||
self.obligations.push(
|
||||
TraitRef {
|
||||
trait_id: to_chalk_trait_id(trait_),
|
||||
substitution: trait_substs.clone(),
|
||||
}
|
||||
.cast(&Interner),
|
||||
);
|
||||
Some(trait_substs)
|
||||
}
|
||||
AssocContainerId::ModuleId(_) => None,
|
||||
|
@ -5,7 +5,7 @@ use std::borrow::Cow;
|
||||
use chalk_ir::{FloatTy, IntTy, TyVariableKind};
|
||||
use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
|
||||
|
||||
use super::{InferenceContext, Obligation};
|
||||
use super::{DomainGoal, InferenceContext};
|
||||
use crate::{
|
||||
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar,
|
||||
Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
|
||||
@ -87,14 +87,11 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
|
||||
|
||||
pub(crate) fn canonicalize_obligation(
|
||||
mut self,
|
||||
obligation: InEnvironment<Obligation>,
|
||||
) -> Canonicalized<InEnvironment<Obligation>> {
|
||||
obligation: InEnvironment<DomainGoal>,
|
||||
) -> Canonicalized<InEnvironment<DomainGoal>> {
|
||||
let result = match obligation.value {
|
||||
Obligation::Trait(tr) => {
|
||||
Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
|
||||
}
|
||||
Obligation::AliasEq(alias_eq) => {
|
||||
Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
|
||||
DomainGoal::Holds(wc) => {
|
||||
DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
|
||||
}
|
||||
};
|
||||
self.into_canonicalized(InEnvironment {
|
||||
|
@ -13,6 +13,7 @@ mod op;
|
||||
mod lower;
|
||||
pub(crate) mod infer;
|
||||
pub(crate) mod utils;
|
||||
mod chalk_cast;
|
||||
|
||||
pub mod display;
|
||||
pub mod db;
|
||||
@ -45,9 +46,11 @@ pub use lower::{
|
||||
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
|
||||
TyDefId, TyLoweringContext, ValueTyDefId,
|
||||
};
|
||||
pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
|
||||
pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment};
|
||||
|
||||
pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
|
||||
pub use chalk_ir::{
|
||||
cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
|
||||
};
|
||||
|
||||
pub use crate::traits::chalk::Interner;
|
||||
|
||||
|
@ -6,7 +6,7 @@ use std::{iter, sync::Arc};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use base_db::CrateId;
|
||||
use chalk_ir::Mutability;
|
||||
use chalk_ir::{cast::Cast, Mutability};
|
||||
use hir_def::{
|
||||
lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
|
||||
ImplId, Lookup, ModuleId, TraitId,
|
||||
@ -767,7 +767,7 @@ fn generic_implements_goal(
|
||||
env: Arc<TraitEnvironment>,
|
||||
trait_: TraitId,
|
||||
self_ty: Canonical<Ty>,
|
||||
) -> Canonical<InEnvironment<super::Obligation>> {
|
||||
) -> Canonical<InEnvironment<super::DomainGoal>> {
|
||||
let mut kinds = self_ty.kinds.to_vec();
|
||||
let substs = super::Substitution::build_for_def(db, trait_)
|
||||
.push(self_ty.value)
|
||||
@ -775,7 +775,7 @@ fn generic_implements_goal(
|
||||
.build();
|
||||
kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
|
||||
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
|
||||
let obligation = super::Obligation::Trait(trait_ref);
|
||||
let obligation = trait_ref.cast(&Interner);
|
||||
Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@ use hir_def::{lang_item::LangItemTarget, TraitId};
|
||||
use stdx::panic_context;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, TraitRef, Ty,
|
||||
TyKind, TypeWalk, WhereClause,
|
||||
db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind,
|
||||
TypeWalk, WhereClause,
|
||||
};
|
||||
|
||||
use self::chalk::{from_chalk, Interner, ToChalk};
|
||||
@ -88,20 +88,8 @@ impl<T> InEnvironment<T> {
|
||||
/// a certain type implements a certain trait. Proving the Obligation might
|
||||
/// result in additional information about inference variables.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum Obligation {
|
||||
/// Prove that a certain type implements a trait (the type is the `Self` type
|
||||
/// parameter to the `TraitRef`).
|
||||
Trait(TraitRef),
|
||||
AliasEq(AliasEq),
|
||||
}
|
||||
|
||||
impl Obligation {
|
||||
pub fn from_predicate(predicate: WhereClause) -> Option<Obligation> {
|
||||
match predicate {
|
||||
WhereClause::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)),
|
||||
WhereClause::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)),
|
||||
}
|
||||
}
|
||||
pub enum DomainGoal {
|
||||
Holds(WhereClause),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
@ -136,16 +124,20 @@ impl TypeWalk for AliasEq {
|
||||
pub(crate) fn trait_solve_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
goal: Canonical<InEnvironment<Obligation>>,
|
||||
goal: Canonical<InEnvironment<DomainGoal>>,
|
||||
) -> 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::AliasEq(_) => "alias_eq".to_string(),
|
||||
DomainGoal::Holds(WhereClause::Implemented(it)) => {
|
||||
db.trait_data(it.hir_trait_id()).name.to_string()
|
||||
}
|
||||
DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
|
||||
});
|
||||
log::info!("trait_solve_query({})", goal.value.value.display(db));
|
||||
|
||||
if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) =
|
||||
&goal.value.value
|
||||
if let DomainGoal::Holds(WhereClause::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
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
db::HirDatabase,
|
||||
from_assoc_type_id,
|
||||
primitive::UintTy,
|
||||
traits::{Canonical, Obligation},
|
||||
traits::{Canonical, DomainGoal},
|
||||
AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution,
|
||||
TraitRef, Ty, WhereClause,
|
||||
};
|
||||
@ -422,13 +422,15 @@ impl ToChalk for AliasEq {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToChalk for Obligation {
|
||||
impl ToChalk for DomainGoal {
|
||||
type Chalk = chalk_ir::DomainGoal<Interner>;
|
||||
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
|
||||
match self {
|
||||
Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner),
|
||||
Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner),
|
||||
DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner),
|
||||
DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
|
||||
alias_eq.to_chalk(db).cast(&Interner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user