Skip to content

Commit 78977cd

Browse files
committed
Adapt to the new generic parameter/argument order
1 parent 4385d3d commit 78977cd

File tree

11 files changed

+259
-161
lines changed

11 files changed

+259
-161
lines changed

crates/hir-ty/src/autoderef.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,14 @@ fn deref_by_trait(table: &mut InferenceTable<'_>, ty: Ty) -> Option<Ty> {
123123
let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
124124

125125
let projection = {
126-
let b = TyBuilder::assoc_type_projection(db, target);
126+
let b = TyBuilder::subst_for_def(db, deref_trait, None);
127127
if b.remaining() != 1 {
128128
// the Target type + Deref trait should only have one generic parameter,
129129
// namely Deref's Self type
130130
return None;
131131
}
132-
b.push(ty).build()
132+
let deref_subst = b.push(ty).build();
133+
TyBuilder::assoc_type_projection(db, target, Some(deref_subst)).build()
133134
};
134135

135136
// Check that the type implements Deref at all

crates/hir-ty/src/chalk_db.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,12 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
382382
// `resume_type`, `yield_type`, and `return_type` of the generator in question.
383383
let subst = TyBuilder::subst_for_generator(self.db, parent).fill_with_unknown().build();
384384

385-
let len = subst.len(Interner);
386385
let input_output = rust_ir::GeneratorInputOutputDatum {
387-
resume_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 3))
386+
resume_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
388387
.intern(Interner),
389-
yield_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 2))
388+
yield_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 1))
390389
.intern(Interner),
391-
return_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 1))
390+
return_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 2))
392391
.intern(Interner),
393392
// FIXME: calculate upvars
394393
upvars: vec![],
@@ -476,10 +475,15 @@ pub(crate) fn associated_ty_data_query(
476475
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
477476
let ctx = crate::TyLoweringContext::new(db, &resolver)
478477
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
479-
let pro_ty = TyBuilder::assoc_type_projection(db, type_alias)
478+
479+
let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
480+
.fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, generic_params.len_self())
481+
.build();
482+
let pro_ty = TyBuilder::assoc_type_projection(db, type_alias, Some(trait_subst))
480483
.fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, 0)
481484
.build();
482485
let self_ty = TyKind::Alias(AliasTy::Projection(pro_ty)).intern(Interner);
486+
483487
let mut bounds: Vec<_> = type_alias_data
484488
.bounds
485489
.iter()

crates/hir-ty/src/display.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
db::HirDatabase,
2828
from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, lt_from_placeholder_idx,
2929
mapping::from_chalk,
30-
primitive, subst_prefix, to_assoc_type_id,
30+
primitive, to_assoc_type_id,
3131
utils::{self, generics},
3232
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstValue, DomainGoal,
3333
GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives, Mutability,
@@ -506,8 +506,15 @@ impl HirDisplay for Ty {
506506
let total_len = parent_params + self_param + type_params + const_params;
507507
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
508508
if total_len > 0 {
509+
// `parameters` are in the order of fn's params (including impl traits),
510+
// parent's params (those from enclosing impl or trait, if any).
511+
let parameters = parameters.as_slice(Interner);
512+
let fn_params_len = self_param + type_params + const_params;
513+
let fn_params = parameters.get(..fn_params_len);
514+
let parent_params = parameters.get(parameters.len() - parent_params..);
515+
let params = parent_params.into_iter().chain(fn_params).flatten();
509516
write!(f, "<")?;
510-
f.write_joined(&parameters.as_slice(Interner)[..total_len], ", ")?;
517+
f.write_joined(params, ", ")?;
511518
write!(f, ">")?;
512519
}
513520
}
@@ -579,9 +586,8 @@ impl HirDisplay for Ty {
579586
Some(x) => x,
580587
None => return true,
581588
};
582-
let actual_default = default_parameter
583-
.clone()
584-
.substitute(Interner, &subst_prefix(parameters, i));
589+
let actual_default =
590+
default_parameter.clone().substitute(Interner, &parameters);
585591
parameter != &actual_default
586592
}
587593
let mut default_from = 0;

crates/hir-ty/src/infer.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use hir_def::{
2626
path::{path, Path},
2727
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
2828
type_ref::TypeRef,
29-
AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup,
30-
TraitId, TypeAliasId, VariantId,
29+
AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule,
30+
ItemContainerId, Lookup, TraitId, TypeAliasId, VariantId,
3131
};
3232
use hir_expand::name::{name, Name};
3333
use itertools::Either;
@@ -713,6 +713,8 @@ impl<'a> InferenceContext<'a> {
713713
&mut self,
714714
inner_ty: Ty,
715715
assoc_ty: Option<TypeAliasId>,
716+
// FIXME(GATs): these are args for the trait ref, args for assoc type itself should be
717+
// handled when we support them.
716718
params: &[GenericArg],
717719
) -> Ty {
718720
match assoc_ty {
@@ -804,7 +806,18 @@ impl<'a> InferenceContext<'a> {
804806
self.resolve_variant_on_alias(ty, unresolved, path)
805807
}
806808
TypeNs::TypeAliasId(it) => {
807-
let ty = TyBuilder::def_ty(self.db, it.into())
809+
let container = it.lookup(self.db.upcast()).container;
810+
let parent_subst = match container {
811+
ItemContainerId::TraitId(id) => {
812+
let subst = TyBuilder::subst_for_def(self.db, id, None)
813+
.fill_with_inference_vars(&mut self.table)
814+
.build();
815+
Some(subst)
816+
}
817+
// Type aliases do not exist in impls.
818+
_ => None,
819+
};
820+
let ty = TyBuilder::def_ty(self.db, it.into(), parent_subst)
808821
.fill_with_inference_vars(&mut self.table)
809822
.build();
810823
self.resolve_variant_on_alias(ty, unresolved, path)

crates/hir-ty/src/infer/expr.rs

+21-22
Original file line numberDiff line numberDiff line change
@@ -987,11 +987,13 @@ impl<'a> InferenceContext<'a> {
987987
let lhs_ty = self.infer_expr(lhs, &lhs_expectation);
988988
let rhs_ty = self.table.new_type_var();
989989

990-
let func = lang_names_for_bin_op(op).and_then(|(name, lang_item)| {
991-
self.db.trait_data(self.resolve_lang_item(lang_item)?.as_trait()?).method_by_name(&name)
990+
let trait_func = lang_names_for_bin_op(op).and_then(|(name, lang_item)| {
991+
let trait_id = self.resolve_lang_item(lang_item)?.as_trait()?;
992+
let func = self.db.trait_data(trait_id).method_by_name(&name)?;
993+
Some((trait_id, func))
992994
});
993-
let func = match func {
994-
Some(func) => func,
995+
let (trait_, func) = match trait_func {
996+
Some(it) => it,
995997
None => {
996998
let rhs_ty = self.builtin_binary_op_rhs_expectation(op, lhs_ty.clone());
997999
let rhs_ty = self.infer_expr_coerce(rhs, &Expectation::from_option(rhs_ty));
@@ -1001,7 +1003,9 @@ impl<'a> InferenceContext<'a> {
10011003
}
10021004
};
10031005

1004-
let subst = TyBuilder::subst_for_def(self.db, func)
1006+
// HACK: We can use this substitution for the function because the function itself doesn't
1007+
// have its own generic parameters.
1008+
let subst = TyBuilder::subst_for_def(self.db, trait_, None)
10051009
.push(lhs_ty.clone())
10061010
.push(rhs_ty.clone())
10071011
.build();
@@ -1280,19 +1284,7 @@ impl<'a> InferenceContext<'a> {
12801284
assert_eq!(self_params, 0); // method shouldn't have another Self param
12811285
let total_len = parent_params + type_params + const_params + impl_trait_params;
12821286
let mut substs = Vec::with_capacity(total_len);
1283-
// Parent arguments are unknown
1284-
for (id, param) in def_generics.iter_parent() {
1285-
match param {
1286-
TypeOrConstParamData::TypeParamData(_) => {
1287-
substs.push(GenericArgData::Ty(self.table.new_type_var()).intern(Interner));
1288-
}
1289-
TypeOrConstParamData::ConstParamData(_) => {
1290-
let ty = self.db.const_param_ty(ConstParamId::from_unchecked(id));
1291-
substs
1292-
.push(GenericArgData::Const(self.table.new_const_var(ty)).intern(Interner));
1293-
}
1294-
}
1295-
}
1287+
12961288
// handle provided arguments
12971289
if let Some(generic_args) = generic_args {
12981290
// if args are provided, it should be all of them, but we can't rely on that
@@ -1301,7 +1293,7 @@ impl<'a> InferenceContext<'a> {
13011293
.iter()
13021294
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
13031295
.take(type_params + const_params)
1304-
.zip(def_generics.iter_id().skip(parent_params))
1296+
.zip(def_generics.iter_id())
13051297
{
13061298
if let Some(g) = generic_arg_to_chalk(
13071299
self.db,
@@ -1325,6 +1317,9 @@ impl<'a> InferenceContext<'a> {
13251317
}
13261318
}
13271319
};
1320+
1321+
// Handle everything else as unknown. This also handles generic arguments for the method's
1322+
// parent (impl or trait), which should come after those for the method.
13281323
for (id, data) in def_generics.iter().skip(substs.len()) {
13291324
match data {
13301325
TypeOrConstParamData::TypeParamData(_) => {
@@ -1362,9 +1357,13 @@ impl<'a> InferenceContext<'a> {
13621357
CallableDefId::FunctionId(f) => {
13631358
if let ItemContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container {
13641359
// construct a TraitRef
1365-
let substs = crate::subst_prefix(
1366-
&*parameters,
1367-
generics(self.db.upcast(), trait_.into()).len(),
1360+
let params_len = parameters.len(Interner);
1361+
let trait_params_len = generics(self.db.upcast(), trait_.into()).len();
1362+
let substs = Substitution::from_iter(
1363+
Interner,
1364+
// The generic parameters for the trait come after those for the
1365+
// function.
1366+
&parameters.as_slice(Interner)[params_len - trait_params_len..],
13681367
);
13691368
self.push_obligation(
13701369
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }

crates/hir-ty/src/infer/path.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::{
1212
builder::ParamKind,
1313
consteval,
1414
method_resolution::{self, VisibleFromModule},
15+
utils::generics,
1516
Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, ValueTyDefId,
1617
};
1718

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

98-
let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(Interner));
9999
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
100100
let substs = ctx.substs_from_path(path, typable, true);
101-
let mut it = substs.as_slice(Interner)[parent_substs.len(Interner)..].iter().cloned();
102-
let ty = TyBuilder::value_ty(self.db, typable)
103-
.use_parent_substs(&parent_substs)
101+
let substs = substs.as_slice(Interner);
102+
let parent_substs = self_subst.or_else(|| {
103+
let generics = generics(self.db.upcast(), typable.to_generic_def_id()?);
104+
let parent_params_len = generics.parent_generics()?.len();
105+
let parent_args = &substs[substs.len() - parent_params_len..];
106+
Some(Substitution::from_iter(Interner, parent_args))
107+
});
108+
let parent_substs_len = parent_substs.as_ref().map_or(0, |s| s.len(Interner));
109+
let mut it = substs.iter().take(substs.len() - parent_substs_len).cloned();
110+
let ty = TyBuilder::value_ty(self.db, typable, parent_substs)
104111
.fill(|x| {
105112
it.next().unwrap_or_else(|| match x {
106113
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
@@ -246,7 +253,7 @@ impl<'a> InferenceContext<'a> {
246253
};
247254
let substs = match container {
248255
ItemContainerId::ImplId(impl_id) => {
249-
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
256+
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id, None)
250257
.fill_with_inference_vars(&mut self.table)
251258
.build();
252259
let impl_self_ty =

crates/hir-ty/src/infer/unify.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -598,11 +598,14 @@ impl<'a> InferenceTable<'a> {
598598
.build();
599599

600600
let projection = {
601-
let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
601+
let b = TyBuilder::subst_for_def(self.db, fn_once_trait, None);
602602
if b.remaining() != 2 {
603603
return None;
604604
}
605-
b.push(ty.clone()).push(arg_ty).build()
605+
let fn_once_subst = b.push(ty.clone()).push(arg_ty).build();
606+
607+
TyBuilder::assoc_type_projection(self.db, output_assoc_type, Some(fn_once_subst))
608+
.build()
606609
};
607610

608611
let trait_env = self.trait_env.env.clone();

0 commit comments

Comments
 (0)