Fixed typevar with fixed range #238
|
@ -38,7 +38,7 @@ use tempfile::{self, TempDir};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::{rpc_codegen_callback, ArtiqCodeGenerator},
|
codegen::{rpc_codegen_callback, ArtiqCodeGenerator},
|
||||||
symbol_resolver::{InnerResolver, PythonHelper, Resolver},
|
symbol_resolver::{InnerResolver, PythonHelper, Resolver, DeferredEvaluationStore},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod codegen;
|
mod codegen;
|
||||||
|
@ -89,6 +89,7 @@ struct Nac3 {
|
||||||
top_levels: Vec<TopLevelComponent>,
|
top_levels: Vec<TopLevelComponent>,
|
||||||
string_store: Arc<RwLock<HashMap<String, i32>>>,
|
string_store: Arc<RwLock<HashMap<String, i32>>>,
|
||||||
exception_ids: Arc<RwLock<HashMap<usize, usize>>>,
|
exception_ids: Arc<RwLock<HashMap<usize, usize>>>,
|
||||||
|
deferred_eval_store: DeferredEvaluationStore
|
||||||
}
|
}
|
||||||
|
|
||||||
create_exception!(nac3artiq, CompileError, exceptions::PyException);
|
create_exception!(nac3artiq, CompileError, exceptions::PyException);
|
||||||
|
@ -400,6 +401,7 @@ impl Nac3 {
|
||||||
working_directory,
|
working_directory,
|
||||||
string_store: Default::default(),
|
string_store: Default::default(),
|
||||||
exception_ids: Default::default(),
|
exception_ids: Default::default(),
|
||||||
|
deferred_eval_store: DeferredEvaluationStore::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,6 +524,7 @@ impl Nac3 {
|
||||||
helper,
|
helper,
|
||||||
string_store: self.string_store.clone(),
|
string_store: self.string_store.clone(),
|
||||||
exception_ids: self.exception_ids.clone(),
|
exception_ids: self.exception_ids.clone(),
|
||||||
|
deferred_eval_store: self.deferred_eval_store.clone(),
|
||||||
})))
|
})))
|
||||||
as Arc<dyn SymbolResolver + Send + Sync>;
|
as Arc<dyn SymbolResolver + Send + Sync>;
|
||||||
let name_to_pyid = Rc::new(name_to_pyid);
|
let name_to_pyid = Rc::new(name_to_pyid);
|
||||||
|
@ -607,6 +610,7 @@ impl Nac3 {
|
||||||
helper,
|
helper,
|
||||||
string_store: self.string_store.clone(),
|
string_store: self.string_store.clone(),
|
||||||
exception_ids: self.exception_ids.clone(),
|
exception_ids: self.exception_ids.clone(),
|
||||||
|
deferred_eval_store: self.deferred_eval_store.clone(),
|
||||||
}))) as Arc<dyn SymbolResolver + Send + Sync>;
|
}))) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||||
let (_, def_id, _) = composer
|
let (_, def_id, _) = composer
|
||||||
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into())
|
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into())
|
||||||
|
|
|
@ -16,7 +16,10 @@ use pyo3::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
sync::Arc,
|
sync::{
|
||||||
|
Arc,
|
||||||
|
atomic::{AtomicBool, Ordering::Relaxed}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::PrimitivePythonId;
|
use crate::PrimitivePythonId;
|
||||||
|
@ -30,6 +33,21 @@ pub enum PrimitiveValue {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct DeferredEvaluationStore {
|
||||||
|
needs_defer: Arc<AtomicBool>,
|
||||||
|
store: Arc<RwLock<Vec<(Vec<Type>, PyObject, String)>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeferredEvaluationStore {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
DeferredEvaluationStore {
|
||||||
|
needs_defer: Arc::new(AtomicBool::new(true)),
|
||||||
|
store: Arc::new(RwLock::new(Vec::new())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct InnerResolver {
|
pub struct InnerResolver {
|
||||||
pub id_to_type: RwLock<HashMap<StrRef, Type>>,
|
pub id_to_type: RwLock<HashMap<StrRef, Type>>,
|
||||||
pub id_to_def: RwLock<HashMap<StrRef, DefinitionId>>,
|
pub id_to_def: RwLock<HashMap<StrRef, DefinitionId>>,
|
||||||
|
@ -44,6 +62,7 @@ pub struct InnerResolver {
|
||||||
pub helper: PythonHelper,
|
pub helper: PythonHelper,
|
||||||
pub string_store: Arc<RwLock<HashMap<String, i32>>>,
|
pub string_store: Arc<RwLock<HashMap<String, i32>>>,
|
||||||
pub exception_ids: Arc<RwLock<HashMap<usize, usize>>>,
|
pub exception_ids: Arc<RwLock<HashMap<usize, usize>>>,
|
||||||
|
pub deferred_eval_store: DeferredEvaluationStore,
|
||||||
// module specific
|
// module specific
|
||||||
pub name_to_pyid: HashMap<StrRef, u64>,
|
pub name_to_pyid: HashMap<StrRef, u64>,
|
||||||
pub module: PyObject,
|
pub module: PyObject,
|
||||||
|
@ -298,8 +317,12 @@ impl InnerResolver {
|
||||||
let constraint_types = {
|
let constraint_types = {
|
||||||
let constraints = pyty.getattr("__constraints__").unwrap();
|
let constraints = pyty.getattr("__constraints__").unwrap();
|
||||||
let mut result: Vec<Type> = vec![];
|
let mut result: Vec<Type> = vec![];
|
||||||
|
let needs_defer = self.deferred_eval_store.needs_defer.load(Relaxed);
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
if let Ok(constr) = constraints.get_item(i) {
|
if let Ok(constr) = constraints.get_item(i) {
|
||||||
|
if needs_defer {
|
||||||
|
result.push(unifier.get_dummy_var().0);
|
||||||
|
} else {
|
||||||
result.push({
|
result.push({
|
||||||
match self.get_pyty_obj_type(py, constr, unifier, defs, primitives)? {
|
match self.get_pyty_obj_type(py, constr, unifier, defs, primitives)? {
|
||||||
Ok((ty, _)) => {
|
Ok((ty, _)) => {
|
||||||
|
@ -316,10 +339,18 @@ impl InnerResolver {
|
||||||
Err(err) => return Ok(Err(err)),
|
Err(err) => return Ok(Err(err)),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if needs_defer {
|
||||||
|
self.deferred_eval_store.store.write()
|
||||||
|
.push((result.clone(),
|
||||||
|
constraints.extract()?,
|
||||||
|
pyty.getattr("__name__")?.extract::<String>()?
|
||||||
|
))
|
||||||
|
}
|
||||||
result
|
result
|
||||||
};
|
};
|
||||||
let res =
|
let res =
|
||||||
|
@ -908,15 +939,14 @@ impl SymbolResolver for Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(t) = sym_ty {
|
if let Ok(t) = sym_ty {
|
||||||
|
if let TypeEnum::TVar { .. } = &*unifier.get_ty(t) {
|
||||||
self.0.pyid_to_type.write().insert(*id, t);
|
self.0.pyid_to_type.write().insert(*id, t);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(sym_ty)
|
Ok(sym_ty)
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
};
|
};
|
||||||
if let Ok(t) = &result {
|
|
||||||
self.0.id_to_type.write().insert(str, *t);
|
|
||||||
}
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -992,6 +1022,45 @@ impl SymbolResolver for Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_deferred_eval(
|
||||||
|
&self,
|
||||||
|
unifier: &mut Unifier,
|
||||||
|
defs: &[Arc<RwLock<TopLevelDef>>],
|
||||||
|
primitives: &PrimitiveStore
|
||||||
|
) -> Result<(), String> {
|
||||||
|
// we don't need a lock because this will only be run in a single thread
|
||||||
|
if self.0.deferred_eval_store.needs_defer.load(Relaxed) {
|
||||||
|
self.0.deferred_eval_store.needs_defer.store(false, Relaxed);
|
||||||
|
let store = self.0.deferred_eval_store.store.read();
|
||||||
|
Python::with_gil(|py| -> PyResult<Result<(), String>> {
|
||||||
|
for (variables, constraints, name) in store.iter() {
|
||||||
|
let constraints: &PyAny = constraints.as_ref(py);
|
||||||
|
for (i, var) in variables.iter().enumerate() {
|
||||||
|
if let Ok(constr) = constraints.get_item(i) {
|
||||||
|
match self.0.get_pyty_obj_type(py, constr, unifier, defs, primitives)? {
|
||||||
|
Ok((ty, _)) => {
|
||||||
|
if !unifier.is_concrete(ty, &[]) {
|
||||||
|
return Ok(Err(format!(
|
||||||
|
"the {}th constraint of TypeVar `{}` is not concrete",
|
||||||
|
i + 1,
|
||||||
|
name,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
unifier.unify(ty, *var).unwrap()
|
||||||
|
}
|
||||||
|
Err(err) => return Ok(Err(err)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Ok(()))
|
||||||
|
}).unwrap()?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_exception_id(&self, tyid: usize) -> usize {
|
fn get_exception_id(&self, tyid: usize) -> usize {
|
||||||
let exn_ids = self.0.exception_ids.read();
|
let exn_ids = self.0.exception_ids.read();
|
||||||
exn_ids.get(&tyid).cloned().unwrap_or(0)
|
exn_ids.get(&tyid).cloned().unwrap_or(0)
|
||||||
|
|
|
@ -496,7 +496,13 @@ pub fn gen_func_instance<'ctx, 'a>(
|
||||||
}
|
}
|
||||||
let symbol = format!("{}.{}", name, instance_to_symbol.len());
|
let symbol = format!("{}.{}", name, instance_to_symbol.len());
|
||||||
instance_to_symbol.insert(key, symbol.clone());
|
instance_to_symbol.insert(key, symbol.clone());
|
||||||
let key = ctx.get_subst_key(obj.as_ref().map(|a| a.0), sign, Some(var_id));
|
let mut filter = var_id.clone();
|
||||||
|
if let Some((obj_ty, _)) = &obj {
|
||||||
|
if let TypeEnum::TObj { params, .. } = &*ctx.unifier.get_ty(*obj_ty) {
|
||||||
|
filter.extend(params.keys());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let key = ctx.get_subst_key(obj.as_ref().map(|a| a.0), sign, Some(&filter));
|
||||||
let instance = instance_to_stmt.get(&key).unwrap();
|
let instance = instance_to_stmt.get(&key).unwrap();
|
||||||
|
|
||||||
let mut store = ConcreteTypeStore::new();
|
let mut store = ConcreteTypeStore::new();
|
||||||
|
|
|
@ -141,7 +141,15 @@ pub trait SymbolResolver {
|
||||||
fn get_default_param_value(&self, expr: &nac3parser::ast::Expr) -> Option<SymbolValue>;
|
fn get_default_param_value(&self, expr: &nac3parser::ast::Expr) -> Option<SymbolValue>;
|
||||||
fn get_string_id(&self, s: &str) -> i32;
|
fn get_string_id(&self, s: &str) -> i32;
|
||||||
fn get_exception_id(&self, tyid: usize) -> usize;
|
fn get_exception_id(&self, tyid: usize) -> usize;
|
||||||
// handle function call etc.
|
|
||||||
|
fn handle_deferred_eval(
|
||||||
|
&self,
|
||||||
|
_unifier: &mut Unifier,
|
||||||
|
_top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
||||||
|
_primitives: &PrimitiveStore
|
||||||
|
) -> Result<(), String> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
|
|
@ -775,6 +775,18 @@ impl TopLevelComposer {
|
||||||
return Err(errors.into_iter().sorted().join("\n----------\n"));
|
return Err(errors.into_iter().sorted().join("\n----------\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (def, _) in def_ast_list.iter().skip(self.builtin_num) {
|
||||||
|
match &*def.read() {
|
||||||
|
TopLevelDef::Class { resolver: Some(resolver), .. }
|
||||||
|
| TopLevelDef::Function { resolver: Some(resolver), .. } => {
|
||||||
|
if let Err(e) = resolver.handle_deferred_eval(unifier, &temp_def_list, primitives) {
|
||||||
|
errors.insert(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,17 +1069,7 @@ impl TopLevelComposer {
|
||||||
let (method_dummy_ty, method_id) =
|
let (method_dummy_ty, method_id) =
|
||||||
Self::get_class_method_def_info(class_methods_def, *name)?;
|
Self::get_class_method_def_info(class_methods_def, *name)?;
|
||||||
|
|
||||||
// the method var map can surely include the class's generic parameters
|
let mut method_var_map: HashMap<u32, Type> = HashMap::new();
|
||||||
let mut method_var_map: HashMap<u32, Type> = class_type_vars_def
|
|
||||||
.iter()
|
|
||||||
.map(|ty| {
|
|
||||||
if let TypeEnum::TVar { id, .. } = unifier.get_ty(*ty).as_ref() {
|
|
||||||
(*id, *ty)
|
|
||||||
} else {
|
|
||||||
unreachable!("must be type var here")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let arg_types: Vec<FuncArg> = {
|
let arg_types: Vec<FuncArg> = {
|
||||||
// check method parameters cannot have same name
|
// check method parameters cannot have same name
|
||||||
|
@ -1494,8 +1496,8 @@ impl TopLevelComposer {
|
||||||
if new_var_ids != *var_id {
|
if new_var_ids != *var_id {
|
||||||
let new_signature = FunSignature {
|
let new_signature = FunSignature {
|
||||||
args: args.clone(),
|
args: args.clone(),
|
||||||
ret: ret.clone(),
|
ret: *ret,
|
||||||
vars: new_var_ids.iter().zip(vars.values()).map(|(id, v)| (*id, v.clone())).collect(),
|
vars: new_var_ids.iter().zip(vars.values()).map(|(id, v)| (*id, *v)).collect(),
|
||||||
};
|
};
|
||||||
unifier.unification_table.set_value(*signature, Rc::new(TypeEnum::TFunc(new_signature)));
|
unifier.unification_table.set_value(*signature, Rc::new(TypeEnum::TFunc(new_signature)));
|
||||||
*var_id = new_var_ids;
|
*var_id = new_var_ids;
|
||||||
|
@ -1674,13 +1676,13 @@ impl TopLevelComposer {
|
||||||
simple_name,
|
simple_name,
|
||||||
signature,
|
signature,
|
||||||
resolver,
|
resolver,
|
||||||
var_id: insted_vars,
|
|
||||||
..
|
..
|
||||||
} = &mut *function_def
|
} = &mut *function_def
|
||||||
{
|
{
|
||||||
if let TypeEnum::TFunc(FunSignature { args, ret, vars }) =
|
if let TypeEnum::TFunc(FunSignature { args, ret, vars }) =
|
||||||
unifier.get_ty(*signature).as_ref()
|
unifier.get_ty(*signature).as_ref()
|
||||||
{
|
{
|
||||||
|
let mut vars = vars.clone();
|
||||||
// None if is not class method
|
// None if is not class method
|
||||||
let uninst_self_type = {
|
let uninst_self_type = {
|
||||||
if let Some(class_id) = method_class.get(&DefinitionId(id)) {
|
if let Some(class_id) = method_class.get(&DefinitionId(id)) {
|
||||||
|
@ -1695,6 +1697,12 @@ impl TopLevelComposer {
|
||||||
&ty_ann,
|
&ty_ann,
|
||||||
&mut None
|
&mut None
|
||||||
)?;
|
)?;
|
||||||
|
vars.extend(type_vars.iter().map(|ty|
|
||||||
|
if let TypeEnum::TVar { id, .. } = &*unifier.get_ty(*ty) {
|
||||||
|
(*id, *ty)
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}));
|
||||||
Some((self_ty, type_vars.clone()))
|
Some((self_ty, type_vars.clone()))
|
||||||
} else {
|
} else {
|
||||||
unreachable!("must be class def")
|
unreachable!("must be class def")
|
||||||
|
@ -1725,7 +1733,7 @@ impl TopLevelComposer {
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
let mut result: Vec<HashMap<u32, Type>> = Default::default();
|
let mut result: Vec<HashMap<u32, Type>> = Default::default();
|
||||||
for comb in var_combs {
|
for comb in var_combs {
|
||||||
result.push(insted_vars.clone().into_iter().zip(comb).collect());
|
result.push(vars.keys().cloned().zip(comb).collect());
|
||||||
}
|
}
|
||||||
// NOTE: if is empty, means no type var, append a empty subst, ok to do this?
|
// NOTE: if is empty, means no type var, append a empty subst, ok to do this?
|
||||||
if result.is_empty() {
|
if result.is_empty() {
|
||||||
|
@ -1913,7 +1921,7 @@ impl TopLevelComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
instance_to_stmt.insert(
|
instance_to_stmt.insert(
|
||||||
get_subst_key(unifier, self_type, &subst, Some(insted_vars)),
|
get_subst_key(unifier, self_type, &subst, Some(&vars.keys().cloned().collect())),
|
||||||
FunInstance {
|
FunInstance {
|
||||||
body: Arc::new(fun_body),
|
body: Arc::new(fun_body),
|
||||||
unifier_id: 0,
|
unifier_id: 0,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
source: nac3core/src/toplevel/test.rs
|
source: nac3core/src/toplevel/test.rs
|
||||||
assertion_line: 540
|
assertion_line: 549
|
||||||
expression: res_vec
|
expression: res_vec
|
||||||
|
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
"Class {\nname: \"Generic_A\",\nancestors: [\"{class: Generic_A, params: [\\\"V\\\"]}\", \"{class: B, params: []}\"],\nfields: [\"aa\", \"a\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"foo\", \"fn[[b:T], none]\"), (\"fun\", \"fn[[a:int32], V]\")],\ntype_vars: [\"V\"]\n}\n",
|
"Class {\nname: \"Generic_A\",\nancestors: [\"{class: Generic_A, params: [\\\"V\\\"]}\", \"{class: B, params: []}\"],\nfields: [\"aa\", \"a\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"foo\", \"fn[[b:T], none]\"), (\"fun\", \"fn[[a:int32], V]\")],\ntype_vars: [\"V\"]\n}\n",
|
||||||
"Function {\nname: \"Generic_A.__init__\",\nsig: \"fn[[], none]\",\nvar_id: [6]\n}\n",
|
"Function {\nname: \"Generic_A.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||||
"Function {\nname: \"Generic_A.fun\",\nsig: \"fn[[a:int32], V]\",\nvar_id: [6, 17]\n}\n",
|
"Function {\nname: \"Generic_A.fun\",\nsig: \"fn[[a:int32], V]\",\nvar_id: [17]\n}\n",
|
||||||
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: []}\"],\nfields: [\"aa\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"foo\", \"fn[[b:T], none]\")],\ntype_vars: []\n}\n",
|
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: []}\"],\nfields: [\"aa\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"foo\", \"fn[[b:T], none]\")],\ntype_vars: []\n}\n",
|
||||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||||
"Function {\nname: \"B.foo\",\nsig: \"fn[[b:T], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"B.foo\",\nsig: \"fn[[b:T], none]\",\nvar_id: []\n}\n",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: nac3core/src/toplevel/test.rs
|
source: nac3core/src/toplevel/test.rs
|
||||||
assertion_line: 540
|
assertion_line: 549
|
||||||
expression: res_vec
|
expression: res_vec
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -10,8 +10,8 @@ expression: res_vec
|
||||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\",\nvar_id: []\n}\n",
|
||||||
"Function {\nname: \"A.foo\",\nsig: \"fn[[c:C], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"A.foo\",\nsig: \"fn[[c:C], none]\",\nvar_id: []\n}\n",
|
||||||
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: [\\\"var6\\\"]}\", \"{class: A, params: [\\\"float\\\"]}\"],\nfields: [\"a\", \"b\", \"c\", \"d\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: [\"var6\"]\n}\n",
|
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: [\\\"var6\\\"]}\", \"{class: A, params: [\\\"float\\\"]}\"],\nfields: [\"a\", \"b\", \"c\", \"d\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: [\"var6\"]\n}\n",
|
||||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: [6]\n}\n",
|
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||||
"Function {\nname: \"B.fun\",\nsig: \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\",\nvar_id: [6]\n}\n",
|
"Function {\nname: \"B.fun\",\nsig: \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\",\nvar_id: []\n}\n",
|
||||||
"Class {\nname: \"C\",\nancestors: [\"{class: C, params: []}\", \"{class: B, params: [\\\"bool\\\"]}\", \"{class: A, params: [\\\"float\\\"]}\"],\nfields: [\"a\", \"b\", \"c\", \"d\", \"e\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: []\n}\n",
|
"Class {\nname: \"C\",\nancestors: [\"{class: C, params: []}\", \"{class: B, params: [\\\"bool\\\"]}\", \"{class: A, params: [\\\"float\\\"]}\"],\nfields: [\"a\", \"b\", \"c\", \"d\", \"e\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: []\n}\n",
|
||||||
"Function {\nname: \"C.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"C.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
---
|
---
|
||||||
source: nac3core/src/toplevel/test.rs
|
source: nac3core/src/toplevel/test.rs
|
||||||
assertion_line: 540
|
assertion_line: 549
|
||||||
expression: res_vec
|
expression: res_vec
|
||||||
|
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
"Function {\nname: \"foo\",\nsig: \"fn[[a:list[int32], b:tuple[T, float]], A[B, bool]]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"foo\",\nsig: \"fn[[a:list[int32], b:tuple[T, float]], A[B, bool]]\",\nvar_id: []\n}\n",
|
||||||
"Class {\nname: \"A\",\nancestors: [\"{class: A, params: [\\\"T\\\", \\\"V\\\"]}\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[v:V], none]\"), (\"fun\", \"fn[[a:T], V]\")],\ntype_vars: [\"T\", \"V\"]\n}\n",
|
"Class {\nname: \"A\",\nancestors: [\"{class: A, params: [\\\"T\\\", \\\"V\\\"]}\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[v:V], none]\"), (\"fun\", \"fn[[a:T], V]\")],\ntype_vars: [\"T\", \"V\"]\n}\n",
|
||||||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[v:V], none]\",\nvar_id: [18, 19]\n}\n",
|
"Function {\nname: \"A.__init__\",\nsig: \"fn[[v:V], none]\",\nvar_id: [19]\n}\n",
|
||||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:T], V]\",\nvar_id: [19, 24]\n}\n",
|
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:T], V]\",\nvar_id: [24]\n}\n",
|
||||||
"Function {\nname: \"gfun\",\nsig: \"fn[[a:A[int32, list[float]]], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"gfun\",\nsig: \"fn[[a:A[int32, list[float]]], none]\",\nvar_id: []\n}\n",
|
||||||
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: []}\"],\nfields: [],\nmethods: [(\"__init__\", \"fn[[], none]\")],\ntype_vars: []\n}\n",
|
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: []}\"],\nfields: [],\nmethods: [(\"__init__\", \"fn[[], none]\")],\ntype_vars: []\n}\n",
|
||||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
source: nac3core/src/toplevel/test.rs
|
source: nac3core/src/toplevel/test.rs
|
||||||
assertion_line: 540
|
assertion_line: 549
|
||||||
expression: res_vec
|
expression: res_vec
|
||||||
|
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
"Class {\nname: \"A\",\nancestors: [\"{class: A, params: [\\\"var5\\\", \\\"var6\\\"]}\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[a:A[bool, float], b:B], none]\"), (\"fun\", \"fn[[a:A[bool, float]], A[bool, int32]]\")],\ntype_vars: [\"var5\", \"var6\"]\n}\n",
|
"Class {\nname: \"A\",\nancestors: [\"{class: A, params: [\\\"var5\\\", \\\"var6\\\"]}\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[a:A[bool, float], b:B], none]\"), (\"fun\", \"fn[[a:A[bool, float]], A[bool, int32]]\")],\ntype_vars: [\"var5\", \"var6\"]\n}\n",
|
||||||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[a:A[bool, float], b:B], none]\",\nvar_id: [6]\n}\n",
|
"Function {\nname: \"A.__init__\",\nsig: \"fn[[a:A[bool, float], b:B], none]\",\nvar_id: []\n}\n",
|
||||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:A[bool, float]], A[bool, int32]]\",\nvar_id: [6]\n}\n",
|
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:A[bool, float]], A[bool, int32]]\",\nvar_id: []\n}\n",
|
||||||
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: []}\", \"{class: A, params: [\\\"int64\\\", \\\"bool\\\"]}\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:A[bool, float]], A[bool, int32]]\"), (\"foo\", \"fn[[b:B], B]\"), (\"bar\", \"fn[[a:A[int32, list[B]]], tuple[A[bool, virtual[A[B, int32]]], B]]\")],\ntype_vars: []\n}\n",
|
"Class {\nname: \"B\",\nancestors: [\"{class: B, params: []}\", \"{class: A, params: [\\\"int64\\\", \\\"bool\\\"]}\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:A[bool, float]], A[bool, int32]]\"), (\"foo\", \"fn[[b:B], B]\"), (\"bar\", \"fn[[a:A[int32, list[B]]], tuple[A[bool, virtual[A[B, int32]]], B]]\")],\ntype_vars: []\n}\n",
|
||||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||||
"Function {\nname: \"B.foo\",\nsig: \"fn[[b:B], B]\",\nvar_id: []\n}\n",
|
"Function {\nname: \"B.foo\",\nsig: \"fn[[b:B], B]\",\nvar_id: []\n}\n",
|
||||||
|
|
Loading…
Reference in New Issue