mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 18:29:00 +00:00
feat(els): display type bounds as inlay hints
This commit is contained in:
parent
855d47f02c
commit
7103c9f3bb
6 changed files with 123 additions and 57 deletions
|
@ -1,6 +1,8 @@
|
|||
use std::mem;
|
||||
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::Str;
|
||||
use erg_common::{assume_unreachable, fn_name};
|
||||
use erg_common::{dict, set};
|
||||
#[allow(unused_imports)]
|
||||
|
@ -728,7 +730,7 @@ impl Context {
|
|||
self.level = 0;
|
||||
let mut errs = TyCheckErrors::empty();
|
||||
for chunk in hir.module.iter_mut() {
|
||||
if let Err(es) = self.resolve_expr_t(chunk) {
|
||||
if let Err(es) = self.resolve_expr_t(chunk, &mut set! {}) {
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
|
@ -762,38 +764,50 @@ impl Context {
|
|||
self.methods_list = methods_list;
|
||||
}
|
||||
|
||||
fn resolve_params_t(&self, params: &mut hir::Params) -> TyCheckResult<()> {
|
||||
fn resolve_params_t(
|
||||
&self,
|
||||
params: &mut hir::Params,
|
||||
qvars: &mut Set<Str>,
|
||||
) -> TyCheckResult<()> {
|
||||
for param in params.non_defaults.iter_mut() {
|
||||
param.vi.t = self.deref_tyvar(mem::take(&mut param.vi.t), Contravariant, param)?;
|
||||
if !qvars.contains(¶m.vi.t.qual_name()) {
|
||||
param.vi.t = self.deref_tyvar(mem::take(&mut param.vi.t), Contravariant, param)?;
|
||||
}
|
||||
}
|
||||
if let Some(var_params) = &mut params.var_params {
|
||||
var_params.vi.t = self.deref_tyvar(
|
||||
mem::take(&mut var_params.vi.t),
|
||||
Contravariant,
|
||||
var_params.as_ref(),
|
||||
)?;
|
||||
if !qvars.contains(&var_params.vi.t.qual_name()) {
|
||||
var_params.vi.t = self.deref_tyvar(
|
||||
mem::take(&mut var_params.vi.t),
|
||||
Contravariant,
|
||||
var_params.as_ref(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
for param in params.defaults.iter_mut() {
|
||||
param.sig.vi.t =
|
||||
self.deref_tyvar(mem::take(&mut param.sig.vi.t), Contravariant, param)?;
|
||||
self.resolve_expr_t(&mut param.default_val)?;
|
||||
if !qvars.contains(¶m.sig.vi.t.qual_name()) {
|
||||
param.sig.vi.t =
|
||||
self.deref_tyvar(mem::take(&mut param.sig.vi.t), Contravariant, param)?;
|
||||
}
|
||||
self.resolve_expr_t(&mut param.default_val, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_expr_t(&self, expr: &mut hir::Expr) -> TyCheckResult<()> {
|
||||
fn resolve_expr_t(&self, expr: &mut hir::Expr, qvars: &mut Set<Str>) -> TyCheckResult<()> {
|
||||
match expr {
|
||||
hir::Expr::Lit(_) => Ok(()),
|
||||
hir::Expr::Accessor(acc) => {
|
||||
let variance = if acc.var_info().kind.is_parameter() {
|
||||
Contravariant
|
||||
} else {
|
||||
Covariant
|
||||
};
|
||||
let t = mem::take(acc.ref_mut_t());
|
||||
*acc.ref_mut_t() = self.deref_tyvar(t, variance, acc)?;
|
||||
if !qvars.contains(&acc.ref_t().qual_name()) {
|
||||
let variance = if acc.var_info().kind.is_parameter() {
|
||||
Contravariant
|
||||
} else {
|
||||
Covariant
|
||||
};
|
||||
let t = mem::take(acc.ref_mut_t());
|
||||
*acc.ref_mut_t() = self.deref_tyvar(t, variance, acc)?;
|
||||
}
|
||||
if let hir::Accessor::Attr(attr) = acc {
|
||||
self.resolve_expr_t(&mut attr.obj)?;
|
||||
self.resolve_expr_t(&mut attr.obj, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -801,14 +815,14 @@ impl Context {
|
|||
hir::Array::Normal(arr) => {
|
||||
arr.t = self.deref_tyvar(mem::take(&mut arr.t), Covariant, arr)?;
|
||||
for elem in arr.elems.pos_args.iter_mut() {
|
||||
self.resolve_expr_t(&mut elem.expr)?;
|
||||
self.resolve_expr_t(&mut elem.expr, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Array::WithLength(arr) => {
|
||||
arr.t = self.deref_tyvar(mem::take(&mut arr.t), Covariant, arr)?;
|
||||
self.resolve_expr_t(&mut arr.elem)?;
|
||||
self.resolve_expr_t(&mut arr.len)?;
|
||||
self.resolve_expr_t(&mut arr.elem, qvars)?;
|
||||
self.resolve_expr_t(&mut arr.len, qvars)?;
|
||||
Ok(())
|
||||
}
|
||||
other => feature_error!(
|
||||
|
@ -823,7 +837,7 @@ impl Context {
|
|||
hir::Tuple::Normal(tup) => {
|
||||
tup.t = self.deref_tyvar(mem::take(&mut tup.t), Covariant, tup)?;
|
||||
for elem in tup.elems.pos_args.iter_mut() {
|
||||
self.resolve_expr_t(&mut elem.expr)?;
|
||||
self.resolve_expr_t(&mut elem.expr, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -832,14 +846,14 @@ impl Context {
|
|||
hir::Set::Normal(st) => {
|
||||
st.t = self.deref_tyvar(mem::take(&mut st.t), Covariant, st)?;
|
||||
for elem in st.elems.pos_args.iter_mut() {
|
||||
self.resolve_expr_t(&mut elem.expr)?;
|
||||
self.resolve_expr_t(&mut elem.expr, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Set::WithLength(st) => {
|
||||
st.t = self.deref_tyvar(mem::take(&mut st.t), Covariant, st)?;
|
||||
self.resolve_expr_t(&mut st.elem)?;
|
||||
self.resolve_expr_t(&mut st.len)?;
|
||||
self.resolve_expr_t(&mut st.elem, qvars)?;
|
||||
self.resolve_expr_t(&mut st.len, qvars)?;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
|
@ -847,8 +861,8 @@ impl Context {
|
|||
hir::Dict::Normal(dic) => {
|
||||
dic.t = self.deref_tyvar(mem::take(&mut dic.t), Covariant, dic)?;
|
||||
for kv in dic.kvs.iter_mut() {
|
||||
self.resolve_expr_t(&mut kv.key)?;
|
||||
self.resolve_expr_t(&mut kv.value)?;
|
||||
self.resolve_expr_t(&mut kv.key, qvars)?;
|
||||
self.resolve_expr_t(&mut kv.value, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -874,7 +888,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
for chunk in attr.body.block.iter_mut() {
|
||||
self.resolve_expr_t(chunk)?;
|
||||
self.resolve_expr_t(chunk, qvars)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -882,14 +896,14 @@ impl Context {
|
|||
hir::Expr::BinOp(binop) => {
|
||||
let t = mem::take(binop.signature_mut_t().unwrap());
|
||||
*binop.signature_mut_t().unwrap() = self.deref_tyvar(t, Covariant, binop)?;
|
||||
self.resolve_expr_t(&mut binop.lhs)?;
|
||||
self.resolve_expr_t(&mut binop.rhs)?;
|
||||
self.resolve_expr_t(&mut binop.lhs, qvars)?;
|
||||
self.resolve_expr_t(&mut binop.rhs, qvars)?;
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::UnaryOp(unaryop) => {
|
||||
let t = mem::take(unaryop.signature_mut_t().unwrap());
|
||||
*unaryop.signature_mut_t().unwrap() = self.deref_tyvar(t, Covariant, unaryop)?;
|
||||
self.resolve_expr_t(&mut unaryop.expr)?;
|
||||
self.resolve_expr_t(&mut unaryop.expr, qvars)?;
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::Call(call) => {
|
||||
|
@ -897,66 +911,78 @@ impl Context {
|
|||
let t = mem::take(t);
|
||||
*call.signature_mut_t().unwrap() = self.deref_tyvar(t, Covariant, call)?;
|
||||
}
|
||||
self.resolve_expr_t(&mut call.obj)?;
|
||||
self.resolve_expr_t(&mut call.obj, qvars)?;
|
||||
for arg in call.args.pos_args.iter_mut() {
|
||||
self.resolve_expr_t(&mut arg.expr)?;
|
||||
self.resolve_expr_t(&mut arg.expr, qvars)?;
|
||||
}
|
||||
if let Some(var_args) = &mut call.args.var_args {
|
||||
self.resolve_expr_t(&mut var_args.expr)?;
|
||||
self.resolve_expr_t(&mut var_args.expr, qvars)?;
|
||||
}
|
||||
for arg in call.args.kw_args.iter_mut() {
|
||||
self.resolve_expr_t(&mut arg.expr)?;
|
||||
self.resolve_expr_t(&mut arg.expr, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::Def(def) => {
|
||||
*def.sig.ref_mut_t() =
|
||||
self.deref_tyvar(mem::take(def.sig.ref_mut_t()), Covariant, &def.sig)?;
|
||||
let subr_qvars_ = def.sig.ref_t().qvars();
|
||||
let subr_qvars = subr_qvars_.clone().into_iter().map(|(name, _)| name);
|
||||
qvars.extend(subr_qvars);
|
||||
if let Some(params) = def.sig.params_mut() {
|
||||
self.resolve_params_t(params)?;
|
||||
self.resolve_params_t(params, qvars)?;
|
||||
}
|
||||
for chunk in def.body.block.iter_mut() {
|
||||
self.resolve_expr_t(chunk)?;
|
||||
self.resolve_expr_t(chunk, qvars)?;
|
||||
}
|
||||
for (name, _) in subr_qvars_.into_iter() {
|
||||
qvars.remove(&name);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::Lambda(lambda) => {
|
||||
lambda.t = self.deref_tyvar(mem::take(&mut lambda.t), Covariant, lambda)?;
|
||||
self.resolve_params_t(&mut lambda.params)?;
|
||||
let subr_qvars_ = lambda.ref_t().qvars();
|
||||
let subr_qvars = subr_qvars_.clone().into_iter().map(|(name, _)| name);
|
||||
qvars.extend(subr_qvars);
|
||||
self.resolve_params_t(&mut lambda.params, qvars)?;
|
||||
for chunk in lambda.body.iter_mut() {
|
||||
self.resolve_expr_t(chunk)?;
|
||||
self.resolve_expr_t(chunk, qvars)?;
|
||||
}
|
||||
for (name, _) in subr_qvars_.into_iter() {
|
||||
qvars.remove(&name);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::ClassDef(class_def) => {
|
||||
for def in class_def.methods.iter_mut() {
|
||||
self.resolve_expr_t(def)?;
|
||||
self.resolve_expr_t(def, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::PatchDef(patch_def) => {
|
||||
for def in patch_def.methods.iter_mut() {
|
||||
self.resolve_expr_t(def)?;
|
||||
self.resolve_expr_t(def, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::ReDef(redef) => {
|
||||
// REVIEW: redef.attr is not dereferenced
|
||||
for chunk in redef.block.iter_mut() {
|
||||
self.resolve_expr_t(chunk)?;
|
||||
self.resolve_expr_t(chunk, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::TypeAsc(tasc) => self.resolve_expr_t(&mut tasc.expr),
|
||||
hir::Expr::TypeAsc(tasc) => self.resolve_expr_t(&mut tasc.expr, qvars),
|
||||
hir::Expr::Code(chunks) | hir::Expr::Compound(chunks) => {
|
||||
for chunk in chunks.iter_mut() {
|
||||
self.resolve_expr_t(chunk)?;
|
||||
self.resolve_expr_t(chunk, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
hir::Expr::Dummy(chunks) => {
|
||||
for chunk in chunks.iter_mut() {
|
||||
self.resolve_expr_t(chunk)?;
|
||||
self.resolve_expr_t(chunk, qvars)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue