forked from M-Labs/nac3
1
0
Fork 0

nac3core: top level derive fmt::Debug, fix dead lock

This commit is contained in:
ychenfo 2021-09-07 00:20:40 +08:00
parent 54b4572c5f
commit 235b6e34d1
5 changed files with 60 additions and 40 deletions

View File

@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::fmt::Debug;
use std::{cell::RefCell, sync::Arc};
use crate::toplevel::{DefinitionId, TopLevelDef};
@ -219,3 +220,9 @@ impl dyn SymbolResolver + Send + Sync {
parse_type_annotation(self, top_level_defs, unifier, primitives, expr)
}
}
impl Debug for dyn SymbolResolver + Send + Sync {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "")
}
}

View File

@ -1,4 +1,4 @@
use std::{borrow::{Borrow, BorrowMut}, collections::{HashMap, HashSet}, iter::FromIterator, ops::{Deref, DerefMut}, sync::Arc};
use std::{borrow::BorrowMut, collections::{HashMap, HashSet}, iter::FromIterator, ops::{Deref, DerefMut}, sync::Arc};
use super::typecheck::type_inferencer::PrimitiveStore;
use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier};
@ -6,11 +6,11 @@ use crate::{
symbol_resolver::SymbolResolver,
typecheck::{type_inferencer::CodeLocation, typedef::CallId},
};
use itertools::{izip, Itertools};
use itertools::Itertools;
use parking_lot::{Mutex, RwLock};
use rustpython_parser::ast::{self, Stmt};
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
pub struct DefinitionId(pub usize);
mod type_annotation;
@ -19,7 +19,7 @@ mod helper;
#[cfg(test)]
mod test;
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct FunInstance {
pub body: Vec<Stmt<Option<Type>>>,
pub calls: HashMap<CodeLocation, CallId>,
@ -27,6 +27,7 @@ pub struct FunInstance {
pub unifier_id: usize,
}
#[derive(Debug)]
pub enum TopLevelDef {
Class {
// name for error messages and symbols

View File

@ -8,12 +8,12 @@ use crate::{
},
};
use indoc::indoc;
use parking_lot::{Mutex, RwLock};
use rustpython_parser::{ast::fold::Fold, parser::parse_program};
use std::{borrow::BorrowMut, collections::{HashMap, HashSet}, sync::Arc};
use parking_lot::Mutex;
use rustpython_parser::parser::parse_program;
use std::{collections::HashMap, sync::Arc};
use test_case::test_case;
use super::TopLevelComposer;
use super::*;
struct Resolver {
id_to_type: HashMap<String, Type>,
@ -48,13 +48,13 @@ impl SymbolResolver for Resolver {
#[test_case(
vec![
indoc! {"
def fun(a: int) -> int:
def fun(a: int32) -> int32:
return a
"},
indoc! {"
class A:
def __init__(self):
self.a: int = 3
self.a: int32 = 3
"},
indoc! {"
class B:
@ -71,7 +71,7 @@ impl SymbolResolver for Resolver {
indoc! {"
class C(B):
def __init__(self):
self.c: int = 4
self.c: int32 = 4
self.a: bool = True
"}
]
@ -90,35 +90,30 @@ fn test_simple_register(source: Vec<&str>) {
#[test_case(
vec![
indoc! {"
def fun(a: int) -> int:
def fun(a: int32) -> int32:
return a
"},
// indoc! {"
// class A:
// def __init__(self):
// self.a: int = 3
// "},
// indoc! {"
// class B:
// def __init__(self):
// self.b: float = 4.3
// def fun(self):
// self.b = self.b + 3.0
// "},
// indoc! {"
// def foo(a: float):
// a + 1.0
// "},
// indoc! {"
// class C(B):
// def __init__(self):
// self.c: int = 4
// self.a: bool = True
// "}
indoc! {"
def foo(a: float):
a + 1.0
"},
indoc! {"
def f(b: int64) -> int32:
return 3
"},
],
vec![
"fn[[a=0], 0]",
"fn[[a=2], 4]",
"fn[[b=1], 0]",
],
vec![
"fun",
"foo",
"f"
]
)]
fn test_simple_analyze(source: Vec<&str>) {
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
let mut composer = TopLevelComposer::new();
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
@ -136,4 +131,13 @@ fn test_simple_analyze(source: Vec<&str>) {
}
composer.start_analysis().unwrap();
for (i, (def, _)) in composer.definition_ast_list.into_iter().enumerate() {
let def = &*def.read();
if let TopLevelDef::Function { signature, name, .. } = def {
let ty_str = composer.unifier.stringify(*signature, &mut |id| id.to_string(), &mut |id| id.to_string());
assert_eq!(ty_str, tys[i]);
assert_eq!(name, names[i]);
}
}
}

View File

@ -2,7 +2,7 @@ use crate::typecheck::typedef::TypeVarMeta;
use super::*;
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum TypeAnnotation {
PrimitiveKind(Type),
// we use type vars kind at params to represent self type
@ -33,7 +33,12 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
"bool" => Ok(TypeAnnotation::PrimitiveKind(primitives.bool)),
"None" => Ok(TypeAnnotation::PrimitiveKind(primitives.none)),
x => {
if let Some(obj_id) = resolver.lock().get_identifier_def(x) {
if let Some(obj_id) = {
// write this way because the lock in the if/let construct lives
// for the whole if let construct
let id = resolver.lock().get_identifier_def(x);
id
} {
let def = top_level_defs[obj_id.0].read();
if let TopLevelDef::Class { type_vars, .. } = &*def {
// also check param number here
@ -47,7 +52,10 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
} else {
Err("function cannot be used as a type".into())
}
} else if let Some(ty) = resolver.lock().get_symbol_type(unifier, primitives, id) {
} else if let Some(ty) = {
let ty = resolver.lock().get_symbol_type(unifier, primitives, id);
ty
} {
if let TypeEnum::TVar { .. } = unifier.get_ty(ty).as_ref() {
Ok(TypeAnnotation::TypeVarKind(ty))
} else {

View File

@ -16,7 +16,7 @@ mod test;
/// Handle for a type, implementated as a key in the unification table.
pub type Type = UnificationKey;
#[derive(Clone, Copy, PartialEq, Eq)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct CallId(usize);
pub type Mapping<K, V = Type> = HashMap<K, V>;