Unnamed repository; edit this file 'description' to name the repository.
include lifetime in ParamKind and in Generics::provenance_split
dfireBird 2024-03-18
parent e463a3e · commit d6e3929
-rw-r--r--crates/hir-ty/src/builder.rs20
-rw-r--r--crates/hir-ty/src/display.rs16
-rw-r--r--crates/hir-ty/src/infer/expr.rs22
-rw-r--r--crates/hir-ty/src/infer/path.rs3
-rw-r--r--crates/hir-ty/src/infer/unify.rs1
-rw-r--r--crates/hir-ty/src/lib.rs4
-rw-r--r--crates/hir-ty/src/lower.rs82
-rw-r--r--crates/hir-ty/src/mapping.rs2
-rw-r--r--crates/hir-ty/src/utils.rs7
-rw-r--r--crates/hir/src/lib.rs9
10 files changed, 116 insertions, 50 deletions
diff --git a/crates/hir-ty/src/builder.rs b/crates/hir-ty/src/builder.rs
index c485c9b2e8..e311338a2d 100644
--- a/crates/hir-ty/src/builder.rs
+++ b/crates/hir-ty/src/builder.rs
@@ -15,15 +15,16 @@ use hir_def::{
use smallvec::SmallVec;
use crate::{
- consteval::unknown_const_as_generic, db::HirDatabase, infer::unify::InferenceTable, primitive,
- to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, BoundVar, CallableSig,
- GenericArg, GenericArgData, Interner, ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt,
- TyKind,
+ consteval::unknown_const_as_generic, db::HirDatabase, error_lifetime,
+ infer::unify::InferenceTable, primitive, static_lifetime, to_assoc_type_id, to_chalk_trait_id,
+ utils::generics, Binders, BoundVar, CallableSig, GenericArg, GenericArgData, Interner,
+ ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParamKind {
Type,
+ Lifetime,
Const(Ty),
}
@@ -107,6 +108,9 @@ impl<D> TyBuilder<D> {
ParamKind::Const(ty) => {
BoundVar::new(debruijn, idx).to_const(Interner, ty.clone()).cast(Interner)
}
+ ParamKind::Lifetime => {
+ BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner)
+ }
});
this.vec.extend(filler.take(this.remaining()).casted(Interner));
assert_eq!(this.remaining(), 0);
@@ -119,6 +123,7 @@ impl<D> TyBuilder<D> {
let filler = this.param_kinds[this.vec.len()..].iter().map(|x| match x {
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
});
this.vec.extend(filler.casted(Interner));
assert_eq!(this.remaining(), 0);
@@ -130,6 +135,8 @@ impl<D> TyBuilder<D> {
self.fill(|x| match x {
ParamKind::Type => table.new_type_var().cast(Interner),
ParamKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
+ // FIXME: create new_lifetime_var in table
+ ParamKind::Lifetime => static_lifetime().cast(Interner),
})
}
@@ -142,7 +149,8 @@ impl<D> TyBuilder<D> {
fn assert_match_kind(&self, a: &chalk_ir::GenericArg<Interner>, e: &ParamKind) {
match (a.data(Interner), e) {
(GenericArgData::Ty(_), ParamKind::Type)
- | (GenericArgData::Const(_), ParamKind::Const(_)) => (),
+ | (GenericArgData::Const(_), ParamKind::Const(_))
+ | (GenericArgData::Lifetime(_), ParamKind::Lifetime) => (),
_ => panic!("Mismatched kinds: {a:?}, {:?}, {:?}", self.vec, self.param_kinds),
}
}
@@ -217,6 +225,7 @@ impl TyBuilder<()> {
) -> TyBuilder<()> {
let generics = generics(db.upcast(), def.into());
assert!(generics.parent_generics().is_some() == parent_subst.is_some());
+ let lt_iter = generics.iter_lt_self().map(|_| ParamKind::Lifetime);
let params = generics
.iter_self()
.map(|(id, data)| match data {
@@ -225,6 +234,7 @@ impl TyBuilder<()> {
ParamKind::Const(db.const_param_ty(ConstParamId::from_unchecked(id)))
}
})
+ .chain(lt_iter)
.collect();
TyBuilder::new((), params, parent_subst)
}
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 269db57bc3..32be0f248b 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -938,15 +938,23 @@ impl HirDisplay for Ty {
f.end_location_link();
if parameters.len(Interner) > 0 {
let generics = generics(db.upcast(), def.into());
- let (parent_params, self_param, type_params, const_params, _impl_trait_params) =
- generics.provenance_split();
- let total_len = parent_params + self_param + type_params + const_params;
+ let (
+ parent_params,
+ self_param,
+ type_params,
+ const_params,
+ _impl_trait_params,
+ lifetime_params,
+ ) = generics.provenance_split();
+ let total_len =
+ parent_params + self_param + type_params + const_params + lifetime_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_len =
+ self_param + type_params + const_params + lifetime_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();
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index a3dab1fd9d..edfc8a8165 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -13,7 +13,7 @@ use hir_def::{
ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
},
lang_item::{LangItem, LangItemTarget},
- path::{GenericArg, GenericArgs, Path},
+ path::{GenericArgs, Path},
BlockId, ConstParamId, FieldId, ItemContainerId, Lookup, TupleFieldId, TupleId,
};
use hir_expand::name::{name, Name};
@@ -1816,10 +1816,17 @@ impl InferenceContext<'_> {
def_generics: Generics,
generic_args: Option<&GenericArgs>,
) -> Substitution {
- let (parent_params, self_params, type_params, const_params, impl_trait_params) =
- def_generics.provenance_split();
+ let (
+ parent_params,
+ self_params,
+ type_params,
+ const_params,
+ impl_trait_params,
+ lifetime_params,
+ ) = def_generics.provenance_split();
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 total_len =
+ parent_params + type_params + const_params + impl_trait_params + lifetime_params;
let mut substs = Vec::with_capacity(total_len);
// handle provided arguments
@@ -1828,9 +1835,8 @@ impl InferenceContext<'_> {
for (arg, kind_id) in generic_args
.args
.iter()
- .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
- .take(type_params + const_params)
- .zip(def_generics.iter_id())
+ .take(type_params + const_params + lifetime_params)
+ .zip(def_generics.iter_id_with_lt())
{
if let Some(g) = generic_arg_to_chalk(
self.db,
@@ -1850,6 +1856,8 @@ impl InferenceContext<'_> {
DebruijnIndex::INNERMOST,
)
},
+ // FIXME: create make_lifetimes and infer lifetimes
+ |_, _| static_lifetime(),
) {
substs.push(g);
}
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index 44b35b2ebb..9a1835b625 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -11,7 +11,7 @@ use stdx::never;
use crate::{
builder::ParamKind,
- consteval,
+ consteval, error_lifetime,
method_resolution::{self, VisibleFromModule},
to_chalk_trait_id,
utils::generics,
@@ -111,6 +111,7 @@ impl InferenceContext<'_> {
it.next().unwrap_or_else(|| match x {
ParamKind::Type => self.result.standard_types.unknown.clone().cast(Interner),
ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
})
})
.build();
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index 93fd54455b..a6c5666911 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -807,6 +807,7 @@ impl<'a> InferenceTable<'a> {
.fill(|it| {
let arg = match it {
ParamKind::Type => self.new_type_var(),
+ ParamKind::Lifetime => unreachable!("Tuple with lifetime parameter"),
ParamKind::Const(_) => unreachable!("Tuple with const parameter"),
};
arg_tys.push(arg.clone());
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 97a8f8660a..f5410ca6a1 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -92,8 +92,8 @@ pub use lower::{
};
pub use mapping::{
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
- lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id, to_foreign_def_id,
- to_placeholder_idx,
+ lt_from_placeholder_idx, lt_to_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
+ to_foreign_def_id, to_placeholder_idx,
};
pub use method_resolution::check_orphan_rules;
pub use traits::TraitEnvironment;
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 3327d28479..453ac2fca7 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -34,9 +34,9 @@ use hir_def::{
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
},
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
- GenericDefId, HasModule, ImplId, InTypeConstLoc, ItemContainerId, LocalFieldId, Lookup,
- ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
- TypeParamId, UnionId, VariantId,
+ GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId, LocalFieldId,
+ Lookup, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
+ UnionId, VariantId,
};
use hir_expand::{name::Name, ExpandResult};
use intern::Interned;
@@ -377,15 +377,20 @@ impl<'a> TyLoweringContext<'a> {
list_params,
const_params,
_impl_trait_params,
+ lifetime_params,
) = if let Some(def) = self.resolver.generic_def() {
let generics = generics(self.db.upcast(), def);
generics.provenance_split()
} else {
- (0, 0, 0, 0, 0)
+ (0, 0, 0, 0, 0, 0)
};
TyKind::BoundVar(BoundVar::new(
self.in_binders,
- idx as usize + self_params + list_params + const_params,
+ idx as usize
+ + self_params
+ + list_params
+ + const_params
+ + lifetime_params,
))
.intern(Interner)
}
@@ -818,14 +823,21 @@ impl<'a> TyLoweringContext<'a> {
return Substitution::empty(Interner);
};
let def_generics = generics(self.db.upcast(), def);
- let (parent_params, self_params, type_params, const_params, impl_trait_params) =
- def_generics.provenance_split();
- let item_len = self_params + type_params + const_params + impl_trait_params;
+ let (
+ parent_params,
+ self_params,
+ type_params,
+ const_params,
+ impl_trait_params,
+ lifetime_params,
+ ) = def_generics.provenance_split();
+ let item_len =
+ self_params + type_params + const_params + impl_trait_params + lifetime_params;
let total_len = parent_params + item_len;
let ty_error = TyKind::Error.intern(Interner).cast(Interner);
- let mut def_generic_iter = def_generics.iter_id();
+ let mut def_generic_iter = def_generics.iter_id_with_lt();
let fill_self_params = || {
for x in explicit_self_ty
@@ -835,7 +847,10 @@ impl<'a> TyLoweringContext<'a> {
.take(self_params)
{
if let Some(id) = def_generic_iter.next() {
- assert!(id.is_left());
+ assert!(matches!(
+ id,
+ GenericParamId::TypeParamId(_) | GenericParamId::LifetimeParamId(_)
+ ));
substs.push(x);
}
}
@@ -847,19 +862,13 @@ impl<'a> TyLoweringContext<'a> {
fill_self_params();
}
let expected_num = if generic_args.has_self_type {
- self_params + type_params + const_params
+ self_params + type_params + const_params + lifetime_params
} else {
type_params + const_params
};
let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
// if args are provided, it should be all of them, but we can't rely on that
- for arg in generic_args
- .args
- .iter()
- .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
- .skip(skip)
- .take(expected_num)
- {
+ for arg in generic_args.args.iter().skip(skip).take(expected_num) {
if let Some(id) = def_generic_iter.next() {
if let Some(x) = generic_arg_to_chalk(
self.db,
@@ -868,6 +877,7 @@ impl<'a> TyLoweringContext<'a> {
&mut (),
|_, type_ref| self.lower_ty(type_ref),
|_, const_ref, ty| self.lower_const(const_ref, ty),
+ |_, lifetime_ref| self.lower_lifetime(lifetime_ref),
) {
had_explicit_args = true;
substs.push(x);
@@ -883,9 +893,12 @@ impl<'a> TyLoweringContext<'a> {
// These params include those of parent.
let remaining_params: SmallVec<[_; 2]> = def_generic_iter
- .map(|eid| match eid {
- Either::Left(_) => ty_error.clone(),
- Either::Right(x) => unknown_const_as_generic(self.db.const_param_ty(x)),
+ .map(|id| match id {
+ GenericParamId::ConstParamId(x) => {
+ unknown_const_as_generic(self.db.const_param_ty(x))
+ }
+ GenericParamId::TypeParamId(_) => ty_error.clone(),
+ GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
})
.collect();
assert_eq!(remaining_params.len() + substs.len(), total_len);
@@ -1719,7 +1732,7 @@ pub(crate) fn generic_defaults_query(
let generic_params = generics(db.upcast(), def);
let parent_start_idx = generic_params.len_self();
- let defaults = Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| {
+ let toc_iter = generic_params.iter().enumerate().map(|(idx, (id, p))| {
match p {
TypeOrConstParamData::TypeParamData(p) => {
let mut ty =
@@ -1747,7 +1760,14 @@ pub(crate) fn generic_defaults_query(
make_binders(db, &generic_params, val)
}
}
- }));
+ });
+
+ let lt_iter = generic_params
+ .iter_lt()
+ .enumerate()
+ .map(|_| make_binders(db, &generic_params, static_lifetime().cast(Interner)));
+
+ let defaults = Arc::from_iter(toc_iter.chain(lt_iter));
defaults
}
@@ -2127,23 +2147,29 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
/// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
pub(crate) fn generic_arg_to_chalk<'a, T>(
db: &dyn HirDatabase,
- kind_id: Either<TypeParamId, ConstParamId>,
+ kind_id: GenericParamId,
arg: &'a GenericArg,
this: &mut T,
for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
for_const: impl FnOnce(&mut T, &ConstRef, Ty) -> Const + 'a,
+ for_lifetime: impl FnOnce(&mut T, &LifetimeRef) -> Lifetime + 'a,
) -> Option<crate::GenericArg> {
let kind = match kind_id {
- Either::Left(_) => ParamKind::Type,
- Either::Right(id) => {
+ GenericParamId::TypeParamId(_) => ParamKind::Type,
+ GenericParamId::ConstParamId(id) => {
let ty = db.const_param_ty(id);
ParamKind::Const(ty)
}
+ GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime,
};
Some(match (arg, kind) {
(GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, type_ref).cast(Interner),
(GenericArg::Const(c), ParamKind::Const(c_ty)) => for_const(this, c, c_ty).cast(Interner),
+ (GenericArg::Lifetime(lifetime_ref), ParamKind::Lifetime) => {
+ for_lifetime(this, lifetime_ref).cast(Interner)
+ }
(GenericArg::Const(_), ParamKind::Type) => TyKind::Error.intern(Interner).cast(Interner),
+ (GenericArg::Lifetime(_), ParamKind::Type) => TyKind::Error.intern(Interner).cast(Interner),
(GenericArg::Type(t), ParamKind::Const(c_ty)) => {
// We want to recover simple idents, which parser detects them
// 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>(
}
unknown_const_as_generic(c_ty)
}
- (GenericArg::Lifetime(_), _) => return None,
+ (GenericArg::Lifetime(_), ParamKind::Const(c_ty)) => unknown_const_as_generic(c_ty),
+ (GenericArg::Type(_), ParamKind::Lifetime) => error_lifetime().cast(Interner),
+ (GenericArg::Const(_), ParamKind::Lifetime) => error_lifetime().cast(Interner),
})
}
diff --git a/crates/hir-ty/src/mapping.rs b/crates/hir-ty/src/mapping.rs
index 1474626039..c61d827714 100644
--- a/crates/hir-ty/src/mapping.rs
+++ b/crates/hir-ty/src/mapping.rs
@@ -151,7 +151,7 @@ pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> L
db.lookup_intern_lifetime_param_id(interned_id)
}
-pub(crate) fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> PlaceholderIndex {
+pub fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> PlaceholderIndex {
let interned_id = db.intern_lifetime_param_id(id);
PlaceholderIndex {
ui: chalk_ir::UniverseIndex::ROOT,
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index 5e084ffb08..39e7bdd962 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -367,11 +367,12 @@ impl Generics {
}
/// (parent total, self param, type param list, const param list, impl trait)
- pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize, usize) {
+ pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize, usize, usize) {
let mut self_params = 0;
let mut type_params = 0;
let mut impl_trait_params = 0;
let mut const_params = 0;
+ let mut lifetime_params = 0;
self.params.iter().for_each(|(_, data)| match data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList => type_params += 1,
@@ -381,8 +382,10 @@ impl Generics {
TypeOrConstParamData::ConstParamData(_) => const_params += 1,
});
+ self.params.iter_lt().for_each(|(_, _)| lifetime_params += 1);
+
let parent_len = self.parent_generics().map_or(0, Generics::len);
- (parent_len, self_params, type_params, const_params, impl_trait_params)
+ (parent_len, self_params, type_params, const_params, impl_trait_params, lifetime_params)
}
pub(crate) fn param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4f9697f7fe..f3065fab82 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -65,7 +65,7 @@ use hir_ty::{
consteval::{try_const_usize, unknown_const_as_generic, ConstExt},
db::InternedClosure,
diagnostics::BodyValidationDiagnostic,
- known_const_to_ast,
+ error_lifetime, known_const_to_ast,
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
method_resolution::{self, TyFingerprint},
mir::{interpret_mir, MutBorrowKind},
@@ -1106,6 +1106,7 @@ impl Field {
generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
}
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
})
.build();
let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
@@ -1447,6 +1448,7 @@ impl Adt {
match x {
ParamKind::Type => r.cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
}
})
.build();
@@ -1865,6 +1867,7 @@ impl Function {
generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
}
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
};
let parent_substs =
@@ -1963,6 +1966,7 @@ impl Function {
.unwrap_or_else(|| TyKind::Error.intern(Interner))
.cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
})
.build()
});
@@ -2221,6 +2225,7 @@ impl SelfParam {
generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
}
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
};
let parent_substs = TyBuilder::subst_for_def(db, parent_id, None).fill(&mut filler).build();
@@ -4114,6 +4119,7 @@ impl Type {
// FIXME: this code is not covered in tests.
unknown_const_as_generic(ty.clone())
}
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
}
})
.build();
@@ -4144,6 +4150,7 @@ impl Type {
match it {
ParamKind::Type => args.next().unwrap().ty.clone().cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
+ ParamKind::Lifetime => error_lifetime().cast(Interner),
}
})
.build();