mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
Merge #8309
8309: Introduce `GenericArg` like in Chalk r=flodiebold a=flodiebold Plus some more adaptations to Substitution. Lots of `assert_ty_ref` that we should revisit when introducing lifetime/const parameters. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
8289b96216
17 changed files with 323 additions and 161 deletions
|
@ -1829,9 +1829,11 @@ impl Type {
|
|||
);
|
||||
|
||||
match db.trait_solve(self.krate, goal)? {
|
||||
Solution::Unique(SolutionVariables(subst)) => {
|
||||
subst.value.first().map(|ty| self.derived(ty.clone()))
|
||||
}
|
||||
Solution::Unique(SolutionVariables(subst)) => subst
|
||||
.value
|
||||
.interned(&Interner)
|
||||
.first()
|
||||
.map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),
|
||||
Solution::Ambig(_) => None,
|
||||
}
|
||||
}
|
||||
|
@ -1889,7 +1891,9 @@ impl Type {
|
|||
| TyKind::Tuple(_, substs)
|
||||
| TyKind::OpaqueType(_, substs)
|
||||
| TyKind::FnDef(_, substs)
|
||||
| TyKind::Closure(_, substs) => substs.iter().any(go),
|
||||
| TyKind::Closure(_, substs) => {
|
||||
substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
|
||||
}
|
||||
|
||||
TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
|
||||
go(ty)
|
||||
|
@ -1928,7 +1932,10 @@ impl Type {
|
|||
|
||||
pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
|
||||
if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
|
||||
substs.iter().map(|ty| self.derived(ty.clone())).collect()
|
||||
substs
|
||||
.iter(&Interner)
|
||||
.map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone()))
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
|
@ -1973,8 +1980,9 @@ impl Type {
|
|||
.strip_references()
|
||||
.substs()
|
||||
.into_iter()
|
||||
.flat_map(|substs| substs.iter())
|
||||
.map(move |ty| self.derived(ty.clone()))
|
||||
.flat_map(|substs| substs.iter(&Interner))
|
||||
.filter_map(|arg| arg.ty(&Interner).cloned())
|
||||
.map(move |ty| self.derived(ty))
|
||||
}
|
||||
|
||||
pub fn iterate_method_candidates<T>(
|
||||
|
@ -2080,7 +2088,7 @@ impl Type {
|
|||
substs: &Substitution,
|
||||
cb: &mut impl FnMut(Type),
|
||||
) {
|
||||
for ty in substs.iter() {
|
||||
for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) {
|
||||
walk_type(db, &type_.derived(ty.clone()), cb);
|
||||
}
|
||||
}
|
||||
|
@ -2096,7 +2104,12 @@ impl Type {
|
|||
WhereClause::Implemented(trait_ref) => {
|
||||
cb(type_.clone());
|
||||
// skip the self type. it's likely the type we just got the bounds from
|
||||
for ty in trait_ref.substitution.iter().skip(1) {
|
||||
for ty in trait_ref
|
||||
.substitution
|
||||
.iter(&Interner)
|
||||
.skip(1)
|
||||
.filter_map(|a| a.ty(&Interner))
|
||||
{
|
||||
walk_type(db, &type_.derived(ty.clone()), cb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ fn deref_by_trait(
|
|||
// new variables in that case
|
||||
|
||||
for i in 1..vars.0.binders.len(&Interner) {
|
||||
if vars.0.value[i - 1].interned(&Interner)
|
||||
if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).interned(&Interner)
|
||||
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
|
||||
{
|
||||
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
|
||||
|
@ -139,7 +139,12 @@ fn deref_by_trait(
|
|||
}
|
||||
}
|
||||
Some(Canonical {
|
||||
value: vars.0.value[vars.0.value.len() - 1].clone(),
|
||||
value: vars
|
||||
.0
|
||||
.value
|
||||
.at(&Interner, vars.0.value.len(&Interner) - 1)
|
||||
.assert_ty_ref(&Interner)
|
||||
.clone(),
|
||||
binders: vars.0.binders.clone(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use chalk_ir::{
|
|||
interner::HasInterner,
|
||||
};
|
||||
|
||||
use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
|
||||
use crate::{AliasEq, DomainGoal, GenericArg, GenericArgData, Interner, TraitRef, Ty, WhereClause};
|
||||
|
||||
macro_rules! has_interner {
|
||||
($t:ty) => {
|
||||
|
@ -17,6 +17,8 @@ macro_rules! has_interner {
|
|||
|
||||
has_interner!(WhereClause);
|
||||
has_interner!(DomainGoal);
|
||||
has_interner!(GenericArg);
|
||||
has_interner!(Ty);
|
||||
|
||||
impl CastTo<WhereClause> for TraitRef {
|
||||
fn cast_to(self, _interner: &Interner) -> WhereClause {
|
||||
|
@ -36,6 +38,12 @@ impl CastTo<DomainGoal> for WhereClause {
|
|||
}
|
||||
}
|
||||
|
||||
impl CastTo<GenericArg> for Ty {
|
||||
fn cast_to(self, interner: &Interner) -> GenericArg {
|
||||
GenericArg::new(interner, GenericArgData::Ty(self))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! transitive_impl {
|
||||
($a:ty, $b:ty, $c:ty) => {
|
||||
impl CastTo<$c> for $a {
|
||||
|
@ -51,3 +59,15 @@ macro_rules! transitive_impl {
|
|||
|
||||
transitive_impl!(TraitRef, WhereClause, DomainGoal);
|
||||
transitive_impl!(AliasEq, WhereClause, DomainGoal);
|
||||
|
||||
macro_rules! reflexive_impl {
|
||||
($a:ty) => {
|
||||
impl CastTo<$a> for $a {
|
||||
fn cast_to(self, _interner: &Interner) -> $a {
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
reflexive_impl!(GenericArg);
|
||||
|
|
|
@ -392,7 +392,9 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
_ => return,
|
||||
};
|
||||
|
||||
if params.len() > 0 && params[0] == mismatch.actual {
|
||||
if params.len(&Interner) > 0
|
||||
&& params.at(&Interner, 0).ty(&Interner) == Some(&mismatch.actual)
|
||||
{
|
||||
let (_, source_map) = db.body_with_source_map(self.owner);
|
||||
|
||||
if let Ok(source_ptr) = source_map.expr_syntax(id) {
|
||||
|
|
|
@ -792,7 +792,10 @@ fn pat_constructor(cx: &MatchCheckCtx, pat: PatIdOrWild) -> MatchCheckResult<Opt
|
|||
Pat::Tuple { .. } => {
|
||||
let pat_id = pat.as_id().expect("we already know this pattern is not a wild");
|
||||
Some(Constructor::Tuple {
|
||||
arity: cx.infer.type_of_pat[pat_id].as_tuple().ok_or(MatchCheckErr::Unknown)?.len(),
|
||||
arity: cx.infer.type_of_pat[pat_id]
|
||||
.as_tuple()
|
||||
.ok_or(MatchCheckErr::Unknown)?
|
||||
.len(&Interner),
|
||||
})
|
||||
}
|
||||
Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] {
|
||||
|
|
|
@ -8,7 +8,7 @@ use hir_def::{
|
|||
find_path,
|
||||
generics::TypeParamProvenance,
|
||||
item_scope::ItemInNs,
|
||||
path::{GenericArg, Path, PathKind},
|
||||
path::{Path, PathKind},
|
||||
type_ref::{TypeBound, TypeRef},
|
||||
visibility::Visibility,
|
||||
AssocContainerId, Lookup, ModuleId, TraitId,
|
||||
|
@ -18,7 +18,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, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
|
||||
CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy,
|
||||
ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
|
@ -251,16 +251,16 @@ impl HirDisplay for ProjectionTy {
|
|||
}
|
||||
|
||||
let trait_ = f.db.trait_data(self.trait_(f.db));
|
||||
let first_parameter = self.substitution[0].into_displayable(
|
||||
let first_parameter = self.self_type_parameter().into_displayable(
|
||||
f.db,
|
||||
f.max_size,
|
||||
f.omit_verbose_types,
|
||||
f.display_target,
|
||||
);
|
||||
write!(f, "<{} as {}", first_parameter, trait_.name)?;
|
||||
if self.substitution.len() > 1 {
|
||||
if self.substitution.len(&Interner) > 1 {
|
||||
write!(f, "<")?;
|
||||
f.write_joined(&self.substitution[1..], ", ")?;
|
||||
f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
|
||||
|
@ -274,7 +274,15 @@ impl HirDisplay for OpaqueTy {
|
|||
return write!(f, "{}", TYPE_HINT_TRUNCATION);
|
||||
}
|
||||
|
||||
self.substitution[0].hir_fmt(f)
|
||||
self.substitution.at(&Interner, 0).hir_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for GenericArg {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
match self.interned() {
|
||||
crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,9 +381,9 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
}
|
||||
TyKind::Tuple(_, substs) => {
|
||||
if substs.len() == 1 {
|
||||
if substs.len(&Interner) == 1 {
|
||||
write!(f, "(")?;
|
||||
substs[0].hir_fmt(f)?;
|
||||
substs.at(&Interner, 0).hir_fmt(f)?;
|
||||
write!(f, ",)")?;
|
||||
} else {
|
||||
write!(f, "(")?;
|
||||
|
@ -399,7 +407,7 @@ impl HirDisplay for Ty {
|
|||
write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
|
||||
}
|
||||
};
|
||||
if parameters.len() > 0 {
|
||||
if parameters.len(&Interner) > 0 {
|
||||
let generics = generics(f.db.upcast(), def.into());
|
||||
let (parent_params, self_param, type_params, _impl_trait_params) =
|
||||
generics.provenance_split();
|
||||
|
@ -451,7 +459,7 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
}
|
||||
|
||||
if parameters.len() > 0 {
|
||||
if parameters.len(&Interner) > 0 {
|
||||
let parameters_to_write = if f.display_target.is_source_code()
|
||||
|| f.omit_verbose_types()
|
||||
{
|
||||
|
@ -463,9 +471,11 @@ impl HirDisplay for Ty {
|
|||
None => parameters.0.as_ref(),
|
||||
Some(default_parameters) => {
|
||||
let mut default_from = 0;
|
||||
for (i, parameter) in parameters.iter().enumerate() {
|
||||
match (parameter.interned(&Interner), default_parameters.get(i))
|
||||
{
|
||||
for (i, parameter) in parameters.iter(&Interner).enumerate() {
|
||||
match (
|
||||
parameter.assert_ty_ref(&Interner).interned(&Interner),
|
||||
default_parameters.get(i),
|
||||
) {
|
||||
(&TyKind::Unknown, _) | (_, None) => {
|
||||
default_from = i + 1;
|
||||
}
|
||||
|
@ -473,7 +483,8 @@ impl HirDisplay for Ty {
|
|||
let actual_default = default_parameter
|
||||
.clone()
|
||||
.subst(¶meters.prefix(i));
|
||||
if parameter != &actual_default {
|
||||
if parameter.assert_ty_ref(&Interner) != &actual_default
|
||||
{
|
||||
default_from = i + 1;
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +515,7 @@ impl HirDisplay for Ty {
|
|||
// 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() {
|
||||
write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
|
||||
if parameters.len() > 0 {
|
||||
if parameters.len(&Interner) > 0 {
|
||||
write!(f, "<")?;
|
||||
f.write_joined(&*parameters.0, ", ")?;
|
||||
write!(f, ">")?;
|
||||
|
@ -537,7 +548,7 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
|
||||
write!(f, "impl Future<Output = ")?;
|
||||
parameters[0].hir_fmt(f)?;
|
||||
parameters.at(&Interner, 0).hir_fmt(f)?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
}
|
||||
|
@ -548,7 +559,7 @@ impl HirDisplay for Ty {
|
|||
DisplaySourceCodeError::Closure,
|
||||
));
|
||||
}
|
||||
let sig = substs[0].callable_sig(f.db);
|
||||
let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db);
|
||||
if let Some(sig) = sig {
|
||||
if sig.params().is_empty() {
|
||||
write!(f, "||")?;
|
||||
|
@ -718,7 +729,9 @@ fn write_bounds_like_dyn_trait(
|
|||
write!(f, "{}", f.db.trait_data(trait_).name)?;
|
||||
if let [_, params @ ..] = &*trait_ref.substitution.0 {
|
||||
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.assert_ty_ref(&Interner).as_tuple())
|
||||
{
|
||||
write!(f, "(")?;
|
||||
f.write_joined(&*args.0, ", ")?;
|
||||
write!(f, ")")?;
|
||||
|
@ -767,16 +780,16 @@ impl TraitRef {
|
|||
return write!(f, "{}", TYPE_HINT_TRUNCATION);
|
||||
}
|
||||
|
||||
self.substitution[0].hir_fmt(f)?;
|
||||
self.self_type_parameter().hir_fmt(f)?;
|
||||
if use_as {
|
||||
write!(f, " as ")?;
|
||||
} else {
|
||||
write!(f, ": ")?;
|
||||
}
|
||||
write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
|
||||
if self.substitution.len() > 1 {
|
||||
if self.substitution.len(&Interner) > 1 {
|
||||
write!(f, "<")?;
|
||||
f.write_joined(&self.substitution[1..], ", ")?;
|
||||
f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -1016,11 +1029,11 @@ impl HirDisplay for Path {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for GenericArg {
|
||||
impl HirDisplay for hir_def::path::GenericArg {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
GenericArg::Type(ty) => ty.hir_fmt(f),
|
||||
GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
|
||||
hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
|
||||
hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ impl<'a> InferenceContext<'a> {
|
|||
},
|
||||
|
||||
(TyKind::Closure(.., substs), TyKind::Function { .. }) => {
|
||||
from_ty = substs[0].clone();
|
||||
from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
|
|
@ -266,7 +266,7 @@ impl<'a> InferenceContext<'a> {
|
|||
let sig_ty = TyKind::Function(FnPointer {
|
||||
num_args: sig_tys.len() - 1,
|
||||
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
|
||||
substs: Substitution(sig_tys.clone().into()),
|
||||
substs: Substitution::from_iter(&Interner, sig_tys.clone()),
|
||||
})
|
||||
.intern(&Interner);
|
||||
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
|
||||
|
@ -406,7 +406,7 @@ impl<'a> InferenceContext<'a> {
|
|||
|
||||
self.unify(&ty, &expected.ty);
|
||||
|
||||
let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty);
|
||||
let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
|
||||
let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
|
||||
let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
|
||||
for field in fields.iter() {
|
||||
|
@ -456,9 +456,13 @@ impl<'a> InferenceContext<'a> {
|
|||
.unwrap_or(true)
|
||||
};
|
||||
match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
|
||||
TyKind::Tuple(_, substs) => {
|
||||
name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
|
||||
}
|
||||
TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
|
||||
substs
|
||||
.interned(&Interner)
|
||||
.get(idx)
|
||||
.map(|a| a.assert_ty_ref(&Interner))
|
||||
.cloned()
|
||||
}),
|
||||
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
|
||||
let local_id = self.db.struct_data(*s).variant_data.field(name)?;
|
||||
let field = FieldId { parent: (*s).into(), local_id };
|
||||
|
@ -635,7 +639,7 @@ impl<'a> InferenceContext<'a> {
|
|||
let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
|
||||
match (range_type, lhs_ty, rhs_ty) {
|
||||
(RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
|
||||
Some(adt) => Ty::adt_ty(adt, Substitution::empty()),
|
||||
Some(adt) => Ty::adt_ty(adt, Substitution::empty(&Interner)),
|
||||
None => self.err_ty(),
|
||||
},
|
||||
(RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
|
||||
|
@ -694,8 +698,8 @@ impl<'a> InferenceContext<'a> {
|
|||
Expr::Tuple { exprs } => {
|
||||
let mut tys = match expected.ty.interned(&Interner) {
|
||||
TyKind::Tuple(_, substs) => substs
|
||||
.iter()
|
||||
.cloned()
|
||||
.iter(&Interner)
|
||||
.map(|a| a.assert_ty_ref(&Interner).clone())
|
||||
.chain(repeat_with(|| self.table.new_type_var()))
|
||||
.take(exprs.len())
|
||||
.collect::<Vec<_>>(),
|
||||
|
@ -706,7 +710,7 @@ impl<'a> InferenceContext<'a> {
|
|||
self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
|
||||
}
|
||||
|
||||
TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner)
|
||||
TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
|
||||
}
|
||||
Expr::Array(array) => {
|
||||
let elem_ty = match expected.ty.interned(&Interner) {
|
||||
|
@ -953,7 +957,7 @@ impl<'a> InferenceContext<'a> {
|
|||
substs.push(self.err_ty());
|
||||
}
|
||||
assert_eq!(substs.len(), total_len);
|
||||
Substitution(substs.into())
|
||||
Substitution::from_iter(&Interner, substs)
|
||||
}
|
||||
|
||||
fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
|
||||
|
|
|
@ -35,7 +35,7 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
self.unify(&ty, expected);
|
||||
|
||||
let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty);
|
||||
let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
|
||||
|
||||
let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
|
||||
let (pre, post) = match ellipsis {
|
||||
|
@ -74,7 +74,7 @@ impl<'a> InferenceContext<'a> {
|
|||
|
||||
self.unify(&ty, expected);
|
||||
|
||||
let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty);
|
||||
let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
|
||||
|
||||
let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
|
||||
for subpat in subpats {
|
||||
|
@ -134,7 +134,8 @@ impl<'a> InferenceContext<'a> {
|
|||
};
|
||||
let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
|
||||
let err_ty = self.err_ty();
|
||||
let mut expectations_iter = expectations.iter().chain(repeat(&err_ty));
|
||||
let mut expectations_iter =
|
||||
expectations.iter().map(|a| a.assert_ty_ref(&Interner)).chain(repeat(&err_ty));
|
||||
let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
|
||||
|
||||
let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
|
||||
|
@ -142,7 +143,8 @@ impl<'a> InferenceContext<'a> {
|
|||
inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
|
||||
inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
|
||||
|
||||
TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner)
|
||||
TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
|
||||
.intern(&Interner)
|
||||
}
|
||||
Pat::Or(ref pats) => {
|
||||
if let Some((first_pat, rest)) = pats.split_first() {
|
||||
|
@ -236,9 +238,10 @@ impl<'a> InferenceContext<'a> {
|
|||
Pat::Box { inner } => match self.resolve_boxed_box() {
|
||||
Some(box_adt) => {
|
||||
let (inner_ty, alloc_ty) = match expected.as_adt() {
|
||||
Some((adt, subst)) if adt == box_adt => {
|
||||
(subst[0].clone(), subst.get(1).cloned())
|
||||
}
|
||||
Some((adt, subst)) if adt == box_adt => (
|
||||
subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
|
||||
subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
|
||||
),
|
||||
_ => (self.result.standard_types.unknown.clone(), None),
|
||||
};
|
||||
|
||||
|
|
|
@ -97,12 +97,12 @@ impl<'a> InferenceContext<'a> {
|
|||
|
||||
let ty = self.db.value_ty(typable);
|
||||
// self_subst is just for the parent
|
||||
let parent_substs = self_subst.unwrap_or_else(Substitution::empty);
|
||||
let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner));
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
||||
let substs = ctx.substs_from_path(path, typable, true);
|
||||
let full_substs = Substitution::builder(substs.len())
|
||||
let full_substs = Substitution::builder(substs.len(&Interner))
|
||||
.use_parent_substs(&parent_substs)
|
||||
.fill(substs.0[parent_substs.len()..].iter().cloned())
|
||||
.fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
|
||||
.build();
|
||||
let ty = ty.subst(&full_substs);
|
||||
Some(ty)
|
||||
|
|
|
@ -129,29 +129,28 @@ impl<T> Canonicalized<T> {
|
|||
solution: Canonical<Substitution>,
|
||||
) {
|
||||
// the solution may contain new variables, which we need to convert to new inference vars
|
||||
let new_vars = Substitution(
|
||||
solution
|
||||
.binders
|
||||
.iter(&Interner)
|
||||
.map(|k| match k.kind {
|
||||
VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
|
||||
VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
|
||||
VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
|
||||
// HACK: Chalk can sometimes return new lifetime variables. We
|
||||
// want to just skip them, but to not mess up the indices of
|
||||
// other variables, we'll just create a new type variable in
|
||||
// their place instead. This should not matter (we never see the
|
||||
// actual *uses* of the lifetime variable).
|
||||
VariableKind::Lifetime => ctx.table.new_type_var(),
|
||||
_ => panic!("const variable in solution"),
|
||||
})
|
||||
.collect(),
|
||||
let new_vars = Substitution::from_iter(
|
||||
&Interner,
|
||||
solution.binders.iter(&Interner).map(|k| match k.kind {
|
||||
VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
|
||||
VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
|
||||
VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
|
||||
// HACK: Chalk can sometimes return new lifetime variables. We
|
||||
// want to just skip them, but to not mess up the indices of
|
||||
// other variables, we'll just create a new type variable in
|
||||
// their place instead. This should not matter (we never see the
|
||||
// actual *uses* of the lifetime variable).
|
||||
VariableKind::Lifetime => ctx.table.new_type_var(),
|
||||
_ => panic!("const variable in solution"),
|
||||
}),
|
||||
);
|
||||
for (i, ty) in solution.value.into_iter().enumerate() {
|
||||
for (i, ty) in solution.value.iter(&Interner).enumerate() {
|
||||
let (v, k) = self.free_vars[i];
|
||||
// eagerly replace projections in the type; we may be getting types
|
||||
// e.g. from where clauses where this hasn't happened yet
|
||||
let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
|
||||
let ty = ctx.normalize_associated_types_in(
|
||||
ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars),
|
||||
);
|
||||
ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
|
||||
}
|
||||
}
|
||||
|
@ -163,13 +162,13 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
|
|||
|
||||
pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
|
||||
let mut table = InferenceTable::new();
|
||||
let vars = Substitution(
|
||||
let vars = Substitution::from_iter(
|
||||
&Interner,
|
||||
tys.binders
|
||||
.iter(&Interner)
|
||||
// we always use type vars here because we want everything to
|
||||
// fallback to Unknown in the end (kind of hacky, as below)
|
||||
.map(|_| table.new_type_var())
|
||||
.collect(),
|
||||
.map(|_| table.new_type_var()),
|
||||
);
|
||||
let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars);
|
||||
let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars);
|
||||
|
@ -178,7 +177,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
|
|||
}
|
||||
// default any type vars that weren't unified back to their original bound vars
|
||||
// (kind of hacky)
|
||||
for (i, var) in vars.iter().enumerate() {
|
||||
for (i, var) in vars.iter(&Interner).enumerate() {
|
||||
let var = var.assert_ty_ref(&Interner);
|
||||
if &*table.resolve_ty_shallow(var) == var {
|
||||
table.unify(
|
||||
var,
|
||||
|
@ -188,7 +188,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
|
|||
}
|
||||
Some(
|
||||
Substitution::builder(tys.binders.len(&Interner))
|
||||
.fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))
|
||||
.fill(
|
||||
vars.iter(&Interner)
|
||||
.map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
|
@ -284,7 +287,9 @@ impl InferenceTable {
|
|||
substs2: &Substitution,
|
||||
depth: usize,
|
||||
) -> bool {
|
||||
substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth))
|
||||
substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| {
|
||||
self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
|
||||
})
|
||||
}
|
||||
|
||||
fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
|
||||
|
|
|
@ -24,9 +24,10 @@ mod tests;
|
|||
#[cfg(test)]
|
||||
mod test_db;
|
||||
|
||||
use std::{iter, mem, ops::Deref, sync::Arc};
|
||||
use std::{iter, mem, sync::Arc};
|
||||
|
||||
use base_db::salsa;
|
||||
use chalk_ir::cast::{CastTo, Caster};
|
||||
use hir_def::{
|
||||
builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId,
|
||||
GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
|
||||
|
@ -109,7 +110,7 @@ impl ProjectionTy {
|
|||
}
|
||||
|
||||
pub fn self_type_parameter(&self) -> &Ty {
|
||||
&self.substitution[0]
|
||||
&self.substitution.interned(&Interner)[0].assert_ty_ref(&Interner)
|
||||
}
|
||||
|
||||
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
|
||||
|
@ -324,9 +325,72 @@ impl Ty {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct GenericArg {
|
||||
interned: GenericArgData,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericArgData {
|
||||
Ty(Ty),
|
||||
}
|
||||
|
||||
impl GenericArg {
|
||||
/// Constructs a generic argument using `GenericArgData`.
|
||||
pub fn new(_interner: &Interner, data: GenericArgData) -> Self {
|
||||
GenericArg { interned: data }
|
||||
}
|
||||
|
||||
/// Gets the interned value.
|
||||
pub fn interned(&self) -> &GenericArgData {
|
||||
&self.interned
|
||||
}
|
||||
|
||||
/// Asserts that this is a type argument.
|
||||
pub fn assert_ty_ref(&self, interner: &Interner) -> &Ty {
|
||||
self.ty(interner).unwrap()
|
||||
}
|
||||
|
||||
/// Checks whether the generic argument is a type.
|
||||
pub fn is_ty(&self, _interner: &Interner) -> bool {
|
||||
match self.interned() {
|
||||
GenericArgData::Ty(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the type if it is one, `None` otherwise.
|
||||
pub fn ty(&self, _interner: &Interner) -> Option<&Ty> {
|
||||
match self.interned() {
|
||||
GenericArgData::Ty(t) => Some(t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeWalk for GenericArg {
|
||||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
match &self.interned {
|
||||
GenericArgData::Ty(ty) => {
|
||||
ty.walk(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_mut_binders(
|
||||
&mut self,
|
||||
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
|
||||
binders: DebruijnIndex,
|
||||
) {
|
||||
match &mut self.interned {
|
||||
GenericArgData::Ty(ty) => {
|
||||
ty.walk_mut_binders(f, binders);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of substitutions for generic parameters.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Substitution(SmallVec<[Ty; 2]>);
|
||||
pub struct Substitution(SmallVec<[GenericArg; 2]>);
|
||||
|
||||
impl TypeWalk for Substitution {
|
||||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
|
@ -347,18 +411,34 @@ impl TypeWalk for Substitution {
|
|||
}
|
||||
|
||||
impl Substitution {
|
||||
pub fn interned(&self, _: &Interner) -> &[Ty] {
|
||||
pub fn interned(&self, _: &Interner) -> &[GenericArg] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn empty() -> Substitution {
|
||||
pub fn len(&self, _: &Interner) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self, _: &Interner) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn at(&self, _: &Interner, i: usize) -> &GenericArg {
|
||||
&self.0[i]
|
||||
}
|
||||
|
||||
pub fn empty(_: &Interner) -> Substitution {
|
||||
Substitution(SmallVec::new())
|
||||
}
|
||||
|
||||
pub fn iter(&self, _: &Interner) -> std::slice::Iter<'_, GenericArg> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
pub fn single(ty: Ty) -> Substitution {
|
||||
Substitution({
|
||||
let mut v = SmallVec::new();
|
||||
v.push(ty);
|
||||
v.push(ty.cast(&Interner));
|
||||
v
|
||||
})
|
||||
}
|
||||
|
@ -371,15 +451,11 @@ impl Substitution {
|
|||
Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
|
||||
}
|
||||
|
||||
pub fn as_single(&self) -> &Ty {
|
||||
if self.0.len() != 1 {
|
||||
panic!("expected substs of len 1, got {:?}", self);
|
||||
}
|
||||
&self.0[0]
|
||||
}
|
||||
|
||||
pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
|
||||
Substitution(elements.into_iter().collect())
|
||||
pub fn from_iter(
|
||||
interner: &Interner,
|
||||
elements: impl IntoIterator<Item = impl CastTo<GenericArg>>,
|
||||
) -> Self {
|
||||
Substitution(elements.into_iter().casted(interner).collect())
|
||||
}
|
||||
|
||||
/// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
|
||||
|
@ -387,11 +463,11 @@ impl Substitution {
|
|||
db: &dyn HirDatabase,
|
||||
generic_params: &Generics,
|
||||
) -> Substitution {
|
||||
Substitution(
|
||||
Substitution::from_iter(
|
||||
&Interner,
|
||||
generic_params
|
||||
.iter()
|
||||
.map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner))
|
||||
.collect(),
|
||||
.map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -403,12 +479,12 @@ impl Substitution {
|
|||
|
||||
/// Return Substs that replace each parameter by a bound variable.
|
||||
pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution {
|
||||
Substitution(
|
||||
Substitution::from_iter(
|
||||
&Interner,
|
||||
generic_params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner))
|
||||
.collect(),
|
||||
.map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -435,18 +511,18 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubstsBuilder {
|
||||
vec: Vec<Ty>,
|
||||
vec: Vec<GenericArg>,
|
||||
param_count: usize,
|
||||
}
|
||||
|
||||
impl SubstsBuilder {
|
||||
pub fn build(self) -> Substitution {
|
||||
assert_eq!(self.vec.len(), self.param_count);
|
||||
Substitution(self.vec.into())
|
||||
Substitution::from_iter(&Interner, self.vec)
|
||||
}
|
||||
|
||||
pub fn push(mut self, ty: Ty) -> Self {
|
||||
self.vec.push(ty);
|
||||
pub fn push(mut self, ty: impl CastTo<GenericArg>) -> Self {
|
||||
self.vec.push(ty.cast(&Interner));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -465,28 +541,20 @@ impl SubstsBuilder {
|
|||
self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
|
||||
}
|
||||
|
||||
pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
|
||||
self.vec.extend(filler.take(self.remaining()));
|
||||
pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self {
|
||||
self.vec.extend(filler.take(self.remaining()).casted(&Interner));
|
||||
assert_eq!(self.remaining(), 0);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
|
||||
assert!(self.vec.is_empty());
|
||||
assert!(parent_substs.len() <= self.param_count);
|
||||
self.vec.extend(parent_substs.iter().cloned());
|
||||
assert!(parent_substs.len(&Interner) <= self.param_count);
|
||||
self.vec.extend(parent_substs.iter(&Interner).cloned());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Substitution {
|
||||
type Target = [Ty];
|
||||
|
||||
fn deref(&self) -> &[Ty] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Binders<T> {
|
||||
pub num_binders: usize,
|
||||
|
@ -535,7 +603,7 @@ impl<T: Clone> Binders<&T> {
|
|||
impl<T: TypeWalk> Binders<T> {
|
||||
/// Substitutes all variables.
|
||||
pub fn subst(self, subst: &Substitution) -> T {
|
||||
assert_eq!(subst.len(), self.num_binders);
|
||||
assert_eq!(subst.len(&Interner), self.num_binders);
|
||||
self.value.subst_bound_vars(subst)
|
||||
}
|
||||
}
|
||||
|
@ -563,7 +631,7 @@ pub struct TraitRef {
|
|||
|
||||
impl TraitRef {
|
||||
pub fn self_type_parameter(&self) -> &Ty {
|
||||
&self.substitution[0]
|
||||
&self.substitution.at(&Interner, 0).assert_ty_ref(&Interner)
|
||||
}
|
||||
|
||||
pub fn hir_trait_id(&self) -> TraitId {
|
||||
|
@ -699,14 +767,20 @@ impl CallableSig {
|
|||
.shift_bound_vars_out(DebruijnIndex::ONE)
|
||||
.interned(&Interner)
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|arg| arg.assert_ty_ref(&Interner).clone())
|
||||
.collect(),
|
||||
is_varargs: fn_ptr.sig.variadic,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_substs(substs: &Substitution) -> CallableSig {
|
||||
CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false }
|
||||
CallableSig {
|
||||
params_and_return: substs
|
||||
.iter(&Interner)
|
||||
.map(|arg| arg.assert_ty_ref(&Interner).clone())
|
||||
.collect(),
|
||||
is_varargs: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn params(&self) -> &[Ty] {
|
||||
|
@ -738,7 +812,7 @@ impl TypeWalk for CallableSig {
|
|||
|
||||
impl Ty {
|
||||
pub fn unit() -> Self {
|
||||
TyKind::Tuple(0, Substitution::empty()).intern(&Interner)
|
||||
TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner)
|
||||
}
|
||||
|
||||
pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
|
||||
|
@ -908,7 +982,7 @@ impl Ty {
|
|||
Some(sig.subst(¶meters))
|
||||
}
|
||||
TyKind::Closure(.., substs) => {
|
||||
let sig_param = &substs[0];
|
||||
let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
|
||||
sig_param.callable_sig(db)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -960,7 +1034,7 @@ impl Ty {
|
|||
0,
|
||||
WhereClause::Implemented(TraitRef {
|
||||
trait_id: to_chalk_trait_id(future_trait),
|
||||
substitution: Substitution::empty(),
|
||||
substitution: Substitution::empty(&Interner),
|
||||
}),
|
||||
);
|
||||
Some(vec![impl_bound])
|
||||
|
@ -1109,7 +1183,10 @@ pub trait TypeWalk {
|
|||
&mut |ty, binders| {
|
||||
if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
|
||||
if bound.debruijn >= binders {
|
||||
*ty = substs.0[bound.index].clone().shift_bound_vars(binders);
|
||||
*ty = substs.0[bound.index]
|
||||
.assert_ty_ref(&Interner)
|
||||
.clone()
|
||||
.shift_bound_vars(binders);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1156,12 +1233,12 @@ impl TypeWalk for Ty {
|
|||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
match self.interned(&Interner) {
|
||||
TyKind::Alias(AliasTy::Projection(p_ty)) => {
|
||||
for t in p_ty.substitution.iter() {
|
||||
for t in p_ty.substitution.iter(&Interner) {
|
||||
t.walk(f);
|
||||
}
|
||||
}
|
||||
TyKind::Alias(AliasTy::Opaque(o_ty)) => {
|
||||
for t in o_ty.substitution.iter() {
|
||||
for t in o_ty.substitution.iter(&Interner) {
|
||||
t.walk(f);
|
||||
}
|
||||
}
|
||||
|
@ -1175,7 +1252,7 @@ impl TypeWalk for Ty {
|
|||
}
|
||||
_ => {
|
||||
if let Some(substs) = self.substs() {
|
||||
for t in substs.iter() {
|
||||
for t in substs.iter(&Interner) {
|
||||
t.walk(f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,9 +178,10 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
|
||||
TypeRef::Fn(params, is_varargs) => {
|
||||
let substs = Substitution(params.iter().map(|tr| self.lower_ty(tr)).collect());
|
||||
let substs =
|
||||
Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
|
||||
TyKind::Function(FnPointer {
|
||||
num_args: substs.len() - 1,
|
||||
num_args: substs.len(&Interner) - 1,
|
||||
sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
|
||||
substs,
|
||||
})
|
||||
|
@ -625,7 +626,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
|
||||
for default_ty in defaults.iter().skip(substs.len()) {
|
||||
// each default can depend on the previous parameters
|
||||
let substs_so_far = Substitution(substs.clone().into());
|
||||
let substs_so_far = Substitution::from_iter(&Interner, substs.clone());
|
||||
substs.push(default_ty.clone().subst(&substs_so_far));
|
||||
}
|
||||
}
|
||||
|
@ -638,7 +639,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
assert_eq!(substs.len(), total_len);
|
||||
|
||||
Substitution(substs.into())
|
||||
Substitution::from_iter(&Interner, substs)
|
||||
}
|
||||
|
||||
fn lower_trait_ref_from_path(
|
||||
|
@ -1062,7 +1063,7 @@ fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
|
|||
let generics = generics(db.upcast(), def.into());
|
||||
let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
|
||||
Binders::new(
|
||||
substs.len(),
|
||||
substs.len(&Interner),
|
||||
TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
|
||||
)
|
||||
}
|
||||
|
@ -1107,7 +1108,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
|
|||
let generics = generics(db.upcast(), def.into());
|
||||
let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
|
||||
Binders::new(
|
||||
substs.len(),
|
||||
substs.len(&Interner),
|
||||
TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
|
||||
)
|
||||
}
|
||||
|
@ -1134,7 +1135,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
|
|||
let generics = generics(db.upcast(), def.parent.into());
|
||||
let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
|
||||
Binders::new(
|
||||
substs.len(),
|
||||
substs.len(&Interner),
|
||||
TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
|
||||
)
|
||||
}
|
||||
|
@ -1142,7 +1143,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
|
|||
fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
|
||||
let generics = generics(db.upcast(), adt.into());
|
||||
let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
|
||||
Binders::new(substs.len(), Ty::adt_ty(adt, substs))
|
||||
Binders::new(substs.len(&Interner), Ty::adt_ty(adt, substs))
|
||||
}
|
||||
|
||||
fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
|
||||
|
|
|
@ -720,7 +720,7 @@ pub(crate) fn inherent_impl_substs(
|
|||
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
|
||||
UniverseIndex::ROOT,
|
||||
))
|
||||
.take(vars.len()),
|
||||
.take(vars.len(&Interner)),
|
||||
);
|
||||
let tys = Canonical {
|
||||
binders: CanonicalVarKinds::from_iter(&Interner, kinds),
|
||||
|
@ -732,7 +732,8 @@ pub(crate) fn inherent_impl_substs(
|
|||
// Unknown. I think this can only really happen if self_ty contained
|
||||
// Unknown, and in that case we want the result to contain Unknown in those
|
||||
// places again.
|
||||
substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner)))
|
||||
substs
|
||||
.map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner)))
|
||||
}
|
||||
|
||||
/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
|
||||
|
@ -821,7 +822,7 @@ fn generic_implements_goal(
|
|||
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
|
||||
UniverseIndex::ROOT,
|
||||
))
|
||||
.take(substs.len() - 1),
|
||||
.take(substs.len(&Interner) - 1),
|
||||
);
|
||||
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
|
||||
let obligation = trait_ref.cast(&Interner);
|
||||
|
|
|
@ -138,7 +138,7 @@ pub(crate) fn trait_solve_query(
|
|||
..
|
||||
})) = &goal.value.goal
|
||||
{
|
||||
if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
|
||||
if let TyKind::BoundVar(_) = projection_ty.self_type_parameter().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));
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||
|
||||
use log::debug;
|
||||
|
||||
use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg};
|
||||
use chalk_ir::{fold::shift::Shift, CanonicalVarKinds};
|
||||
use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
|
||||
|
||||
use base_db::{salsa::InternKey, CrateId};
|
||||
|
@ -80,7 +80,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
|||
fn impls_for_trait(
|
||||
&self,
|
||||
trait_id: TraitId,
|
||||
parameters: &[GenericArg<Interner>],
|
||||
parameters: &[chalk_ir::GenericArg<Interner>],
|
||||
binders: &CanonicalVarKinds<Interner>,
|
||||
) -> Vec<ImplId> {
|
||||
debug!("impls_for_trait {:?}", trait_id);
|
||||
|
@ -308,7 +308,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
|||
_closure_id: chalk_ir::ClosureId<Interner>,
|
||||
_substs: &chalk_ir::Substitution<Interner>,
|
||||
) -> chalk_ir::Substitution<Interner> {
|
||||
Substitution::empty().to_chalk(self.db)
|
||||
Substitution::empty(&Interner).to_chalk(self.db)
|
||||
}
|
||||
|
||||
fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
|
||||
|
@ -439,7 +439,7 @@ pub(crate) fn trait_datum_query(
|
|||
lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
|
||||
let trait_datum = TraitDatum {
|
||||
id: trait_id,
|
||||
binders: make_binders(trait_datum_bound, bound_vars.len()),
|
||||
binders: make_binders(trait_datum_bound, bound_vars.len(&Interner)),
|
||||
flags,
|
||||
associated_ty_ids,
|
||||
well_known,
|
||||
|
@ -577,7 +577,7 @@ fn impl_def_datum(
|
|||
.collect();
|
||||
debug!("impl_datum: {:?}", impl_datum_bound);
|
||||
let impl_datum = ImplDatum {
|
||||
binders: make_binders(impl_datum_bound, bound_vars.len()),
|
||||
binders: make_binders(impl_datum_bound, bound_vars.len(&Interner)),
|
||||
impl_type,
|
||||
polarity,
|
||||
associated_ty_value_ids,
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
db::HirDatabase,
|
||||
primitive::UintTy,
|
||||
traits::{Canonical, DomainGoal},
|
||||
AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy,
|
||||
AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
|
||||
QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
|
||||
};
|
||||
|
||||
|
@ -137,7 +137,7 @@ impl ToChalk for Ty {
|
|||
db,
|
||||
substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
|
||||
);
|
||||
TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs })
|
||||
TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs })
|
||||
}
|
||||
chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
|
||||
chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
|
||||
|
@ -216,24 +216,39 @@ fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
|
|||
chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
|
||||
}
|
||||
|
||||
impl ToChalk for GenericArg {
|
||||
type Chalk = chalk_ir::GenericArg<Interner>;
|
||||
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
|
||||
match self.interned {
|
||||
crate::GenericArgData::Ty(ty) => ty.to_chalk(db).cast(&Interner),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
|
||||
match chalk.interned() {
|
||||
chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner),
|
||||
chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(),
|
||||
chalk_ir::GenericArgData::Const(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToChalk for Substitution {
|
||||
type Chalk = chalk_ir::Substitution<Interner>;
|
||||
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
|
||||
chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
|
||||
chalk_ir::Substitution::from_iter(
|
||||
&Interner,
|
||||
self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)),
|
||||
)
|
||||
}
|
||||
|
||||
fn from_chalk(
|
||||
db: &dyn HirDatabase,
|
||||
parameters: chalk_ir::Substitution<Interner>,
|
||||
) -> Substitution {
|
||||
let tys = parameters
|
||||
.iter(&Interner)
|
||||
.map(|p| match p.ty(&Interner) {
|
||||
Some(ty) => from_chalk(db, ty.clone()),
|
||||
None => unimplemented!(),
|
||||
})
|
||||
.collect();
|
||||
let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect();
|
||||
Substitution(tys)
|
||||
}
|
||||
}
|
||||
|
@ -531,7 +546,7 @@ pub(super) fn generic_predicate_to_inline_bound(
|
|||
// have the expected self type
|
||||
return None;
|
||||
}
|
||||
let args_no_self = trait_ref.substitution[1..]
|
||||
let args_no_self = trait_ref.substitution.interned(&Interner)[1..]
|
||||
.iter()
|
||||
.map(|ty| ty.clone().to_chalk(db).cast(&Interner))
|
||||
.collect();
|
||||
|
@ -543,7 +558,7 @@ pub(super) fn generic_predicate_to_inline_bound(
|
|||
return None;
|
||||
}
|
||||
let trait_ = projection_ty.trait_(db);
|
||||
let args_no_self = projection_ty.substitution[1..]
|
||||
let args_no_self = projection_ty.substitution.interned(&Interner)[1..]
|
||||
.iter()
|
||||
.map(|ty| ty.clone().to_chalk(db).cast(&Interner))
|
||||
.collect();
|
||||
|
|
Loading…
Reference in a new issue