feat: IDE features for primitive tuple fields

This commit is contained in:
Lukas Wirth 2024-01-06 15:04:58 +01:00
parent 59457091bb
commit 963568b46f
25 changed files with 242 additions and 96 deletions

View file

@ -14,9 +14,10 @@ use crate::{
};
use base_db::CrateId;
use chalk_ir::Mutability;
use either::Either;
use hir_def::{
hir::{BindingId, Expr, ExprId, Ordering, PatId},
DefWithBodyId, FieldId, StaticId, UnionId, VariantId,
DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId,
};
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
@ -124,9 +125,9 @@ impl Operand {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ProjectionElem<V, T> {
Deref,
Field(FieldId),
Field(Either<FieldId, TupleFieldId>),
// FIXME: get rid of this, and use FieldId for tuples and closures
TupleOrClosureField(usize),
ClosureField(usize),
Index(V),
ConstantIndex { offset: u64, from_end: bool },
Subslice { from: u64, to: u64 },
@ -161,7 +162,7 @@ impl<V, T> ProjectionElem<V, T> {
return TyKind::Error.intern(Interner);
}
},
ProjectionElem::Field(f) => match &base.kind(Interner) {
ProjectionElem::Field(Either::Left(f)) => match &base.kind(Interner) {
TyKind::Adt(_, subst) => {
db.field_types(f.parent)[f.local_id].clone().substitute(Interner, subst)
}
@ -170,19 +171,25 @@ impl<V, T> ProjectionElem<V, T> {
return TyKind::Error.intern(Interner);
}
},
ProjectionElem::TupleOrClosureField(f) => match &base.kind(Interner) {
ProjectionElem::Field(Either::Right(f)) => match &base.kind(Interner) {
TyKind::Tuple(_, subst) => subst
.as_slice(Interner)
.get(*f)
.get(f.index as usize)
.map(|x| x.assert_ty_ref(Interner))
.cloned()
.unwrap_or_else(|| {
never!("Out of bound tuple field");
TyKind::Error.intern(Interner)
}),
_ => {
never!("Only tuple has tuple field");
return TyKind::Error.intern(Interner);
}
},
ProjectionElem::ClosureField(f) => match &base.kind(Interner) {
TyKind::Closure(id, subst) => closure_field(*id, subst, *f),
_ => {
never!("Only tuple or closure has tuple or closure field");
never!("Only closure has closure field");
return TyKind::Error.intern(Interner);
}
},