Skip to content

Commit d6e3929

Browse files
committed
include lifetime in ParamKind and in Generics::provenance_split
1 parent e463a3e commit d6e3929

File tree

10 files changed

+116
-50
lines changed

10 files changed

+116
-50
lines changed

crates/hir-ty/src/builder.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ use hir_def::{
1515
use smallvec::SmallVec;
1616

1717
use crate::{
18-
consteval::unknown_const_as_generic, db::HirDatabase, infer::unify::InferenceTable, primitive,
19-
to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, BoundVar, CallableSig,
20-
GenericArg, GenericArgData, Interner, ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt,
21-
TyKind,
18+
consteval::unknown_const_as_generic, db::HirDatabase, error_lifetime,
19+
infer::unify::InferenceTable, primitive, static_lifetime, to_assoc_type_id, to_chalk_trait_id,
20+
utils::generics, Binders, BoundVar, CallableSig, GenericArg, GenericArgData, Interner,
21+
ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind,
2222
};
2323

2424
#[derive(Debug, Clone, PartialEq, Eq)]
2525
pub enum ParamKind {
2626
Type,
27+
Lifetime,
2728
Const(Ty),
2829
}
2930

@@ -107,6 +108,9 @@ impl<D> TyBuilder<D> {
107108
ParamKind::Const(ty) => {
108109
BoundVar::new(debruijn, idx).to_const(Interner, ty.clone()).cast(Interner)
109110
}
111+
ParamKind::Lifetime => {
112+
BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner)
113+
}
110114
});
111115
this.vec.extend(filler.take(this.remaining()).casted(Interner));
112116
assert_eq!(this.remaining(), 0);
@@ -119,6 +123,7 @@ impl<D> TyBuilder<D> {
119123
let filler = this.param_kinds[this.vec.len()..].iter().map(|x| match x {
120124
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
121125
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
126+
ParamKind::Lifetime => error_lifetime().cast(Interner),
122127
});
123128
this.vec.extend(filler.casted(Interner));
124129
assert_eq!(this.remaining(), 0);
@@ -130,6 +135,8 @@ impl<D> TyBuilder<D> {
130135
self.fill(|x| match x {
131136
ParamKind::Type => table.new_type_var().cast(Interner),
132137
ParamKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
138+
// FIXME: create new_lifetime_var in table
139+
ParamKind::Lifetime => static_lifetime().cast(Interner),
133140
})
134141
}
135142

@@ -142,7 +149,8 @@ impl<D> TyBuilder<D> {
142149
fn assert_match_kind(&self, a: &chalk_ir::GenericArg<Interner>, e: &ParamKind) {
143150
match (a.data(Interner), e) {
144151
(GenericArgData::Ty(_), ParamKind::Type)
145-
| (GenericArgData::Const(_), ParamKind::Const(_)) => (),
152+
| (GenericArgData::Const(_), ParamKind::Const(_))
153+
| (GenericArgData::Lifetime(_), ParamKind::Lifetime) => (),
146154
_ => panic!("Mismatched kinds: {a:?}, {:?}, {:?}", self.vec, self.param_kinds),
147155
}
148156
}
@@ -217,6 +225,7 @@ impl TyBuilder<()> {
217225
) -> TyBuilder<()> {
218226
let generics = generics(db.upcast(), def.into());
219227
assert!(generics.parent_generics().is_some() == parent_subst.is_some());
228+
let lt_iter = generics.iter_lt_self().map(|_| ParamKind::Lifetime);
220229
let params = generics
221230
.iter_self()
222231
.map(|(id, data)| match data {
@@ -225,6 +234,7 @@ impl TyBuilder<()> {
225234
ParamKind::Const(db.const_param_ty(ConstParamId::from_unchecked(id)))
226235
}
227236
})
237+
.chain(lt_iter)
228238
.collect();
229239
TyBuilder::new((), params, parent_subst)
230240
}

crates/hir-ty/src/display.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -938,15 +938,23 @@ impl HirDisplay for Ty {
938938
f.end_location_link();
939939
if parameters.len(Interner) > 0 {
940940
let generics = generics(db.upcast(), def.into());
941-
let (parent_params, self_param, type_params, const_params, _impl_trait_params) =
942-
generics.provenance_split();
943-
let total_len = parent_params + self_param + type_params + const_params;
941+
let (
942+
parent_params,
943+
self_param,
944+
type_params,
945+
const_params,
946+
_impl_trait_params,
947+
lifetime_params,
948+
) = generics.provenance_split();
949+
let total_len =
950+
parent_params + self_param + type_params + const_params + lifetime_params;
944951
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
945952
if total_len > 0 {
946953
// `parameters` are in the order of fn's params (including impl traits),
947954
// parent's params (those from enclosing impl or trait, if any).
948955
let parameters = parameters.as_slice(Interner);
949-
let fn_params_len = self_param + type_params + const_params;
956+
let fn_params_len =
957+
self_param + type_params + const_params + lifetime_params;
950958
let fn_params = parameters.get(..fn_params_len);
951959
let parent_params = parameters.get(parameters.len() - parent_params..);
952960
let params = parent_params.into_iter().chain(fn_params).flatten();

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use hir_def::{
1313
ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
1414
},
1515
lang_item::{LangItem, LangItemTarget},
16-
path::{GenericArg, GenericArgs, Path},
16+
path::{GenericArgs, Path},
1717
BlockId, ConstParamId, FieldId, ItemContainerId, Lookup, TupleFieldId, TupleId,
1818
};
1919
use hir_expand::name::{name, Name};
@@ -1816,10 +1816,17 @@ impl InferenceContext<'_> {
18161816
def_generics: Generics,
18171817
generic_args: Option<&GenericArgs>,
18181818
) -> Substitution {
1819-
let (parent_params, self_params, type_params, const_params, impl_trait_params) =
1820-
def_generics.provenance_split();
1819+
let (
1820+
parent_params,
1821+
self_params,
1822+
type_params,
1823+
const_params,
1824+
impl_trait_params,
1825+
lifetime_params,
1826+
) = def_generics.provenance_split();
18211827
assert_eq!(self_params, 0); // method shouldn't have another Self param
1822-
let total_len = parent_params + type_params + const_params + impl_trait_params;
1828+
let total_len =
1829+
parent_params + type_params + const_params + impl_trait_params + lifetime_params;
18231830
let mut substs = Vec::with_capacity(total_len);
18241831

18251832
// handle provided arguments
@@ -1828,9 +1835,8 @@ impl InferenceContext<'_> {
18281835
for (arg, kind_id) in generic_args
18291836
.args
18301837
.iter()
1831-
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
1832-
.take(type_params + const_params)
1833-
.zip(def_generics.iter_id())
1838+
.take(type_params + const_params + lifetime_params)
1839+
.zip(def_generics.iter_id_with_lt())
18341840
{
18351841
if let Some(g) = generic_arg_to_chalk(
18361842
self.db,
@@ -1850,6 +1856,8 @@ impl InferenceContext<'_> {
18501856
DebruijnIndex::INNERMOST,
18511857
)
18521858
},
1859+
// FIXME: create make_lifetimes and infer lifetimes
1860+
|_, _| static_lifetime(),
18531861
) {
18541862
substs.push(g);
18551863
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use stdx::never;
1111

1212
use crate::{
1313
builder::ParamKind,
14-
consteval,
14+
consteval, error_lifetime,
1515
method_resolution::{self, VisibleFromModule},
1616
to_chalk_trait_id,
1717
utils::generics,
@@ -111,6 +111,7 @@ impl InferenceContext<'_> {
111111
it.next().unwrap_or_else(|| match x {
112112
ParamKind::Type => self.result.standard_types.unknown.clone().cast(Interner),
113113
ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
114+
ParamKind::Lifetime => error_lifetime().cast(Interner),
114115
})
115116
})
116117
.build();

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ impl<'a> InferenceTable<'a> {
807807
.fill(|it| {
808808
let arg = match it {
809809
ParamKind::Type => self.new_type_var(),
810+
ParamKind::Lifetime => unreachable!("Tuple with lifetime parameter"),
810811
ParamKind::Const(_) => unreachable!("Tuple with const parameter"),
811812
};
812813
arg_tys.push(arg.clone());

crates/hir-ty/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ pub use lower::{
9292
};
9393
pub use mapping::{
9494
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
95-
lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id, to_foreign_def_id,
96-
to_placeholder_idx,
95+
lt_from_placeholder_idx, lt_to_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
96+
to_foreign_def_id, to_placeholder_idx,
9797
};
9898
pub use method_resolution::check_orphan_rules;
9999
pub use traits::TraitEnvironment;

crates/hir-ty/src/lower.rs

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ use hir_def::{
3434
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
3535
},
3636
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
37-
GenericDefId, HasModule, ImplId, InTypeConstLoc, ItemContainerId, LocalFieldId, Lookup,
38-
ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
39-
TypeParamId, UnionId, VariantId,
37+
GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId, LocalFieldId,
38+
Lookup, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
39+
UnionId, VariantId,
4040
};
4141
use hir_expand::{name::Name, ExpandResult};
4242
use intern::Interned;
@@ -377,15 +377,20 @@ impl<'a> TyLoweringContext<'a> {
377377
list_params,
378378
const_params,
379379
_impl_trait_params,
380+
lifetime_params,
380381
) = if let Some(def) = self.resolver.generic_def() {
381382
let generics = generics(self.db.upcast(), def);
382383
generics.provenance_split()
383384
} else {
384-
(0, 0, 0, 0, 0)
385+
(0, 0, 0, 0, 0, 0)
385386
};
386387
TyKind::BoundVar(BoundVar::new(
387388
self.in_binders,
388-
idx as usize + self_params + list_params + const_params,
389+
idx as usize
390+
+ self_params
391+
+ list_params
392+
+ const_params
393+
+ lifetime_params,
389394
))
390395
.intern(Interner)
391396
}
@@ -818,14 +823,21 @@ impl<'a> TyLoweringContext<'a> {
818823
return Substitution::empty(Interner);
819824
};
820825
let def_generics = generics(self.db.upcast(), def);
821-
let (parent_params, self_params, type_params, const_params, impl_trait_params) =
822-
def_generics.provenance_split();
823-
let item_len = self_params + type_params + const_params + impl_trait_params;
826+
let (
827+
parent_params,
828+
self_params,
829+
type_params,
830+
const_params,
831+
impl_trait_params,
832+
lifetime_params,
833+
) = def_generics.provenance_split();
834+
let item_len =
835+
self_params + type_params + const_params + impl_trait_params + lifetime_params;
824836
let total_len = parent_params + item_len;
825837

826838
let ty_error = TyKind::Error.intern(Interner).cast(Interner);
827839

828-
let mut def_generic_iter = def_generics.iter_id();
840+
let mut def_generic_iter = def_generics.iter_id_with_lt();
829841

830842
let fill_self_params = || {
831843
for x in explicit_self_ty
@@ -835,7 +847,10 @@ impl<'a> TyLoweringContext<'a> {
835847
.take(self_params)
836848
{
837849
if let Some(id) = def_generic_iter.next() {
838-
assert!(id.is_left());
850+
assert!(matches!(
851+
id,
852+
GenericParamId::TypeParamId(_) | GenericParamId::LifetimeParamId(_)
853+
));
839854
substs.push(x);
840855
}
841856
}
@@ -847,19 +862,13 @@ impl<'a> TyLoweringContext<'a> {
847862
fill_self_params();
848863
}
849864
let expected_num = if generic_args.has_self_type {
850-
self_params + type_params + const_params
865+
self_params + type_params + const_params + lifetime_params
851866
} else {
852867
type_params + const_params
853868
};
854869
let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
855870
// if args are provided, it should be all of them, but we can't rely on that
856-
for arg in generic_args
857-
.args
858-
.iter()
859-
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
860-
.skip(skip)
861-
.take(expected_num)
862-
{
871+
for arg in generic_args.args.iter().skip(skip).take(expected_num) {
863872
if let Some(id) = def_generic_iter.next() {
864873
if let Some(x) = generic_arg_to_chalk(
865874
self.db,
@@ -868,6 +877,7 @@ impl<'a> TyLoweringContext<'a> {
868877
&mut (),
869878
|_, type_ref| self.lower_ty(type_ref),
870879
|_, const_ref, ty| self.lower_const(const_ref, ty),
880+
|_, lifetime_ref| self.lower_lifetime(lifetime_ref),
871881
) {
872882
had_explicit_args = true;
873883
substs.push(x);
@@ -883,9 +893,12 @@ impl<'a> TyLoweringContext<'a> {
883893

884894
// These params include those of parent.
885895
let remaining_params: SmallVec<[_; 2]> = def_generic_iter
886-
.map(|eid| match eid {
887-
Either::Left(_) => ty_error.clone(),
888-
Either::Right(x) => unknown_const_as_generic(self.db.const_param_ty(x)),
896+
.map(|id| match id {
897+
GenericParamId::ConstParamId(x) => {
898+
unknown_const_as_generic(self.db.const_param_ty(x))
899+
}
900+
GenericParamId::TypeParamId(_) => ty_error.clone(),
901+
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
889902
})
890903
.collect();
891904
assert_eq!(remaining_params.len() + substs.len(), total_len);
@@ -1719,7 +1732,7 @@ pub(crate) fn generic_defaults_query(
17191732
let generic_params = generics(db.upcast(), def);
17201733
let parent_start_idx = generic_params.len_self();
17211734

1722-
let defaults = Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| {
1735+
let toc_iter = generic_params.iter().enumerate().map(|(idx, (id, p))| {
17231736
match p {
17241737
TypeOrConstParamData::TypeParamData(p) => {
17251738
let mut ty =
@@ -1747,7 +1760,14 @@ pub(crate) fn generic_defaults_query(
17471760
make_binders(db, &generic_params, val)
17481761
}
17491762
}
1750-
}));
1763+
});
1764+
1765+
let lt_iter = generic_params
1766+
.iter_lt()
1767+
.enumerate()
1768+
.map(|_| make_binders(db, &generic_params, static_lifetime().cast(Interner)));
1769+
1770+
let defaults = Arc::from_iter(toc_iter.chain(lt_iter));
17511771

17521772
defaults
17531773
}
@@ -2127,23 +2147,29 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
21272147
/// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
21282148
pub(crate) fn generic_arg_to_chalk<'a, T>(
21292149
db: &dyn HirDatabase,
2130-
kind_id: Either<TypeParamId, ConstParamId>,
2150+
kind_id: GenericParamId,
21312151
arg: &'a GenericArg,
21322152
this: &mut T,
21332153
for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
21342154
for_const: impl FnOnce(&mut T, &ConstRef, Ty) -> Const + 'a,
2155+
for_lifetime: impl FnOnce(&mut T, &LifetimeRef) -> Lifetime + 'a,
21352156
) -> Option<crate::GenericArg> {
21362157
let kind = match kind_id {
2137-
Either::Left(_) => ParamKind::Type,
2138-
Either::Right(id) => {
2158+
GenericParamId::TypeParamId(_) => ParamKind::Type,
2159+
GenericParamId::ConstParamId(id) => {
21392160
let ty = db.const_param_ty(id);
21402161
ParamKind::Const(ty)
21412162
}
2163+
GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime,
21422164
};
21432165
Some(match (arg, kind) {
21442166
(GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, type_ref).cast(Interner),
21452167
(GenericArg::Const(c), ParamKind::Const(c_ty)) => for_const(this, c, c_ty).cast(Interner),
2168+
(GenericArg::Lifetime(lifetime_ref), ParamKind::Lifetime) => {
2169+
for_lifetime(this, lifetime_ref).cast(Interner)
2170+
}
21462171
(GenericArg::Const(_), ParamKind::Type) => TyKind::Error.intern(Interner).cast(Interner),
2172+
(GenericArg::Lifetime(_), ParamKind::Type) => TyKind::Error.intern(Interner).cast(Interner),
21472173
(GenericArg::Type(t), ParamKind::Const(c_ty)) => {
21482174
// We want to recover simple idents, which parser detects them
21492175
// as types. Maybe here is not the best place to do it, but
@@ -2159,7 +2185,9 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
21592185
}
21602186
unknown_const_as_generic(c_ty)
21612187
}
2162-
(GenericArg::Lifetime(_), _) => return None,
2188+
(GenericArg::Lifetime(_), ParamKind::Const(c_ty)) => unknown_const_as_generic(c_ty),
2189+
(GenericArg::Type(_), ParamKind::Lifetime) => error_lifetime().cast(Interner),
2190+
(GenericArg::Const(_), ParamKind::Lifetime) => error_lifetime().cast(Interner),
21632191
})
21642192
}
21652193

crates/hir-ty/src/mapping.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> L
151151
db.lookup_intern_lifetime_param_id(interned_id)
152152
}
153153

154-
pub(crate) fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> PlaceholderIndex {
154+
pub fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> PlaceholderIndex {
155155
let interned_id = db.intern_lifetime_param_id(id);
156156
PlaceholderIndex {
157157
ui: chalk_ir::UniverseIndex::ROOT,

0 commit comments

Comments
 (0)