forked from M-Labs/nac3
artiq: Apply clippy pedantic changes
This commit is contained in:
parent
ddfb532b80
commit
bd3d67f3d6
|
@ -425,7 +425,7 @@ fn rpc_codegen_callback_fn<'ctx>(
|
|||
if obj.is_some() {
|
||||
tag.push(b'O');
|
||||
}
|
||||
for arg in fun.0.args.iter() {
|
||||
for arg in &fun.0.args {
|
||||
gen_rpc_tag(ctx, arg.ty, &mut tag)?;
|
||||
}
|
||||
tag.push(b':');
|
||||
|
@ -461,7 +461,7 @@ fn rpc_codegen_callback_fn<'ctx>(
|
|||
})
|
||||
.as_pointer_value();
|
||||
|
||||
let arg_length = args.len() + if obj.is_some() { 1 } else { 0 };
|
||||
let arg_length = args.len() + usize::from(obj.is_some());
|
||||
|
||||
let stacksave = ctx.module.get_function("llvm.stacksave").unwrap_or_else(|| {
|
||||
ctx.module.add_function("llvm.stacksave", ptr_type.fn_type(&[], false), None)
|
||||
|
@ -484,11 +484,11 @@ fn rpc_codegen_callback_fn<'ctx>(
|
|||
// -- rpc args handling
|
||||
let mut keys = fun.0.args.clone();
|
||||
let mut mapping = HashMap::new();
|
||||
for (key, value) in args.into_iter() {
|
||||
for (key, value) in args {
|
||||
mapping.insert(key.unwrap_or_else(|| keys.remove(0).name), value);
|
||||
}
|
||||
// default value handling
|
||||
for k in keys.into_iter() {
|
||||
for k in keys {
|
||||
mapping.insert(
|
||||
k.name,
|
||||
ctx.gen_symbol_val(generator, &k.default_value.unwrap(), k.ty).into()
|
||||
|
@ -518,7 +518,7 @@ fn rpc_codegen_callback_fn<'ctx>(
|
|||
ctx.builder.build_gep(
|
||||
args_ptr,
|
||||
&[int32.const_int(i as u64, false)],
|
||||
&format!("rpc.arg{}", i),
|
||||
&format!("rpc.arg{i}"),
|
||||
)
|
||||
};
|
||||
ctx.builder.build_store(arg_ptr, arg_slot);
|
||||
|
@ -621,7 +621,7 @@ pub fn attributes_writeback(
|
|||
ctx: &mut CodeGenContext<'_, '_>,
|
||||
generator: &mut dyn CodeGenerator,
|
||||
inner_resolver: &InnerResolver,
|
||||
host_attributes: PyObject,
|
||||
host_attributes: &PyObject,
|
||||
) -> Result<(), String> {
|
||||
Python::with_gil(|py| -> PyResult<Result<(), String>> {
|
||||
let host_attributes: &PyList = host_attributes.downcast(py)?;
|
||||
|
@ -631,7 +631,7 @@ pub fn attributes_writeback(
|
|||
let zero = int32.const_zero();
|
||||
let mut values = Vec::new();
|
||||
let mut scratch_buffer = Vec::new();
|
||||
for (_, val) in globals.iter() {
|
||||
for val in (*globals).values() {
|
||||
let val = val.as_ref(py);
|
||||
let ty = inner_resolver.get_obj_type(py, val, &mut ctx.unifier, &top_levels, &ctx.primitives)?;
|
||||
if let Err(ty) = ty {
|
||||
|
@ -646,7 +646,7 @@ pub fn attributes_writeback(
|
|||
// for non-primitive attributes, they should be in another global
|
||||
let mut attributes = Vec::new();
|
||||
let obj = inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap();
|
||||
for (name, (field_ty, is_mutable)) in fields.iter() {
|
||||
for (name, (field_ty, is_mutable)) in fields {
|
||||
if !is_mutable {
|
||||
continue
|
||||
}
|
||||
|
@ -683,7 +683,7 @@ pub fn attributes_writeback(
|
|||
default_value: None
|
||||
}).collect(),
|
||||
ret: ctx.primitives.none,
|
||||
vars: Default::default()
|
||||
vars: HashMap::default()
|
||||
};
|
||||
let args: Vec<_> = values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect();
|
||||
if let Err(e) = rpc_codegen_callback_fn(ctx, None, (&fun, DefinitionId(0)), args, generator) {
|
||||
|
|
|
@ -109,7 +109,7 @@ create_exception!(nac3artiq, CompileError, exceptions::PyException);
|
|||
impl Nac3 {
|
||||
fn register_module(
|
||||
&mut self,
|
||||
module: PyObject,
|
||||
module: &PyObject,
|
||||
registered_class_ids: &HashSet<u64>,
|
||||
) -> PyResult<()> {
|
||||
let (module_name, source_file) = Python::with_gil(|py| -> PyResult<(String, String)> {
|
||||
|
@ -118,12 +118,12 @@ impl Nac3 {
|
|||
})?;
|
||||
|
||||
let source = fs::read_to_string(&source_file).map_err(|e| {
|
||||
exceptions::PyIOError::new_err(format!("failed to read input file: {}", e))
|
||||
exceptions::PyIOError::new_err(format!("failed to read input file: {e}"))
|
||||
})?;
|
||||
let parser_result = parse_program(&source, source_file.into())
|
||||
.map_err(|e| exceptions::PySyntaxError::new_err(format!("parse error: {}", e)))?;
|
||||
.map_err(|e| exceptions::PySyntaxError::new_err(format!("parse error: {e}")))?;
|
||||
|
||||
for mut stmt in parser_result.into_iter() {
|
||||
for mut stmt in parser_result {
|
||||
let include = match stmt.node {
|
||||
StmtKind::ClassDef {
|
||||
ref decorator_list, ref mut body, ref mut bases, ..
|
||||
|
@ -197,7 +197,7 @@ impl Nac3 {
|
|||
fn report_modinit(
|
||||
arg_names: &[String],
|
||||
method_name: &str,
|
||||
resolver: Arc<dyn SymbolResolver + Send + Sync>,
|
||||
resolver: &Arc<dyn SymbolResolver + Send + Sync>,
|
||||
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
||||
unifier: &mut Unifier,
|
||||
primitives: &PrimitiveStore,
|
||||
|
@ -205,7 +205,7 @@ impl Nac3 {
|
|||
let base_ty =
|
||||
match resolver.get_symbol_type(unifier, top_level_defs, primitives, "base".into()) {
|
||||
Ok(ty) => ty,
|
||||
Err(e) => return Some(format!("type error inside object launching kernel: {}", e)),
|
||||
Err(e) => return Some(format!("type error inside object launching kernel: {e}")),
|
||||
};
|
||||
|
||||
let fun_ty = if method_name.is_empty() {
|
||||
|
@ -215,8 +215,7 @@ impl Nac3 {
|
|||
Some(t) => t.0,
|
||||
None => {
|
||||
return Some(format!(
|
||||
"object launching kernel does not have method `{}`",
|
||||
method_name
|
||||
"object launching kernel does not have method `{method_name}`"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -237,8 +236,7 @@ impl Nac3 {
|
|||
Some(n) => n,
|
||||
None if default_value.is_none() => {
|
||||
return Some(format!(
|
||||
"argument `{}` not provided when launching kernel function",
|
||||
name
|
||||
"argument `{name}` not provided when launching kernel function"
|
||||
))
|
||||
}
|
||||
_ => break,
|
||||
|
@ -252,8 +250,7 @@ impl Nac3 {
|
|||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
return Some(format!(
|
||||
"type error ({}) at parameter #{} when calling kernel function",
|
||||
e, i
|
||||
"type error ({e}) at parameter #{i} when calling kernel function"
|
||||
))
|
||||
}
|
||||
};
|
||||
|
@ -322,7 +319,7 @@ impl Nac3 {
|
|||
let mut module_to_resolver_cache: HashMap<u64, _> = HashMap::new();
|
||||
|
||||
let mut rpc_ids = vec![];
|
||||
for (stmt, path, module) in self.top_levels.iter() {
|
||||
for (stmt, path, module) in &self.top_levels {
|
||||
let py_module: &PyAny = module.extract(py)?;
|
||||
let module_id: u64 = id_fn.call1((py_module,))?.extract()?;
|
||||
let helper = helper.clone();
|
||||
|
@ -343,7 +340,7 @@ impl Nac3 {
|
|||
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
|
||||
let members: &PyDict =
|
||||
py_module.getattr("__dict__").unwrap().downcast().unwrap();
|
||||
for (key, val) in members.iter() {
|
||||
for (key, val) in members {
|
||||
let key: &str = key.extract().unwrap();
|
||||
let val = id_fn.call1((val,)).unwrap().extract().unwrap();
|
||||
name_to_pyid.insert(key.into(), val);
|
||||
|
@ -355,12 +352,12 @@ impl Nac3 {
|
|||
pyid_to_type: pyid_to_type.clone(),
|
||||
primitive_ids: self.primitive_ids.clone(),
|
||||
global_value_ids: global_value_ids.clone(),
|
||||
class_names: Default::default(),
|
||||
class_names: Mutex::default(),
|
||||
name_to_pyid: name_to_pyid.clone(),
|
||||
module: module.clone(),
|
||||
id_to_pyval: Default::default(),
|
||||
id_to_primitive: Default::default(),
|
||||
field_to_val: Default::default(),
|
||||
id_to_pyval: RwLock::default(),
|
||||
id_to_primitive: RwLock::default(),
|
||||
field_to_val: RwLock::default(),
|
||||
helper,
|
||||
string_store: self.string_store.clone(),
|
||||
exception_ids: self.exception_ids.clone(),
|
||||
|
@ -377,8 +374,7 @@ impl Nac3 {
|
|||
.register_top_level(stmt.clone(), Some(resolver.clone()), path, false)
|
||||
.map_err(|e| {
|
||||
CompileError::new_err(format!(
|
||||
"compilation failed\n----------\n{}",
|
||||
e
|
||||
"compilation failed\n----------\n{e}"
|
||||
))
|
||||
})?;
|
||||
if let Some(class_obj) = class_obj {
|
||||
|
@ -395,7 +391,7 @@ impl Nac3 {
|
|||
StmtKind::ClassDef { name, body, .. } => {
|
||||
let class_name = name.to_string();
|
||||
let class_obj = module.getattr(py, class_name.as_str()).unwrap();
|
||||
for stmt in body.iter() {
|
||||
for stmt in body {
|
||||
if let StmtKind::FunctionDef { name, decorator_list, .. } = &stmt.node {
|
||||
if decorator_list.iter().any(|decorator| matches!(decorator.node, ExprKind::Name { id, .. } if id == "rpc".into())) {
|
||||
if name == &"__init__".into() {
|
||||
|
@ -429,7 +425,7 @@ impl Nac3 {
|
|||
name_to_pyid.insert("base".into(), id_fun.call1((obj,))?.extract()?);
|
||||
let mut arg_names = vec![];
|
||||
for (i, arg) in args.into_iter().enumerate() {
|
||||
let name = format!("tmp{}", i);
|
||||
let name = format!("tmp{i}");
|
||||
module.add(&name, arg)?;
|
||||
name_to_pyid.insert(name.clone().into(), id_fun.call1((arg,))?.extract()?);
|
||||
arg_names.push(name);
|
||||
|
@ -448,10 +444,10 @@ impl Nac3 {
|
|||
pyid_to_type: pyid_to_type.clone(),
|
||||
primitive_ids: self.primitive_ids.clone(),
|
||||
global_value_ids: global_value_ids.clone(),
|
||||
class_names: Default::default(),
|
||||
id_to_pyval: Default::default(),
|
||||
id_to_primitive: Default::default(),
|
||||
field_to_val: Default::default(),
|
||||
class_names: Mutex::default(),
|
||||
id_to_pyval: RwLock::default(),
|
||||
id_to_primitive: RwLock::default(),
|
||||
field_to_val: RwLock::default(),
|
||||
name_to_pyid,
|
||||
module: module.to_object(py),
|
||||
helper,
|
||||
|
@ -461,7 +457,7 @@ impl Nac3 {
|
|||
});
|
||||
let resolver = Arc::new(Resolver(inner_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
let (_, def_id, _) = composer
|
||||
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into(), false)
|
||||
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "", false)
|
||||
.unwrap();
|
||||
|
||||
let fun_signature =
|
||||
|
@ -474,16 +470,11 @@ impl Nac3 {
|
|||
|
||||
if let Err(e) = composer.start_analysis(true) {
|
||||
// report error of __modinit__ separately
|
||||
return if !e.contains("<nac3_synthesized_modinit>") {
|
||||
Err(CompileError::new_err(format!(
|
||||
"compilation failed\n----------\n{}",
|
||||
e
|
||||
)))
|
||||
} else {
|
||||
return if e.contains("<nac3_synthesized_modinit>") {
|
||||
let msg = Self::report_modinit(
|
||||
&arg_names,
|
||||
method_name,
|
||||
resolver.clone(),
|
||||
&resolver,
|
||||
&composer.extract_def_list(),
|
||||
&mut composer.unifier,
|
||||
&self.primitive,
|
||||
|
@ -492,6 +483,10 @@ impl Nac3 {
|
|||
"compilation failed\n----------\n{}",
|
||||
msg.unwrap_or(e)
|
||||
)))
|
||||
} else {
|
||||
Err(CompileError::new_err(format!(
|
||||
"compilation failed\n----------\n{e}"
|
||||
)))
|
||||
}
|
||||
}
|
||||
let top_level = Arc::new(composer.make_top_level_context());
|
||||
|
@ -499,7 +494,7 @@ impl Nac3 {
|
|||
{
|
||||
let rpc_codegen = rpc_codegen_callback();
|
||||
let defs = top_level.definitions.read();
|
||||
for (class_data, id) in rpc_ids.iter() {
|
||||
for (class_data, id) in &rpc_ids {
|
||||
let mut def = defs[id.0].write();
|
||||
match &mut *def {
|
||||
TopLevelDef::Function { codegen_callback, .. } => {
|
||||
|
@ -507,7 +502,7 @@ impl Nac3 {
|
|||
}
|
||||
TopLevelDef::Class { methods, .. } => {
|
||||
let (class_def, method_name) = class_data.as_ref().unwrap();
|
||||
for (name, _, id) in methods.iter() {
|
||||
for (name, _, id) in &*methods {
|
||||
if name != method_name {
|
||||
continue;
|
||||
}
|
||||
|
@ -537,7 +532,7 @@ impl Nac3 {
|
|||
if let TopLevelDef::Function { instance_to_stmt, instance_to_symbol, .. } =
|
||||
&mut *definition
|
||||
{
|
||||
instance_to_symbol.insert("".to_string(), "__modinit__".into());
|
||||
instance_to_symbol.insert(String::new(), "__modinit__".into());
|
||||
instance_to_stmt[""].clone()
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -545,7 +540,7 @@ impl Nac3 {
|
|||
};
|
||||
|
||||
let task = CodeGenTask {
|
||||
subst: Default::default(),
|
||||
subst: Vec::default(),
|
||||
symbol_name: "__modinit__".to_string(),
|
||||
body: instance.body,
|
||||
signature,
|
||||
|
@ -562,18 +557,18 @@ impl Nac3 {
|
|||
store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache);
|
||||
let signature = store.add_cty(signature);
|
||||
let attributes_writeback_task = CodeGenTask {
|
||||
subst: Default::default(),
|
||||
subst: Vec::default(),
|
||||
symbol_name: "attributes_writeback".to_string(),
|
||||
body: Arc::new(Default::default()),
|
||||
body: Arc::new(Vec::default()),
|
||||
signature,
|
||||
resolver,
|
||||
store,
|
||||
unifier_index: instance.unifier_id,
|
||||
calls: Arc::new(Default::default()),
|
||||
calls: Arc::new(HashMap::default()),
|
||||
id: 0,
|
||||
};
|
||||
|
||||
let membuffers: Arc<Mutex<Vec<Vec<u8>>>> = Default::default();
|
||||
let membuffers: Arc<Mutex<Vec<Vec<u8>>>> = Arc::default();
|
||||
|
||||
let membuffer = membuffers.clone();
|
||||
|
||||
|
@ -607,7 +602,7 @@ impl Nac3 {
|
|||
let builder = context.create_builder();
|
||||
let (_, module, _) = gen_func_impl(&context, &mut generator, ®istry, builder, module,
|
||||
attributes_writeback_task, |generator, ctx| {
|
||||
attributes_writeback(ctx, generator, inner_resolver.as_ref(), host_attributes)
|
||||
attributes_writeback(ctx, generator, inner_resolver.as_ref(), &host_attributes)
|
||||
}).unwrap();
|
||||
let buffer = module.write_bitcode_to_memory();
|
||||
let buffer = buffer.as_slice().into();
|
||||
|
@ -671,7 +666,7 @@ impl Nac3 {
|
|||
link_fn(&main)
|
||||
}
|
||||
|
||||
/// Returns the [TargetTriple] used for compiling to [isa].
|
||||
/// Returns the [`TargetTriple`] used for compiling to [isa].
|
||||
fn get_llvm_target_triple(isa: Isa) -> TargetTriple {
|
||||
match isa {
|
||||
Isa::Host => TargetMachine::get_default_triple(),
|
||||
|
@ -680,7 +675,7 @@ impl Nac3 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the [String] representing the target CPU used for compiling to [isa].
|
||||
/// Returns the [`String`] representing the target CPU used for compiling to [isa].
|
||||
fn get_llvm_target_cpu(isa: Isa) -> String {
|
||||
match isa {
|
||||
Isa::Host => TargetMachine::get_host_cpu_name().to_string(),
|
||||
|
@ -689,7 +684,7 @@ impl Nac3 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the [String] representing the target features used for compiling to [isa].
|
||||
/// Returns the [`String`] representing the target features used for compiling to [isa].
|
||||
fn get_llvm_target_features(isa: Isa) -> String {
|
||||
match isa {
|
||||
Isa::Host => TargetMachine::get_host_cpu_features().to_string(),
|
||||
|
@ -699,7 +694,7 @@ impl Nac3 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an instance of [CodeGenTargetMachineOptions] representing the target machine
|
||||
/// Returns an instance of [`CodeGenTargetMachineOptions`] representing the target machine
|
||||
/// options used for compiling to [isa].
|
||||
fn get_llvm_target_options(isa: Isa) -> CodeGenTargetMachineOptions {
|
||||
CodeGenTargetMachineOptions {
|
||||
|
@ -711,7 +706,7 @@ impl Nac3 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an instance of [TargetMachine] used in compiling and linking of a program to the
|
||||
/// Returns an instance of [`TargetMachine`] used in compiling and linking of a program to the
|
||||
/// target [isa].
|
||||
fn get_llvm_target_machine(&self) -> TargetMachine {
|
||||
Nac3::get_llvm_target_options(self.isa)
|
||||
|
@ -790,10 +785,9 @@ impl Nac3 {
|
|||
_ => return Err(exceptions::PyValueError::new_err("invalid ISA")),
|
||||
};
|
||||
let time_fns: &(dyn TimeFns + Sync) = match isa {
|
||||
Isa::Host => &timeline::EXTERN_TIME_FNS,
|
||||
Isa::RiscV32G => &timeline::NOW_PINNING_TIME_FNS_64,
|
||||
Isa::RiscV32IMA => &timeline::NOW_PINNING_TIME_FNS,
|
||||
Isa::CortexA9 => &timeline::EXTERN_TIME_FNS,
|
||||
Isa::CortexA9 | Isa::Host => &timeline::EXTERN_TIME_FNS,
|
||||
};
|
||||
let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0;
|
||||
let builtins = vec![
|
||||
|
@ -884,7 +878,7 @@ impl Nac3 {
|
|||
.and_then(|v| v.get_item("_ConstGenericMarker"))
|
||||
.unwrap(),
|
||||
))
|
||||
.and_then(|v| v.extract())
|
||||
.and_then(PyAny::extract)
|
||||
.unwrap(),
|
||||
int: get_attr_id(builtins_mod, "int"),
|
||||
int32: get_attr_id(numpy_mod, "int32"),
|
||||
|
@ -919,11 +913,11 @@ impl Nac3 {
|
|||
primitive,
|
||||
builtins,
|
||||
primitive_ids,
|
||||
top_levels: Default::default(),
|
||||
pyid_to_def: Default::default(),
|
||||
top_levels: Vec::default(),
|
||||
pyid_to_def: Arc::default(),
|
||||
working_directory,
|
||||
string_store: Default::default(),
|
||||
exception_ids: Default::default(),
|
||||
string_store: Arc::default(),
|
||||
exception_ids: Arc::default(),
|
||||
deferred_eval_store: DeferredEvaluationStore::new(),
|
||||
llvm_options: CodeGenLLVMOptions {
|
||||
opt_level: OptimizationLevel::Default,
|
||||
|
@ -941,11 +935,11 @@ impl Nac3 {
|
|||
let id_fn = PyModule::import(py, "builtins")?.getattr("id")?;
|
||||
let getmodule_fn = PyModule::import(py, "inspect")?.getattr("getmodule")?;
|
||||
|
||||
for function in functions.iter() {
|
||||
for function in functions {
|
||||
let module = getmodule_fn.call1((function,))?.extract()?;
|
||||
modules.insert(id_fn.call1((&module,))?.extract()?, module);
|
||||
}
|
||||
for class in classes.iter() {
|
||||
for class in classes {
|
||||
let module = getmodule_fn.call1((class,))?.extract()?;
|
||||
modules.insert(id_fn.call1((&module,))?.extract()?, module);
|
||||
class_ids.insert(id_fn.call1((class,))?.extract()?);
|
||||
|
@ -954,7 +948,7 @@ impl Nac3 {
|
|||
})?;
|
||||
|
||||
for module in modules.into_values() {
|
||||
self.register_module(module, &class_ids)?;
|
||||
self.register_module(&module, &class_ids)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -100,25 +100,25 @@ impl StaticValue for PythonValue {
|
|||
) -> BasicValueEnum<'ctx> {
|
||||
ctx.module
|
||||
.get_global(format!("{}_const", self.id).as_str())
|
||||
.map(|val| val.as_pointer_value().into())
|
||||
.unwrap_or_else(|| {
|
||||
Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> {
|
||||
let id: u32 = self.store_obj.call1(py, (self.value.clone(),))?.extract(py)?;
|
||||
let struct_type = ctx.ctx.struct_type(&[ctx.ctx.i32_type().into()], false);
|
||||
let global = ctx.module.add_global(
|
||||
struct_type,
|
||||
None,
|
||||
format!("{}_const", self.id).as_str(),
|
||||
);
|
||||
global.set_constant(true);
|
||||
global.set_initializer(&ctx.ctx.const_struct(
|
||||
&[ctx.ctx.i32_type().const_int(id as u64, false).into()],
|
||||
false,
|
||||
));
|
||||
Ok(global.as_pointer_value().into())
|
||||
})
|
||||
.unwrap()
|
||||
})
|
||||
.map_or_else(
|
||||
|| Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> {
|
||||
let id: u32 = self.store_obj.call1(py, (self.value.clone(),))?.extract(py)?;
|
||||
let struct_type = ctx.ctx.struct_type(&[ctx.ctx.i32_type().into()], false);
|
||||
let global = ctx.module.add_global(
|
||||
struct_type,
|
||||
None,
|
||||
format!("{}_const", self.id).as_str(),
|
||||
);
|
||||
global.set_constant(true);
|
||||
global.set_initializer(&ctx.ctx.const_struct(
|
||||
&[ctx.ctx.i32_type().const_int(id as u64, false).into()],
|
||||
false,
|
||||
));
|
||||
Ok(global.as_pointer_value().into())
|
||||
})
|
||||
.unwrap(),
|
||||
|val| val.as_pointer_value().into(),
|
||||
)
|
||||
}
|
||||
|
||||
fn to_basic_value_enum<'ctx, 'a>(
|
||||
|
@ -176,7 +176,7 @@ impl StaticValue for PythonValue {
|
|||
let mut mutable = true;
|
||||
let defs = ctx.top_level.definitions.read();
|
||||
if let TopLevelDef::Class { fields, .. } = &*defs[def_id.0].read() {
|
||||
for (field_name, _, is_mutable) in fields.iter() {
|
||||
for (field_name, _, is_mutable) in fields {
|
||||
if field_name == &name {
|
||||
mutable = *is_mutable;
|
||||
break;
|
||||
|
@ -240,7 +240,7 @@ impl InnerResolver {
|
|||
) -> PyResult<Result<Type, String>> {
|
||||
let mut ty = match self.get_obj_type(py, list.get_item(0)?, unifier, defs, primitives)? {
|
||||
Ok(t) => t,
|
||||
Err(e) => return Ok(Err(format!("type error ({}) at element #0 of the list", e))),
|
||||
Err(e) => return Ok(Err(format!("type error ({e}) at element #0 of the list"))),
|
||||
};
|
||||
for i in 1..len {
|
||||
let b = match list
|
||||
|
@ -249,11 +249,11 @@ impl InnerResolver {
|
|||
{
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
return Ok(Err(format!("type error ({}) at element #{} of the list", e, i)))
|
||||
return Ok(Err(format!("type error ({e}) at element #{i} of the list")))
|
||||
}
|
||||
};
|
||||
ty = match unifier.unify(ty, b) {
|
||||
Ok(_) => ty,
|
||||
Ok(()) => ty,
|
||||
Err(e) => {
|
||||
return Ok(Err(format!(
|
||||
"inhomogeneous type ({}) at element #{i} of the list",
|
||||
|
@ -268,7 +268,7 @@ impl InnerResolver {
|
|||
/// Handles python objects that represent types themselves,
|
||||
///
|
||||
/// Primitives and class types should be themselves, use `ty_id` to check;
|
||||
/// TypeVars and GenericAlias(`A[int, bool]`) should use `ty_ty_id` to check.
|
||||
/// `TypeVars` and `GenericAlias`(`A[int, bool]`) should use `ty_ty_id` to check.
|
||||
///
|
||||
/// The `bool` value returned indicates whether they are instantiated or not
|
||||
fn get_pyty_obj_type(
|
||||
|
@ -309,7 +309,7 @@ impl InnerResolver {
|
|||
Ok(Ok((primitives.option, false)))
|
||||
} else if ty_id == self.primitive_ids.none {
|
||||
unreachable!("none cannot be typeid")
|
||||
} else if let Some(def_id) = self.pyid_to_def.read().get(&ty_id).cloned() {
|
||||
} else if let Some(def_id) = self.pyid_to_def.read().get(&ty_id).copied() {
|
||||
let def = defs[def_id.0].read();
|
||||
if let TopLevelDef::Class { object_id, type_vars, fields, methods, .. } = &*def {
|
||||
// do not handle type var param and concrete check here, and no subst
|
||||
|
@ -376,7 +376,7 @@ impl InnerResolver {
|
|||
}
|
||||
Err(err) => return Ok(Err(err)),
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
|
@ -388,7 +388,7 @@ impl InnerResolver {
|
|||
.push((result.clone(),
|
||||
constraints.extract()?,
|
||||
pyty.getattr("__name__")?.extract::<String>()?
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
(result, is_const_generic)
|
||||
|
@ -514,11 +514,10 @@ impl InnerResolver {
|
|||
Ok(ty) => ty,
|
||||
Err(err) => return Ok(Err(err)),
|
||||
};
|
||||
if !unifier.is_concrete(ty.0, &[]) && !ty.1 {
|
||||
panic!(
|
||||
"virtual class should take concrete parameters in type var ranges"
|
||||
)
|
||||
}
|
||||
assert!(
|
||||
unifier.is_concrete(ty.0, &[]) || ty.1,
|
||||
"virtual class should take concrete parameters in type var ranges"
|
||||
);
|
||||
Ok(Ok((unifier.add_ty(TypeEnum::TVirtual { ty: ty.0 }), true)))
|
||||
} else {
|
||||
return Ok(Err(format!(
|
||||
|
@ -542,8 +541,7 @@ impl InnerResolver {
|
|||
pyo3::types::PyModule::import(py, "builtins").unwrap().getattr("repr").unwrap();
|
||||
let str_repr: String = str_fn.call1((pyty,)).unwrap().extract().unwrap();
|
||||
Ok(Err(format!(
|
||||
"{} is not registered with NAC3 (@nac3 decorator missing?)",
|
||||
str_repr
|
||||
"{str_repr} is not registered with NAC3 (@nac3 decorator missing?)"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -624,7 +622,7 @@ impl InnerResolver {
|
|||
self.get_list_elem_type(py, obj, len, unifier, defs, primitives)?;
|
||||
match actual_ty {
|
||||
Ok(t) => match unifier.unify(*ty, t) {
|
||||
Ok(_) => Ok(Ok(unifier.add_ty(TypeEnum::TList { ty: *ty }))),
|
||||
Ok(()) => Ok(Ok(unifier.add_ty(TypeEnum::TList { ty: *ty }))),
|
||||
Err(e) => Ok(Err(format!(
|
||||
"type error ({}) for the list",
|
||||
e.to_display(unifier)
|
||||
|
@ -648,10 +646,8 @@ impl InnerResolver {
|
|||
(TypeEnum::TObj { obj_id, params, .. }, false)
|
||||
if *obj_id == primitives.option.get_obj_id(unifier) =>
|
||||
{
|
||||
let field_data = match obj.getattr("_nac3_option") {
|
||||
Ok(d) => d,
|
||||
// we use `none = Option(None)`, so the obj always have attr `_nac3_option`
|
||||
Err(_) => unreachable!("cannot be None")
|
||||
let Ok(field_data) = obj.getattr("_nac3_option") else {
|
||||
unreachable!("cannot be None")
|
||||
};
|
||||
// if is `none`
|
||||
let zelf_id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?;
|
||||
|
@ -671,17 +667,15 @@ impl InnerResolver {
|
|||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
return Ok(Ok(unifier.subst(primitives.option, &var_map).unwrap()))
|
||||
} else {
|
||||
unreachable!("must be tobj")
|
||||
}
|
||||
unreachable!("must be tobj")
|
||||
}
|
||||
|
||||
let ty = match self.get_obj_type(py, field_data, unifier, defs, primitives)? {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
return Ok(Err(format!(
|
||||
"error when getting type of the option object ({})",
|
||||
e
|
||||
"error when getting type of the option object ({e})"
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
@ -706,38 +700,36 @@ impl InnerResolver {
|
|||
.collect::<HashMap<_, _>>();
|
||||
let mut instantiate_obj = || {
|
||||
// loop through non-function fields of the class to get the instantiated value
|
||||
for field in fields.iter() {
|
||||
for field in fields {
|
||||
let name: String = (*field.0).into();
|
||||
if let TypeEnum::TFunc(..) = &*unifier.get_ty(field.1.0) {
|
||||
continue;
|
||||
} else {
|
||||
let field_data = match obj.getattr(name.as_str()) {
|
||||
Ok(d) => d,
|
||||
Err(e) => return Ok(Err(format!("{}", e))),
|
||||
};
|
||||
let ty = match self
|
||||
.get_obj_type(py, field_data, unifier, defs, primitives)?
|
||||
{
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
return Ok(Err(format!(
|
||||
"error when getting type of field `{}` ({})",
|
||||
name, e
|
||||
)))
|
||||
}
|
||||
};
|
||||
let field_ty =
|
||||
unifier.subst(field.1.0, &var_map).unwrap_or(field.1.0);
|
||||
if let Err(e) = unifier.unify(ty, field_ty) {
|
||||
// field type mismatch
|
||||
}
|
||||
let field_data = match obj.getattr(name.as_str()) {
|
||||
Ok(d) => d,
|
||||
Err(e) => return Ok(Err(format!("{e}"))),
|
||||
};
|
||||
let ty = match self
|
||||
.get_obj_type(py, field_data, unifier, defs, primitives)?
|
||||
{
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
return Ok(Err(format!(
|
||||
"error when getting type of field `{name}` ({})",
|
||||
e.to_display(unifier)
|
||||
)));
|
||||
"error when getting type of field `{name}` ({e})"
|
||||
)))
|
||||
}
|
||||
};
|
||||
let field_ty =
|
||||
unifier.subst(field.1.0, &var_map).unwrap_or(field.1.0);
|
||||
if let Err(e) = unifier.unify(ty, field_ty) {
|
||||
// field type mismatch
|
||||
return Ok(Err(format!(
|
||||
"error when getting type of field `{name}` ({})",
|
||||
e.to_display(unifier)
|
||||
)));
|
||||
}
|
||||
}
|
||||
for (_, ty) in var_map.iter() {
|
||||
for ty in var_map.values() {
|
||||
// must be concrete type
|
||||
if !unifier.is_concrete(*ty, &[]) {
|
||||
return Ok(Err("object is not of concrete type".into()));
|
||||
|
@ -758,32 +750,32 @@ impl InnerResolver {
|
|||
// check integer bounds
|
||||
if unifier.unioned(extracted_ty, primitives.int32) {
|
||||
obj.extract::<i32>().map_or_else(
|
||||
|_| Ok(Err(format!("{} is not in the range of int32", obj))),
|
||||
|_| Ok(Err(format!("{obj} is not in the range of int32"))),
|
||||
|_| Ok(Ok(extracted_ty))
|
||||
)
|
||||
} else if unifier.unioned(extracted_ty, primitives.int64) {
|
||||
obj.extract::<i64>().map_or_else(
|
||||
|_| Ok(Err(format!("{} is not in the range of int64", obj))),
|
||||
|_| Ok(Err(format!("{obj} is not in the range of int64"))),
|
||||
|_| Ok(Ok(extracted_ty))
|
||||
)
|
||||
} else if unifier.unioned(extracted_ty, primitives.uint32) {
|
||||
obj.extract::<u32>().map_or_else(
|
||||
|_| Ok(Err(format!("{} is not in the range of uint32", obj))),
|
||||
|_| Ok(Err(format!("{obj} is not in the range of uint32"))),
|
||||
|_| Ok(Ok(extracted_ty))
|
||||
)
|
||||
} else if unifier.unioned(extracted_ty, primitives.uint64) {
|
||||
obj.extract::<u64>().map_or_else(
|
||||
|_| Ok(Err(format!("{} is not in the range of uint64", obj))),
|
||||
|_| Ok(Err(format!("{obj} is not in the range of uint64"))),
|
||||
|_| Ok(Ok(extracted_ty))
|
||||
)
|
||||
} else if unifier.unioned(extracted_ty, primitives.bool) {
|
||||
obj.extract::<bool>().map_or_else(
|
||||
|_| Ok(Err(format!("{} is not in the range of bool", obj))),
|
||||
|_| Ok(Err(format!("{obj} is not in the range of bool"))),
|
||||
|_| Ok(Ok(extracted_ty))
|
||||
)
|
||||
} else if unifier.unioned(extracted_ty, primitives.float) {
|
||||
obj.extract::<f64>().map_or_else(
|
||||
|_| Ok(Err(format!("{} is not in the range of float64", obj))),
|
||||
|_| Ok(Err(format!("{obj} is not in the range of float64"))),
|
||||
|_| Ok(Ok(extracted_ty))
|
||||
)
|
||||
} else {
|
||||
|
@ -855,9 +847,8 @@ impl InnerResolver {
|
|||
ctx.module.add_global(arr_ty, Some(AddressSpace::default()), &id_str)
|
||||
});
|
||||
return Ok(Some(global.as_pointer_value().into()));
|
||||
} else {
|
||||
self.global_value_ids.write().insert(id, obj.into());
|
||||
}
|
||||
self.global_value_ids.write().insert(id, obj.into());
|
||||
}
|
||||
|
||||
let arr: Result<Option<Vec<_>>, _> = (0..len)
|
||||
|
@ -867,7 +858,7 @@ impl InnerResolver {
|
|||
.and_then(|elem| self.get_obj_value(py, elem, ctx, generator, elem_ty)
|
||||
.map_err(
|
||||
|e| super::CompileError::new_err(
|
||||
format!("Error getting element {}: {}", i, e))
|
||||
format!("Error getting element {i}: {e}"))
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
|
@ -921,7 +912,7 @@ impl InnerResolver {
|
|||
.map(|((i, elem), ty)| self
|
||||
.get_obj_value(py, elem, ctx, generator, *ty).map_err(|e|
|
||||
super::CompileError::new_err(
|
||||
format!("Error getting element {}: {}", i, e)
|
||||
format!("Error getting element {i}: {e}")
|
||||
)
|
||||
)
|
||||
).collect();
|
||||
|
@ -953,21 +944,19 @@ impl InnerResolver {
|
|||
.get_obj_value(py, obj.getattr("_nac3_option").unwrap(), ctx, generator, option_val_ty)
|
||||
.map_err(|e| {
|
||||
super::CompileError::new_err(format!(
|
||||
"Error getting value of Option object: {}",
|
||||
e
|
||||
"Error getting value of Option object: {e}"
|
||||
))
|
||||
})? {
|
||||
Some(v) => {
|
||||
let global_str = format!("{}_option", id);
|
||||
let global_str = format!("{id}_option");
|
||||
{
|
||||
if self.global_value_ids.read().contains_key(&id) {
|
||||
let global = ctx.module.get_global(&global_str).unwrap_or_else(|| {
|
||||
ctx.module.add_global(v.get_type(), Some(AddressSpace::default()), &global_str)
|
||||
});
|
||||
return Ok(Some(global.as_pointer_value().into()));
|
||||
} else {
|
||||
self.global_value_ids.write().insert(id, obj.into());
|
||||
}
|
||||
self.global_value_ids.write().insert(id, obj.into());
|
||||
}
|
||||
let global = ctx.module.add_global(v.get_type(), Some(AddressSpace::default()), &global_str);
|
||||
global.set_initializer(&v);
|
||||
|
@ -998,9 +987,8 @@ impl InnerResolver {
|
|||
ctx.module.add_global(ty, Some(AddressSpace::default()), &id_str)
|
||||
});
|
||||
return Ok(Some(global.as_pointer_value().into()));
|
||||
} else {
|
||||
self.global_value_ids.write().insert(id, obj.into());
|
||||
}
|
||||
self.global_value_ids.write().insert(id, obj.into());
|
||||
}
|
||||
// should be classes
|
||||
let definition =
|
||||
|
@ -1010,7 +998,7 @@ impl InnerResolver {
|
|||
.iter()
|
||||
.map(|(name, ty, _)| {
|
||||
self.get_obj_value(py, obj.getattr(name.to_string().as_str())?, ctx, generator, *ty)
|
||||
.map_err(|e| super::CompileError::new_err(format!("Error getting field {}: {}", name, e)))
|
||||
.map_err(|e| super::CompileError::new_err(format!("Error getting field {name}: {e}")))
|
||||
})
|
||||
.collect();
|
||||
let values = values?;
|
||||
|
@ -1083,11 +1071,11 @@ impl SymbolResolver for Resolver {
|
|||
let obj: &PyAny = self.0.module.extract(py)?;
|
||||
let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap();
|
||||
let mut sym_value = None;
|
||||
for (key, val) in members.iter() {
|
||||
for (key, val) in members {
|
||||
let key: &str = key.extract()?;
|
||||
if key == id.to_string() {
|
||||
if let Ok(Ok(v)) = self.0.get_default_param_obj_value(py, val) {
|
||||
sym_value = Some(v)
|
||||
sym_value = Some(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1107,43 +1095,41 @@ impl SymbolResolver for Resolver {
|
|||
primitives: &PrimitiveStore,
|
||||
str: StrRef,
|
||||
) -> Result<Type, String> {
|
||||
match {
|
||||
if let Some(ty) = {
|
||||
let id_to_type = self.0.id_to_type.read();
|
||||
id_to_type.get(&str).cloned()
|
||||
id_to_type.get(&str).copied()
|
||||
} {
|
||||
Some(ty) => Ok(ty),
|
||||
None => {
|
||||
let id = match self.0.name_to_pyid.get(&str) {
|
||||
Some(id) => id,
|
||||
None => return Err(format!("cannot find symbol `{}`", str)),
|
||||
};
|
||||
let result = match {
|
||||
let pyid_to_type = self.0.pyid_to_type.read();
|
||||
pyid_to_type.get(id).copied()
|
||||
} {
|
||||
Some(t) => Ok(t),
|
||||
None => Python::with_gil(|py| -> PyResult<Result<Type, String>> {
|
||||
let obj: &PyAny = self.0.module.extract(py)?;
|
||||
let mut sym_ty = Err(format!("cannot find symbol `{}`", str));
|
||||
let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap();
|
||||
for (key, val) in members.iter() {
|
||||
let key: &str = key.extract()?;
|
||||
if key == str.to_string() {
|
||||
sym_ty = self.0.get_obj_type(py, val, unifier, defs, primitives)?;
|
||||
break;
|
||||
}
|
||||
Ok(ty)
|
||||
} else {
|
||||
let Some(id) = self.0.name_to_pyid.get(&str) else {
|
||||
return Err(format!("cannot find symbol `{str}`"))
|
||||
};
|
||||
let result = if let Some(t) = {
|
||||
let pyid_to_type = self.0.pyid_to_type.read();
|
||||
pyid_to_type.get(id).copied()
|
||||
} {
|
||||
Ok(t)
|
||||
} else {
|
||||
Python::with_gil(|py| -> PyResult<Result<Type, String>> {
|
||||
let obj: &PyAny = self.0.module.extract(py)?;
|
||||
let mut sym_ty = Err(format!("cannot find symbol `{str}`"));
|
||||
let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap();
|
||||
for (key, val) in members {
|
||||
let key: &str = key.extract()?;
|
||||
if key == str.to_string() {
|
||||
sym_ty = self.0.get_obj_type(py, val, unifier, defs, primitives)?;
|
||||
break;
|
||||
}
|
||||
if let Ok(t) = sym_ty {
|
||||
if let TypeEnum::TVar { .. } = &*unifier.get_ty(t) {
|
||||
self.0.pyid_to_type.write().insert(*id, t);
|
||||
}
|
||||
}
|
||||
if let Ok(t) = sym_ty {
|
||||
if let TypeEnum::TVar { .. } = &*unifier.get_ty(t) {
|
||||
self.0.pyid_to_type.write().insert(*id, t);
|
||||
}
|
||||
Ok(sym_ty)
|
||||
})
|
||||
.unwrap(),
|
||||
};
|
||||
result
|
||||
}
|
||||
}
|
||||
Ok(sym_ty)
|
||||
}).unwrap()
|
||||
};
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1161,7 +1147,7 @@ impl SymbolResolver for Resolver {
|
|||
let obj: &PyAny = self.0.module.extract(py)?;
|
||||
let mut sym_value: Option<(u64, PyObject)> = None;
|
||||
let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap();
|
||||
for (key, val) in members.iter() {
|
||||
for (key, val) in members {
|
||||
let key: &str = key.extract()?;
|
||||
if key == id.to_string() {
|
||||
let id = self.0.helper.id_fn.call1(py, (val,))?.extract(py)?;
|
||||
|
@ -1189,14 +1175,13 @@ impl SymbolResolver for Resolver {
|
|||
fn get_identifier_def(&self, id: StrRef) -> Result<DefinitionId, String> {
|
||||
{
|
||||
let id_to_def = self.0.id_to_def.read();
|
||||
id_to_def.get(&id).cloned().ok_or_else(|| "".to_string())
|
||||
id_to_def.get(&id).copied().ok_or_else(String::new)
|
||||
}
|
||||
.or_else(|_| {
|
||||
let py_id =
|
||||
self.0.name_to_pyid.get(&id).ok_or(format!("Undefined identifier `{}`", id))?;
|
||||
self.0.name_to_pyid.get(&id).ok_or(format!("Undefined identifier `{id}`"))?;
|
||||
let result = self.0.pyid_to_def.read().get(py_id).copied().ok_or(format!(
|
||||
"`{}` is not registered with NAC3 (@nac3 decorator missing?)",
|
||||
id
|
||||
"`{id}` is not registered with NAC3 (@nac3 decorator missing?)"
|
||||
))?;
|
||||
self.0.id_to_def.write().insert(id, result);
|
||||
Ok(result)
|
||||
|
@ -1241,7 +1226,7 @@ impl SymbolResolver for Resolver {
|
|||
name,
|
||||
)));
|
||||
}
|
||||
unifier.unify(ty, *var).unwrap()
|
||||
unifier.unify(ty, *var).unwrap();
|
||||
}
|
||||
Err(err) => return Ok(Err(err)),
|
||||
}
|
||||
|
@ -1251,13 +1236,13 @@ impl SymbolResolver for Resolver {
|
|||
}
|
||||
}
|
||||
Ok(Ok(()))
|
||||
}).unwrap()?
|
||||
}).unwrap()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_exception_id(&self, tyid: usize) -> usize {
|
||||
let exn_ids = self.0.exception_ids.read();
|
||||
exn_ids.get(&tyid).cloned().unwrap_or(0)
|
||||
exn_ids.get(&tyid).copied().unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ fn test_primitives() {
|
|||
threads,
|
||||
top_level,
|
||||
&llvm_options,
|
||||
f
|
||||
&f
|
||||
);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
|
@ -417,7 +417,7 @@ fn test_simple_call() {
|
|||
threads,
|
||||
top_level,
|
||||
&llvm_options,
|
||||
f
|
||||
&f
|
||||
);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
|
|
Loading…
Reference in New Issue