Skip to content

Commit

Permalink
Adapt to the new generic parameter/argument order
Browse files Browse the repository at this point in the history
  • Loading branch information
lowr committed Oct 2, 2022
1 parent 4385d3d commit 78977cd
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 161 deletions.
5 changes: 3 additions & 2 deletions crates/hir-ty/src/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,14 @@ fn deref_by_trait(table: &mut InferenceTable<'_>, ty: Ty) -> Option<Ty> {
let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;

let projection = {
let b = TyBuilder::assoc_type_projection(db, target);
let b = TyBuilder::subst_for_def(db, deref_trait, None);
if b.remaining() != 1 {
// the Target type + Deref trait should only have one generic parameter,
// namely Deref's Self type
return None;
}
b.push(ty).build()
let deref_subst = b.push(ty).build();
TyBuilder::assoc_type_projection(db, target, Some(deref_subst)).build()
};

// Check that the type implements Deref at all
Expand Down
14 changes: 9 additions & 5 deletions crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,12 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
// `resume_type`, `yield_type`, and `return_type` of the generator in question.
let subst = TyBuilder::subst_for_generator(self.db, parent).fill_with_unknown().build();

let len = subst.len(Interner);
let input_output = rust_ir::GeneratorInputOutputDatum {
resume_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 3))
resume_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
.intern(Interner),
yield_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 2))
yield_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 1))
.intern(Interner),
return_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 1))
return_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 2))
.intern(Interner),
// FIXME: calculate upvars
upvars: vec![],
Expand Down Expand Up @@ -476,10 +475,15 @@ pub(crate) fn associated_ty_data_query(
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
let ctx = crate::TyLoweringContext::new(db, &resolver)
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
let pro_ty = TyBuilder::assoc_type_projection(db, type_alias)

let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
.fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, generic_params.len_self())
.build();
let pro_ty = TyBuilder::assoc_type_projection(db, type_alias, Some(trait_subst))
.fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, 0)
.build();
let self_ty = TyKind::Alias(AliasTy::Projection(pro_ty)).intern(Interner);

let mut bounds: Vec<_> = type_alias_data
.bounds
.iter()
Expand Down
16 changes: 11 additions & 5 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
db::HirDatabase,
from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, lt_from_placeholder_idx,
mapping::from_chalk,
primitive, subst_prefix, to_assoc_type_id,
primitive, to_assoc_type_id,
utils::{self, generics},
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstValue, DomainGoal,
GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives, Mutability,
Expand Down Expand Up @@ -506,8 +506,15 @@ impl HirDisplay for Ty {
let total_len = parent_params + self_param + type_params + const_params;
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
if total_len > 0 {
// `parameters` are in the order of fn's params (including impl traits),
// parent's params (those from enclosing impl or trait, if any).
let parameters = parameters.as_slice(Interner);
let fn_params_len = self_param + type_params + const_params;
let fn_params = parameters.get(..fn_params_len);
let parent_params = parameters.get(parameters.len() - parent_params..);
let params = parent_params.into_iter().chain(fn_params).flatten();
write!(f, "<")?;
f.write_joined(&parameters.as_slice(Interner)[..total_len], ", ")?;
f.write_joined(params, ", ")?;
write!(f, ">")?;
}
}
Expand Down Expand Up @@ -579,9 +586,8 @@ impl HirDisplay for Ty {
Some(x) => x,
None => return true,
};
let actual_default = default_parameter
.clone()
.substitute(Interner, &subst_prefix(parameters, i));
let actual_default =
default_parameter.clone().substitute(Interner, &parameters);
parameter != &actual_default
}
let mut default_from = 0;
Expand Down
19 changes: 16 additions & 3 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use hir_def::{
path::{path, Path},
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
type_ref::TypeRef,
AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup,
TraitId, TypeAliasId, VariantId,
AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule,
ItemContainerId, Lookup, TraitId, TypeAliasId, VariantId,
};
use hir_expand::name::{name, Name};
use itertools::Either;
Expand Down Expand Up @@ -713,6 +713,8 @@ impl<'a> InferenceContext<'a> {
&mut self,
inner_ty: Ty,
assoc_ty: Option<TypeAliasId>,
// FIXME(GATs): these are args for the trait ref, args for assoc type itself should be
// handled when we support them.
params: &[GenericArg],
) -> Ty {
match assoc_ty {
Expand Down Expand Up @@ -804,7 +806,18 @@ impl<'a> InferenceContext<'a> {
self.resolve_variant_on_alias(ty, unresolved, path)
}
TypeNs::TypeAliasId(it) => {
let ty = TyBuilder::def_ty(self.db, it.into())
let container = it.lookup(self.db.upcast()).container;
let parent_subst = match container {
ItemContainerId::TraitId(id) => {
let subst = TyBuilder::subst_for_def(self.db, id, None)
.fill_with_inference_vars(&mut self.table)
.build();
Some(subst)
}
// Type aliases do not exist in impls.
_ => None,
};
let ty = TyBuilder::def_ty(self.db, it.into(), parent_subst)
.fill_with_inference_vars(&mut self.table)
.build();
self.resolve_variant_on_alias(ty, unresolved, path)
Expand Down
43 changes: 21 additions & 22 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -987,11 +987,13 @@ impl<'a> InferenceContext<'a> {
let lhs_ty = self.infer_expr(lhs, &lhs_expectation);
let rhs_ty = self.table.new_type_var();

let func = lang_names_for_bin_op(op).and_then(|(name, lang_item)| {
self.db.trait_data(self.resolve_lang_item(lang_item)?.as_trait()?).method_by_name(&name)
let trait_func = lang_names_for_bin_op(op).and_then(|(name, lang_item)| {
let trait_id = self.resolve_lang_item(lang_item)?.as_trait()?;
let func = self.db.trait_data(trait_id).method_by_name(&name)?;
Some((trait_id, func))
});
let func = match func {
Some(func) => func,
let (trait_, func) = match trait_func {
Some(it) => it,
None => {
let rhs_ty = self.builtin_binary_op_rhs_expectation(op, lhs_ty.clone());
let rhs_ty = self.infer_expr_coerce(rhs, &Expectation::from_option(rhs_ty));
Expand All @@ -1001,7 +1003,9 @@ impl<'a> InferenceContext<'a> {
}
};

let subst = TyBuilder::subst_for_def(self.db, func)
// HACK: We can use this substitution for the function because the function itself doesn't
// have its own generic parameters.
let subst = TyBuilder::subst_for_def(self.db, trait_, None)
.push(lhs_ty.clone())
.push(rhs_ty.clone())
.build();
Expand Down Expand Up @@ -1280,19 +1284,7 @@ impl<'a> InferenceContext<'a> {
assert_eq!(self_params, 0); // method shouldn't have another Self param
let total_len = parent_params + type_params + const_params + impl_trait_params;
let mut substs = Vec::with_capacity(total_len);
// Parent arguments are unknown
for (id, param) in def_generics.iter_parent() {
match param {
TypeOrConstParamData::TypeParamData(_) => {
substs.push(GenericArgData::Ty(self.table.new_type_var()).intern(Interner));
}
TypeOrConstParamData::ConstParamData(_) => {
let ty = self.db.const_param_ty(ConstParamId::from_unchecked(id));
substs
.push(GenericArgData::Const(self.table.new_const_var(ty)).intern(Interner));
}
}
}

// handle provided arguments
if let Some(generic_args) = generic_args {
// if args are provided, it should be all of them, but we can't rely on that
Expand All @@ -1301,7 +1293,7 @@ impl<'a> InferenceContext<'a> {
.iter()
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
.take(type_params + const_params)
.zip(def_generics.iter_id().skip(parent_params))
.zip(def_generics.iter_id())
{
if let Some(g) = generic_arg_to_chalk(
self.db,
Expand All @@ -1325,6 +1317,9 @@ impl<'a> InferenceContext<'a> {
}
}
};

// Handle everything else as unknown. This also handles generic arguments for the method's
// parent (impl or trait), which should come after those for the method.
for (id, data) in def_generics.iter().skip(substs.len()) {
match data {
TypeOrConstParamData::TypeParamData(_) => {
Expand Down Expand Up @@ -1362,9 +1357,13 @@ impl<'a> InferenceContext<'a> {
CallableDefId::FunctionId(f) => {
if let ItemContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container {
// construct a TraitRef
let substs = crate::subst_prefix(
&*parameters,
generics(self.db.upcast(), trait_.into()).len(),
let params_len = parameters.len(Interner);
let trait_params_len = generics(self.db.upcast(), trait_.into()).len();
let substs = Substitution::from_iter(
Interner,
// The generic parameters for the trait come after those for the
// function.
&parameters.as_slice(Interner)[params_len - trait_params_len..],
);
self.push_obligation(
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
Expand Down
17 changes: 12 additions & 5 deletions crates/hir-ty/src/infer/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
builder::ParamKind,
consteval,
method_resolution::{self, VisibleFromModule},
utils::generics,
Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, ValueTyDefId,
};

Expand Down Expand Up @@ -95,12 +96,18 @@ impl<'a> InferenceContext<'a> {
ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
};

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 mut it = substs.as_slice(Interner)[parent_substs.len(Interner)..].iter().cloned();
let ty = TyBuilder::value_ty(self.db, typable)
.use_parent_substs(&parent_substs)
let substs = substs.as_slice(Interner);
let parent_substs = self_subst.or_else(|| {
let generics = generics(self.db.upcast(), typable.to_generic_def_id()?);
let parent_params_len = generics.parent_generics()?.len();
let parent_args = &substs[substs.len() - parent_params_len..];
Some(Substitution::from_iter(Interner, parent_args))
});
let parent_substs_len = parent_substs.as_ref().map_or(0, |s| s.len(Interner));
let mut it = substs.iter().take(substs.len() - parent_substs_len).cloned();
let ty = TyBuilder::value_ty(self.db, typable, parent_substs)
.fill(|x| {
it.next().unwrap_or_else(|| match x {
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
Expand Down Expand Up @@ -246,7 +253,7 @@ impl<'a> InferenceContext<'a> {
};
let substs = match container {
ItemContainerId::ImplId(impl_id) => {
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id, None)
.fill_with_inference_vars(&mut self.table)
.build();
let impl_self_ty =
Expand Down
7 changes: 5 additions & 2 deletions crates/hir-ty/src/infer/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,14 @@ impl<'a> InferenceTable<'a> {
.build();

let projection = {
let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
let b = TyBuilder::subst_for_def(self.db, fn_once_trait, None);
if b.remaining() != 2 {
return None;
}
b.push(ty.clone()).push(arg_ty).build()
let fn_once_subst = b.push(ty.clone()).push(arg_ty).build();

TyBuilder::assoc_type_projection(self.db, output_assoc_type, Some(fn_once_subst))
.build()
};

let trait_env = self.trait_env.env.clone();
Expand Down
Loading

0 comments on commit 78977cd

Please sign in to comment.