mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 14:51:48 +00:00
Chalkify TraitRef
This commit is contained in:
parent
b70bea0d79
commit
7a7e47eab7
15 changed files with 99 additions and 73 deletions
|
@ -1462,7 +1462,7 @@ impl TypeParam {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|pred| match &pred.value {
|
.filter_map(|pred| match &pred.value {
|
||||||
hir_ty::GenericPredicate::Implemented(trait_ref) => {
|
hir_ty::GenericPredicate::Implemented(trait_ref) => {
|
||||||
Some(Trait::from(trait_ref.trait_))
|
Some(Trait::from(trait_ref.hir_trait_id()))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
@ -1757,8 +1757,8 @@ impl Type {
|
||||||
|
|
||||||
pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
|
pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
|
||||||
let trait_ref = hir_ty::TraitRef {
|
let trait_ref = hir_ty::TraitRef {
|
||||||
trait_: trait_.id,
|
trait_id: hir_ty::to_chalk_trait_id(trait_.id),
|
||||||
substs: Substitution::build_for_def(db, trait_.id)
|
substitution: Substitution::build_for_def(db, trait_.id)
|
||||||
.push(self.ty.value.clone())
|
.push(self.ty.value.clone())
|
||||||
.fill(args.iter().map(|t| t.ty.value.clone()))
|
.fill(args.iter().map(|t| t.ty.value.clone()))
|
||||||
.build(),
|
.build(),
|
||||||
|
@ -2023,7 +2023,7 @@ impl Type {
|
||||||
it.into_iter()
|
it.into_iter()
|
||||||
.filter_map(|pred| match pred {
|
.filter_map(|pred| match pred {
|
||||||
hir_ty::GenericPredicate::Implemented(trait_ref) => {
|
hir_ty::GenericPredicate::Implemented(trait_ref) => {
|
||||||
Some(Trait::from(trait_ref.trait_))
|
Some(Trait::from(trait_ref.hir_trait_id()))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
@ -2067,7 +2067,7 @@ impl Type {
|
||||||
match pred {
|
match pred {
|
||||||
GenericPredicate::Implemented(trait_ref) => {
|
GenericPredicate::Implemented(trait_ref) => {
|
||||||
cb(type_.clone());
|
cb(type_.clone());
|
||||||
walk_substs(db, type_, &trait_ref.substs, cb);
|
walk_substs(db, type_, &trait_ref.substitution, cb);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use log::{info, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
to_assoc_type_id,
|
to_assoc_type_id, to_chalk_trait_id,
|
||||||
traits::{InEnvironment, Solution},
|
traits::{InEnvironment, Solution},
|
||||||
utils::generics,
|
utils::generics,
|
||||||
BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
|
BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
|
||||||
|
@ -68,7 +68,8 @@ fn deref_by_trait(
|
||||||
Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
|
Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
|
||||||
|
|
||||||
// Check that the type implements Deref at all
|
// Check that the type implements Deref at all
|
||||||
let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() };
|
let trait_ref =
|
||||||
|
TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
|
||||||
let implements_goal = Canonical {
|
let implements_goal = Canonical {
|
||||||
kinds: ty.value.kinds.clone(),
|
kinds: ty.value.kinds.clone(),
|
||||||
value: InEnvironment {
|
value: InEnvironment {
|
||||||
|
|
|
@ -344,7 +344,7 @@ impl HirDisplay for Ty {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() {
|
if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() {
|
||||||
let trait_ = trait_ref.trait_;
|
let trait_ = trait_ref.hir_trait_id();
|
||||||
if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) {
|
if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) {
|
||||||
return write!(f, "{}", ty_display);
|
return write!(f, "{}", ty_display);
|
||||||
}
|
}
|
||||||
|
@ -670,7 +670,7 @@ fn write_bounds_like_dyn_trait(
|
||||||
for p in predicates.iter() {
|
for p in predicates.iter() {
|
||||||
match p {
|
match p {
|
||||||
GenericPredicate::Implemented(trait_ref) => {
|
GenericPredicate::Implemented(trait_ref) => {
|
||||||
let trait_ = trait_ref.trait_;
|
let trait_ = trait_ref.hir_trait_id();
|
||||||
if !is_fn_trait {
|
if !is_fn_trait {
|
||||||
is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_);
|
is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_);
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ fn write_bounds_like_dyn_trait(
|
||||||
// existential) here, which is the only thing that's
|
// existential) here, which is the only thing that's
|
||||||
// possible in actual Rust, and hence don't print it
|
// possible in actual Rust, and hence don't print it
|
||||||
write!(f, "{}", f.db.trait_data(trait_).name)?;
|
write!(f, "{}", f.db.trait_data(trait_).name)?;
|
||||||
if let [_, params @ ..] = &*trait_ref.substs.0 {
|
if let [_, params @ ..] = &*trait_ref.substitution.0 {
|
||||||
if is_fn_trait {
|
if is_fn_trait {
|
||||||
if let Some(args) = params.first().and_then(|it| it.as_tuple()) {
|
if let Some(args) = params.first().and_then(|it| it.as_tuple()) {
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
|
@ -745,16 +745,16 @@ impl TraitRef {
|
||||||
return write!(f, "{}", TYPE_HINT_TRUNCATION);
|
return write!(f, "{}", TYPE_HINT_TRUNCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.substs[0].hir_fmt(f)?;
|
self.substitution[0].hir_fmt(f)?;
|
||||||
if use_as {
|
if use_as {
|
||||||
write!(f, " as ")?;
|
write!(f, " as ")?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, ": ")?;
|
write!(f, ": ")?;
|
||||||
}
|
}
|
||||||
write!(f, "{}", f.db.trait_data(self.trait_).name)?;
|
write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
|
||||||
if self.substs.len() > 1 {
|
if self.substitution.len() > 1 {
|
||||||
write!(f, "<")?;
|
write!(f, "<")?;
|
||||||
f.write_joined(&self.substs[1..], ", ")?;
|
f.write_joined(&self.substitution[1..], ", ")?;
|
||||||
write!(f, ">")?;
|
write!(f, ">")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -42,7 +42,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
|
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
|
||||||
to_assoc_type_id, AliasTy, Interner, TyKind,
|
to_assoc_type_id, to_chalk_trait_id, AliasTy, Interner, TyKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use unify::unify;
|
pub(crate) use unify::unify;
|
||||||
|
@ -394,7 +394,8 @@ impl<'a> InferenceContext<'a> {
|
||||||
.push(inner_ty)
|
.push(inner_ty)
|
||||||
.fill(params.iter().cloned())
|
.fill(params.iter().cloned())
|
||||||
.build();
|
.build();
|
||||||
let trait_ref = TraitRef { trait_, substs: substs.clone() };
|
let trait_ref =
|
||||||
|
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
|
||||||
let projection = ProjectionPredicate {
|
let projection = ProjectionPredicate {
|
||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
projection_ty: ProjectionTy {
|
projection_ty: ProjectionTy {
|
||||||
|
|
|
@ -8,7 +8,8 @@ use chalk_ir::{Mutability, TyVariableKind};
|
||||||
use hir_def::lang_item::LangItemTarget;
|
use hir_def::lang_item::LangItemTarget;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autoderef, traits::Solution, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
|
autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef,
|
||||||
|
Ty, TyKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{InEnvironment, InferenceContext};
|
use super::{InEnvironment, InferenceContext};
|
||||||
|
@ -140,7 +141,8 @@ impl<'a> InferenceContext<'a> {
|
||||||
.push(from_ty.clone())
|
.push(from_ty.clone())
|
||||||
.push(to_ty.clone())
|
.push(to_ty.clone())
|
||||||
.build();
|
.build();
|
||||||
let trait_ref = TraitRef { trait_: coerce_unsized_trait, substs };
|
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(), Obligation::Trait(trait_ref));
|
||||||
|
|
||||||
let canonicalizer = self.canonicalizer();
|
let canonicalizer = self.canonicalizer();
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
lower::lower_to_chalk_mutability,
|
lower::lower_to_chalk_mutability,
|
||||||
method_resolution, op,
|
method_resolution, op,
|
||||||
primitive::{self, UintTy},
|
primitive::{self, UintTy},
|
||||||
to_assoc_type_id,
|
to_assoc_type_id, to_chalk_trait_id,
|
||||||
traits::{chalk::from_chalk, FnTrait, InEnvironment},
|
traits::{chalk::from_chalk, FnTrait, InEnvironment},
|
||||||
utils::{generics, variant_data, Generics},
|
utils::{generics, variant_data, Generics},
|
||||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
|
AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
|
||||||
|
@ -90,8 +90,10 @@ impl<'a> InferenceContext<'a> {
|
||||||
Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
|
Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
|
||||||
|
|
||||||
let trait_env = Arc::clone(&self.trait_env);
|
let trait_env = Arc::clone(&self.trait_env);
|
||||||
let implements_fn_trait =
|
let implements_fn_trait = Obligation::Trait(TraitRef {
|
||||||
Obligation::Trait(TraitRef { trait_: fn_once_trait, substs: substs.clone() });
|
trait_id: to_chalk_trait_id(fn_once_trait),
|
||||||
|
substitution: substs.clone(),
|
||||||
|
});
|
||||||
let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
|
let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
|
||||||
value: implements_fn_trait.clone(),
|
value: implements_fn_trait.clone(),
|
||||||
environment: trait_env,
|
environment: trait_env,
|
||||||
|
@ -948,7 +950,10 @@ impl<'a> InferenceContext<'a> {
|
||||||
// construct a TraitDef
|
// construct a TraitDef
|
||||||
let substs =
|
let substs =
|
||||||
parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
|
parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
|
||||||
self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
|
self.obligations.push(Obligation::Trait(TraitRef {
|
||||||
|
trait_id: to_chalk_trait_id(trait_),
|
||||||
|
substitution: substs,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
|
CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
|
||||||
|
|
|
@ -9,7 +9,9 @@ use hir_def::{
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
||||||
use crate::{method_resolution, Interner, Substitution, Ty, TyKind, ValueTyDefId};
|
use crate::{
|
||||||
|
method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{ExprOrPatId, InferenceContext, TraitRef};
|
use super::{ExprOrPatId, InferenceContext, TraitRef};
|
||||||
|
|
||||||
|
@ -165,7 +167,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
segment: PathSegment<'_>,
|
segment: PathSegment<'_>,
|
||||||
id: ExprOrPatId,
|
id: ExprOrPatId,
|
||||||
) -> Option<(ValueNs, Option<Substitution>)> {
|
) -> Option<(ValueNs, Option<Substitution>)> {
|
||||||
let trait_ = trait_ref.trait_;
|
let trait_ = trait_ref.hir_trait_id();
|
||||||
let item =
|
let item =
|
||||||
self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
|
self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
|
||||||
match item {
|
match item {
|
||||||
|
@ -200,7 +202,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.write_assoc_resolution(id, item);
|
self.write_assoc_resolution(id, item);
|
||||||
Some((def, Some(trait_ref.substs)))
|
Some((def, Some(trait_ref.substitution)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_ty_assoc_item(
|
fn resolve_ty_assoc_item(
|
||||||
|
@ -255,8 +257,8 @@ impl<'a> InferenceContext<'a> {
|
||||||
.fill(std::iter::repeat_with(|| self.table.new_type_var()))
|
.fill(std::iter::repeat_with(|| self.table.new_type_var()))
|
||||||
.build();
|
.build();
|
||||||
self.obligations.push(super::Obligation::Trait(TraitRef {
|
self.obligations.push(super::Obligation::Trait(TraitRef {
|
||||||
trait_,
|
trait_id: to_chalk_trait_id(trait_),
|
||||||
substs: trait_substs.clone(),
|
substitution: trait_substs.clone(),
|
||||||
}));
|
}));
|
||||||
Some(trait_substs)
|
Some(trait_substs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,9 +390,9 @@ impl InferenceTable {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match (pred1, pred2) {
|
match (pred1, pred2) {
|
||||||
(GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2))
|
(GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2))
|
||||||
if tr1.trait_ == tr2.trait_ =>
|
if tr1.trait_id == tr2.trait_id =>
|
||||||
{
|
{
|
||||||
self.unify_substs(&tr1.substs, &tr2.substs, depth + 1)
|
self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1)
|
||||||
}
|
}
|
||||||
(GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
|
(GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
|
||||||
if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
|
if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
|
||||||
|
|
|
@ -58,6 +58,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
|
||||||
pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
|
pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
|
||||||
pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
|
pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
|
||||||
|
|
||||||
|
pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub enum Lifetime {
|
pub enum Lifetime {
|
||||||
Parameter(LifetimeParamId),
|
Parameter(LifetimeParamId),
|
||||||
|
@ -81,7 +83,10 @@ pub struct ProjectionTy {
|
||||||
|
|
||||||
impl ProjectionTy {
|
impl ProjectionTy {
|
||||||
pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
|
pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
|
||||||
TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() }
|
TraitRef {
|
||||||
|
trait_id: to_chalk_trait_id(self.trait_(db)),
|
||||||
|
substitution: self.substitution.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
|
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
|
||||||
|
@ -493,23 +498,25 @@ impl<T: TypeWalk> TypeWalk for Binders<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
|
/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
|
||||||
/// Name to be bikeshedded: TraitBound? TraitImplements?
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct TraitRef {
|
pub struct TraitRef {
|
||||||
/// FIXME name?
|
pub trait_id: ChalkTraitId,
|
||||||
pub trait_: TraitId,
|
pub substitution: Substitution,
|
||||||
pub substs: Substitution,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TraitRef {
|
impl TraitRef {
|
||||||
pub fn self_ty(&self) -> &Ty {
|
pub fn self_type_parameter(&self) -> &Ty {
|
||||||
&self.substs[0]
|
&self.substitution[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hir_trait_id(&self) -> TraitId {
|
||||||
|
from_chalk_trait_id(self.trait_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeWalk for TraitRef {
|
impl TypeWalk for TraitRef {
|
||||||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||||
self.substs.walk(f);
|
self.substitution.walk(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_mut_binders(
|
fn walk_mut_binders(
|
||||||
|
@ -517,7 +524,7 @@ impl TypeWalk for TraitRef {
|
||||||
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
|
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
|
||||||
binders: DebruijnIndex,
|
binders: DebruijnIndex,
|
||||||
) {
|
) {
|
||||||
self.substs.walk_mut_binders(f, binders);
|
self.substitution.walk_mut_binders(f, binders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,7 +791,7 @@ impl Ty {
|
||||||
|
|
||||||
/// If this is a `dyn Trait`, returns that trait.
|
/// If this is a `dyn Trait`, returns that trait.
|
||||||
pub fn dyn_trait(&self) -> Option<TraitId> {
|
pub fn dyn_trait(&self) -> Option<TraitId> {
|
||||||
self.dyn_trait_ref().map(|it| it.trait_)
|
self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn builtin_deref(&self) -> Option<Ty> {
|
fn builtin_deref(&self) -> Option<Ty> {
|
||||||
|
@ -868,8 +875,8 @@ impl Ty {
|
||||||
// Parameters will be walked outside, and projection predicate is not used.
|
// Parameters will be walked outside, and projection predicate is not used.
|
||||||
// So just provide the Future trait.
|
// So just provide the Future trait.
|
||||||
let impl_bound = GenericPredicate::Implemented(TraitRef {
|
let impl_bound = GenericPredicate::Implemented(TraitRef {
|
||||||
trait_: future_trait,
|
trait_id: to_chalk_trait_id(future_trait),
|
||||||
substs: Substitution::empty(),
|
substitution: Substitution::empty(),
|
||||||
});
|
});
|
||||||
Some(vec![impl_bound])
|
Some(vec![impl_bound])
|
||||||
} else {
|
} else {
|
||||||
|
@ -1158,3 +1165,11 @@ pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderI
|
||||||
idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
|
idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ use stdx::impl_from;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
to_assoc_type_id, to_placeholder_idx,
|
to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
|
||||||
traits::chalk::{Interner, ToChalk},
|
traits::chalk::{Interner, ToChalk},
|
||||||
utils::{
|
utils::{
|
||||||
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
|
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
|
||||||
|
@ -360,7 +360,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
// FIXME handle type parameters on the segment
|
// FIXME handle type parameters on the segment
|
||||||
TyKind::Alias(AliasTy::Projection(ProjectionTy {
|
TyKind::Alias(AliasTy::Projection(ProjectionTy {
|
||||||
associated_ty_id: to_assoc_type_id(associated_ty),
|
associated_ty_id: to_assoc_type_id(associated_ty),
|
||||||
substitution: super_trait_ref.substs,
|
substitution: super_trait_ref.substitution,
|
||||||
}))
|
}))
|
||||||
.intern(&Interner)
|
.intern(&Interner)
|
||||||
}
|
}
|
||||||
|
@ -470,9 +470,9 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
"there should be generics if there's a generic param",
|
"there should be generics if there's a generic param",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
t.substs.clone().subst_bound_vars(&s)
|
t.substitution.clone().subst_bound_vars(&s)
|
||||||
}
|
}
|
||||||
TypeParamLoweringMode::Variable => t.substs.clone(),
|
TypeParamLoweringMode::Variable => t.substitution.clone(),
|
||||||
};
|
};
|
||||||
// We need to shift in the bound vars, since
|
// We need to shift in the bound vars, since
|
||||||
// associated_type_shorthand_candidates does not do that
|
// associated_type_shorthand_candidates does not do that
|
||||||
|
@ -641,7 +641,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
if let Some(self_ty) = explicit_self_ty {
|
if let Some(self_ty) = explicit_self_ty {
|
||||||
substs.0[0] = self_ty;
|
substs.0[0] = self_ty;
|
||||||
}
|
}
|
||||||
TraitRef { trait_: resolved, substs }
|
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_trait_ref(
|
fn lower_trait_ref(
|
||||||
|
@ -743,7 +743,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
};
|
};
|
||||||
let projection_ty = ProjectionTy {
|
let projection_ty = ProjectionTy {
|
||||||
associated_ty_id: to_assoc_type_id(associated_ty),
|
associated_ty_id: to_assoc_type_id(associated_ty),
|
||||||
substitution: super_trait_ref.substs,
|
substitution: super_trait_ref.substitution,
|
||||||
};
|
};
|
||||||
let mut preds = SmallVec::with_capacity(
|
let mut preds = SmallVec::with_capacity(
|
||||||
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
|
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
|
||||||
|
@ -820,8 +820,8 @@ pub fn associated_type_shorthand_candidates<R>(
|
||||||
== TypeParamProvenance::TraitSelf
|
== TypeParamProvenance::TraitSelf
|
||||||
{
|
{
|
||||||
let trait_ref = TraitRef {
|
let trait_ref = TraitRef {
|
||||||
trait_: trait_id,
|
trait_id: to_chalk_trait_id(trait_id),
|
||||||
substs: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
|
substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
|
||||||
};
|
};
|
||||||
traits_.push(trait_ref);
|
traits_.push(trait_ref);
|
||||||
}
|
}
|
||||||
|
@ -832,7 +832,7 @@ pub fn associated_type_shorthand_candidates<R>(
|
||||||
};
|
};
|
||||||
|
|
||||||
for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
|
for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
|
||||||
let data = db.trait_data(t.trait_);
|
let data = db.trait_data(t.hir_trait_id());
|
||||||
|
|
||||||
for (name, assoc_id) in &data.items {
|
for (name, assoc_id) in &data.items {
|
||||||
match assoc_id {
|
match assoc_id {
|
||||||
|
@ -926,7 +926,7 @@ pub(crate) fn trait_environment_query(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let GenericPredicate::Implemented(tr) = &pred {
|
if let GenericPredicate::Implemented(tr) = &pred {
|
||||||
traits_in_scope.push((tr.self_ty().clone(), tr.trait_));
|
traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
|
||||||
}
|
}
|
||||||
let program_clause: chalk_ir::ProgramClause<Interner> =
|
let program_clause: chalk_ir::ProgramClause<Interner> =
|
||||||
pred.clone().to_chalk(db).cast(&Interner);
|
pred.clone().to_chalk(db).cast(&Interner);
|
||||||
|
@ -950,7 +950,7 @@ pub(crate) fn trait_environment_query(
|
||||||
// inside consts or type aliases)
|
// inside consts or type aliases)
|
||||||
cov_mark::hit!(trait_self_implements_self);
|
cov_mark::hit!(trait_self_implements_self);
|
||||||
let substs = Substitution::type_params(db, trait_id);
|
let substs = Substitution::type_params(db, trait_id);
|
||||||
let trait_ref = TraitRef { trait_: trait_id, substs };
|
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
|
||||||
let pred = GenericPredicate::Implemented(trait_ref);
|
let pred = GenericPredicate::Implemented(trait_ref);
|
||||||
let program_clause: chalk_ir::ProgramClause<Interner> =
|
let program_clause: chalk_ir::ProgramClause<Interner> =
|
||||||
pred.clone().to_chalk(db).cast(&Interner);
|
pred.clone().to_chalk(db).cast(&Interner);
|
||||||
|
|
|
@ -19,6 +19,7 @@ use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
from_foreign_def_id,
|
from_foreign_def_id,
|
||||||
primitive::{self, FloatTy, IntTy, UintTy},
|
primitive::{self, FloatTy, IntTy, UintTy},
|
||||||
|
to_chalk_trait_id,
|
||||||
utils::all_super_traits,
|
utils::all_super_traits,
|
||||||
AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
|
AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
|
||||||
Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
|
Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
|
||||||
|
@ -101,7 +102,7 @@ impl TraitImpls {
|
||||||
for (_module_id, module_data) in crate_def_map.modules() {
|
for (_module_id, module_data) in crate_def_map.modules() {
|
||||||
for impl_id in module_data.scope.impls() {
|
for impl_id in module_data.scope.impls() {
|
||||||
let target_trait = match db.impl_trait(impl_id) {
|
let target_trait = match db.impl_trait(impl_id) {
|
||||||
Some(tr) => tr.value.trait_,
|
Some(tr) => tr.value.hir_trait_id(),
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
let self_ty = db.impl_self_ty(impl_id);
|
let self_ty = db.impl_self_ty(impl_id);
|
||||||
|
@ -773,7 +774,7 @@ fn generic_implements_goal(
|
||||||
.fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
|
.fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
|
||||||
.build();
|
.build();
|
||||||
kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
|
kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
|
||||||
let trait_ref = TraitRef { trait_, substs };
|
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
|
||||||
let obligation = super::Obligation::Trait(trait_ref);
|
let obligation = super::Obligation::Trait(trait_ref);
|
||||||
Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
|
Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ pub(crate) fn trait_solve_query(
|
||||||
goal: Canonical<InEnvironment<Obligation>>,
|
goal: Canonical<InEnvironment<Obligation>>,
|
||||||
) -> Option<Solution> {
|
) -> Option<Solution> {
|
||||||
let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
|
let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
|
||||||
Obligation::Trait(it) => db.trait_data(it.trait_).name.to_string(),
|
Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(),
|
||||||
Obligation::Projection(_) => "projection".to_string(),
|
Obligation::Projection(_) => "projection".to_string(),
|
||||||
});
|
});
|
||||||
log::info!("trait_solve_query({})", goal.value.value.display(db));
|
log::info!("trait_solve_query({})", goal.value.value.display(db));
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::{
|
||||||
display::HirDisplay,
|
display::HirDisplay,
|
||||||
from_assoc_type_id,
|
from_assoc_type_id,
|
||||||
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
|
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
|
||||||
to_assoc_type_id,
|
to_assoc_type_id, to_chalk_trait_id,
|
||||||
utils::generics,
|
utils::generics,
|
||||||
BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
|
BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
|
||||||
ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
|
ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
|
||||||
|
@ -219,9 +219,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
||||||
// for<T> <Self> [Future<Self>, Future::Output<Self> = T]
|
// for<T> <Self> [Future<Self>, Future::Output<Self> = T]
|
||||||
// ^1 ^0 ^0 ^0 ^1
|
// ^1 ^0 ^0 ^0 ^1
|
||||||
let impl_bound = GenericPredicate::Implemented(TraitRef {
|
let impl_bound = GenericPredicate::Implemented(TraitRef {
|
||||||
trait_: future_trait,
|
trait_id: to_chalk_trait_id(future_trait),
|
||||||
// Self type as the first parameter.
|
// Self type as the first parameter.
|
||||||
substs: Substitution::single(
|
substitution: Substitution::single(
|
||||||
TyKind::BoundVar(BoundVar {
|
TyKind::BoundVar(BoundVar {
|
||||||
debruijn: DebruijnIndex::INNERMOST,
|
debruijn: DebruijnIndex::INNERMOST,
|
||||||
index: 0,
|
index: 0,
|
||||||
|
@ -546,7 +546,7 @@ fn impl_def_datum(
|
||||||
|
|
||||||
let generic_params = generics(db.upcast(), impl_id.into());
|
let generic_params = generics(db.upcast(), impl_id.into());
|
||||||
let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
|
let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
|
||||||
let trait_ = trait_ref.trait_;
|
let trait_ = trait_ref.hir_trait_id();
|
||||||
let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
|
let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
|
||||||
rust_ir::ImplType::Local
|
rust_ir::ImplType::Local
|
||||||
} else {
|
} else {
|
||||||
|
@ -614,7 +614,7 @@ fn type_alias_associated_ty_value(
|
||||||
let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
|
let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
|
||||||
|
|
||||||
let assoc_ty = db
|
let assoc_ty = db
|
||||||
.trait_data(trait_ref.trait_)
|
.trait_data(trait_ref.hir_trait_id())
|
||||||
.associated_type_by_name(&type_alias_data.name)
|
.associated_type_by_name(&type_alias_data.name)
|
||||||
.expect("assoc ty value should not exist"); // validated when building the impl data as well
|
.expect("assoc ty value should not exist"); // validated when building the impl data as well
|
||||||
let ty = db.ty(type_alias.into());
|
let ty = db.ty(type_alias.into());
|
||||||
|
|
|
@ -239,15 +239,15 @@ impl ToChalk for TraitRef {
|
||||||
type Chalk = chalk_ir::TraitRef<Interner>;
|
type Chalk = chalk_ir::TraitRef<Interner>;
|
||||||
|
|
||||||
fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
|
fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
|
||||||
let trait_id = self.trait_.to_chalk(db);
|
let trait_id = self.trait_id;
|
||||||
let substitution = self.substs.to_chalk(db);
|
let substitution = self.substitution.to_chalk(db);
|
||||||
chalk_ir::TraitRef { trait_id, substitution }
|
chalk_ir::TraitRef { trait_id, substitution }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
|
fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
|
||||||
let trait_ = from_chalk(db, trait_ref.trait_id);
|
let trait_id = trait_ref.trait_id;
|
||||||
let substs = from_chalk(db, trait_ref.substitution);
|
let substs = from_chalk(db, trait_ref.substitution);
|
||||||
TraitRef { trait_, substs }
|
TraitRef { trait_id, substitution: substs }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,17 +515,16 @@ pub(super) fn generic_predicate_to_inline_bound(
|
||||||
// We don't have a special type for this, but Chalk does.
|
// We don't have a special type for this, but Chalk does.
|
||||||
match pred {
|
match pred {
|
||||||
GenericPredicate::Implemented(trait_ref) => {
|
GenericPredicate::Implemented(trait_ref) => {
|
||||||
if &trait_ref.substs[0] != self_ty {
|
if &trait_ref.substitution[0] != self_ty {
|
||||||
// we can only convert predicates back to type bounds if they
|
// we can only convert predicates back to type bounds if they
|
||||||
// have the expected self type
|
// have the expected self type
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let args_no_self = trait_ref.substs[1..]
|
let args_no_self = trait_ref.substitution[1..]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| ty.clone().to_chalk(db).cast(&Interner))
|
.map(|ty| ty.clone().to_chalk(db).cast(&Interner))
|
||||||
.collect();
|
.collect();
|
||||||
let trait_bound =
|
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
|
||||||
rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self };
|
|
||||||
Some(rust_ir::InlineBound::TraitBound(trait_bound))
|
Some(rust_ir::InlineBound::TraitBound(trait_bound))
|
||||||
}
|
}
|
||||||
GenericPredicate::Projection(proj) => {
|
GenericPredicate::Projection(proj) => {
|
||||||
|
|
|
@ -55,9 +55,9 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
|
||||||
// lifetime problems, but since there usually shouldn't be more than a
|
// lifetime problems, but since there usually shouldn't be more than a
|
||||||
// few direct traits this should be fine (we could even use some kind of
|
// few direct traits this should be fine (we could even use some kind of
|
||||||
// SmallVec if performance is a concern)
|
// SmallVec if performance is a concern)
|
||||||
let generic_params = db.generic_params(trait_ref.trait_.into());
|
let generic_params = db.generic_params(trait_ref.hir_trait_id().into());
|
||||||
let trait_self = match generic_params.find_trait_self_param() {
|
let trait_self = match generic_params.find_trait_self_param() {
|
||||||
Some(p) => TypeParamId { parent: trait_ref.trait_.into(), local_id: p },
|
Some(p) => TypeParamId { parent: trait_ref.hir_trait_id().into(), local_id: p },
|
||||||
None => return Vec::new(),
|
None => return Vec::new(),
|
||||||
};
|
};
|
||||||
db.generic_predicates_for_param(trait_self)
|
db.generic_predicates_for_param(trait_self)
|
||||||
|
@ -68,7 +68,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map(|pred| pred.subst(&trait_ref.substs))
|
.map(|pred| pred.subst(&trait_ref.substitution))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) ->
|
||||||
// yeah this is quadratic, but trait hierarchies should be flat
|
// yeah this is quadratic, but trait hierarchies should be flat
|
||||||
// enough that this doesn't matter
|
// enough that this doesn't matter
|
||||||
for tt in direct_super_trait_refs(db, t) {
|
for tt in direct_super_trait_refs(db, t) {
|
||||||
if !result.iter().any(|tr| tr.trait_ == tt.trait_) {
|
if !result.iter().any(|tr| tr.trait_id == tt.trait_id) {
|
||||||
result.push(tt);
|
result.push(tt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ pub(super) fn associated_type_by_name_including_super_traits(
|
||||||
name: &Name,
|
name: &Name,
|
||||||
) -> Option<(TraitRef, TypeAliasId)> {
|
) -> Option<(TraitRef, TypeAliasId)> {
|
||||||
all_super_trait_refs(db, trait_ref).into_iter().find_map(|t| {
|
all_super_trait_refs(db, trait_ref).into_iter().find_map(|t| {
|
||||||
let assoc_type = db.trait_data(t.trait_).associated_type_by_name(name)?;
|
let assoc_type = db.trait_data(t.hir_trait_id()).associated_type_by_name(name)?;
|
||||||
Some((t, assoc_type))
|
Some((t, assoc_type))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue