fix: attribute completion

This commit is contained in:
Shunsuke Shibayama 2023-10-22 14:48:35 +09:00
parent 37f026bb0c
commit ac0ca49724
6 changed files with 175 additions and 8 deletions

View file

@ -1110,6 +1110,8 @@ impl Context {
let t = mem::take(acc.ref_mut_t().unwrap());
let mut dereferencer = Dereferencer::simple(self, qnames, acc);
*acc.ref_mut_t().unwrap() = dereferencer.deref_tyvar(t)?;
} else {
acc.ref_mut_t().unwrap().dereference();
}
if let hir::Accessor::Attr(attr) = acc {
self.resolve_expr_t(&mut attr.obj, qnames)?;

View file

@ -3757,6 +3757,90 @@ impl Type {
_ => set! { self.clone() },
}
}
pub fn dereference(&mut self) {
match self {
Self::FreeVar(fv) if fv.is_linked() => {
let new = fv.crack().clone();
*self = new;
self.dereference();
}
Self::FreeVar(fv) if fv.is_generalized() => {
fv.update_init();
}
// TODO: T(:> X, <: Y).dereference()
Self::Refinement(refine) => refine.t.dereference(),
Self::Ref(t) => {
t.dereference();
}
Self::RefMut { before, after } => {
before.dereference();
if let Some(after) = after.as_mut() {
after.dereference();
}
}
Self::Subr(sub) => {
for nd in sub.non_default_params.iter_mut() {
nd.typ_mut().dereference();
}
if let Some(var) = sub.var_params.as_mut() {
var.typ_mut().dereference();
}
for d in sub.default_params.iter_mut() {
d.typ_mut().dereference();
}
sub.return_t.dereference();
}
Self::Callable { param_ts, return_t } => {
for t in param_ts.iter_mut() {
t.dereference();
}
return_t.dereference();
}
Self::And(l, r) | Self::Or(l, r) => {
l.dereference();
r.dereference();
}
Self::Not(ty) => {
ty.dereference();
}
Self::Bounded { sub, sup } => {
sub.dereference();
sup.dereference();
}
Self::Quantified(ty) | Self::Structural(ty) => {
ty.dereference();
}
Self::Record(rec) => {
for v in rec.values_mut() {
v.dereference();
}
}
Self::NamedTuple(r) => {
for (_, v) in r.iter_mut() {
v.dereference();
}
}
Self::Proj { lhs, .. } => {
lhs.dereference();
}
Self::ProjCall { lhs, args, .. } => {
lhs.dereference();
for arg in args.iter_mut() {
arg.dereference();
}
}
Self::Poly { params, .. } => {
for param in params.iter_mut() {
param.dereference();
}
}
Self::Guard(guard) => {
guard.to.dereference();
}
_ => {}
}
}
}
pub struct ReplaceTable<'t> {

View file

@ -1543,6 +1543,76 @@ impl TyParam {
_ => set! {},
}
}
pub fn dereference(&mut self) {
match self {
Self::FreeVar(fv) if fv.is_linked() => {
let new = fv.crack().clone();
*self = new;
self.dereference();
}
Self::FreeVar(fv) if fv.is_generalized() => {
fv.update_init();
}
Self::Type(t) => t.dereference(),
Self::Value(ValueObj::Type(t)) => t.typ_mut().dereference(),
Self::App { args, .. } => {
for arg in args {
arg.dereference();
}
}
Self::Proj { obj, .. } => obj.dereference(),
Self::ProjCall { obj, args, .. } => {
obj.dereference();
for arg in args {
arg.dereference();
}
}
Self::Array(ts) | Self::Tuple(ts) => {
for t in ts {
t.dereference();
}
}
Self::Set(ts) => {
let ts_ = std::mem::take(ts);
*ts = ts_
.into_iter()
.map(|mut t| {
t.dereference();
t
})
.collect();
}
Self::Dict(ts) => {
let ts_ = std::mem::take(ts);
*ts = ts_
.into_iter()
.map(|(mut k, mut v)| {
k.dereference();
v.dereference();
(k, v)
})
.collect();
}
Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
for (_, t) in rec.iter_mut() {
t.dereference();
}
}
Self::Lambda(lambda) => {
for t in &mut lambda.body {
t.dereference();
}
}
Self::UnaryOp { val, .. } => val.dereference(),
Self::BinOp { lhs, rhs, .. } => {
lhs.dereference();
rhs.dereference();
}
Self::Erased(t) => t.dereference(),
_ => {}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]