From 49de81ef1e8cc7e35ec14a45b68181a611772a1d Mon Sep 17 00:00:00 2001 From: David Mak Date: Tue, 20 Feb 2024 18:07:55 +0800 Subject: [PATCH] core: Apply clippy suggestions --- nac3artiq/src/lib.rs | 4 +- nac3artiq/src/symbol_resolver.rs | 4 +- nac3core/src/codegen/classes.rs | 63 +++++++--- nac3core/src/codegen/expr.rs | 33 +++-- nac3core/src/codegen/generator.rs | 4 +- nac3core/src/codegen/irrt/mod.rs | 32 ++--- nac3core/src/codegen/mod.rs | 6 +- nac3core/src/codegen/stmt.rs | 4 +- nac3core/src/symbol_resolver.rs | 9 +- nac3core/src/toplevel/builtins.rs | 28 ++--- nac3core/src/toplevel/composer.rs | 6 +- nac3core/src/toplevel/numpy.rs | 118 +++++++++--------- nac3core/src/toplevel/type_annotation.rs | 2 +- nac3core/src/typecheck/type_inferencer/mod.rs | 15 ++- nac3core/src/typecheck/typedef/mod.rs | 45 +++---- 15 files changed, 206 insertions(+), 167 deletions(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 2cda3f21..a1ae1df9 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -65,8 +65,8 @@ enum Isa { impl Isa { /// Returns the number of bits in `size_t` for the [`Isa`]. - fn get_size_type(&self) -> u32 { - if self == &Isa::Host { + fn get_size_type(self) -> u32 { + if self == Isa::Host { 64u32 } else { 32u32 diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index aeb99fa3..3de2bdcd 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -662,10 +662,10 @@ 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::TNDArray { ty: *ty, ndims: *ndims }))), + Ok(()) => Ok(Ok(unifier.add_ty(TypeEnum::TNDArray { ty: *ty, ndims: *ndims }))), Err(e) => Ok(Err(format!( "type error ({}) for the ndarray", - e.to_display(unifier).to_string() + e.to_display(unifier), ))), }, Err(e) => Ok(Err(e)), diff --git a/nac3core/src/codegen/classes.rs b/nac3core/src/codegen/classes.rs index adcd9249..347f84c4 100644 --- a/nac3core/src/codegen/classes.rs +++ b/nac3core/src/codegen/classes.rs @@ -58,13 +58,15 @@ impl<'ctx> ListValue<'ctx> { Ok(()) } - /// Creates an [ListValue] from a [PointerValue]. + /// Creates an [`ListValue`] from a [`PointerValue`]. + #[must_use] pub fn from_ptr_val(ptr: PointerValue<'ctx>, llvm_usize: IntType<'ctx>, name: Option<&'ctx str>) -> Self { assert_is_list(ptr, llvm_usize); ListValue(ptr, name) } - /// Returns the underlying [PointerValue] pointing to the `list` instance. + /// Returns the underlying [`PointerValue`] pointing to the `list` instance. + #[must_use] pub fn get_ptr(&self) -> PointerValue<'ctx> { self.0 } @@ -119,8 +121,9 @@ impl<'ctx> ListValue<'ctx> { /// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr` /// on the field. + #[must_use] pub fn get_data(&self) -> ListDataProxy<'ctx> { - ListDataProxy(self.clone()) + ListDataProxy(*self) } /// Stores the `size` of this `list` into this instance. @@ -140,7 +143,7 @@ impl<'ctx> ListValue<'ctx> { pub fn load_size(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { let psize = self.get_size_ptr(ctx); let var_name = name - .map(|v| v.to_string()) + .map(ToString::to_string) .or_else(|| self.1.map(|v| format!("{v}.size"))) .unwrap_or_default(); @@ -164,6 +167,9 @@ impl<'ctx> ListDataProxy<'ctx> { .unwrap() } + /// # Safety + /// + /// This function should be called with a valid index. pub unsafe fn ptr_offset_unchecked( &self, ctx: &CodeGenContext<'ctx, '_>, @@ -211,6 +217,9 @@ impl<'ctx> ListDataProxy<'ctx> { } } + /// # Safety + /// + /// This function should be called with a valid index. pub unsafe fn get_unchecked( &self, ctx: &mut CodeGenContext<'ctx, '_>, @@ -271,13 +280,15 @@ impl<'ctx> RangeValue<'ctx> { Ok(()) } - /// Creates an [RangeValue] from a [PointerValue]. + /// Creates an [`RangeValue`] from a [`PointerValue`]. + #[must_use] pub fn from_ptr_val(ptr: PointerValue<'ctx>, name: Option<&'ctx str>) -> Self { assert_is_range(ptr); RangeValue(ptr, name) } - /// Returns the underlying [PointerValue] pointing to the `range` instance. + /// Returns the underlying [`PointerValue`] pointing to the `range` instance. + #[must_use] pub fn get_ptr(&self) -> PointerValue<'ctx> { self.0 } @@ -337,7 +348,7 @@ impl<'ctx> RangeValue<'ctx> { pub fn load_start(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { let pstart = self.get_start_ptr(ctx); let var_name = name - .map(|v| v.to_string()) + .map(ToString::to_string) .or_else(|| self.1.map(|v| format!("{v}.start"))) .unwrap_or_default(); @@ -362,7 +373,7 @@ impl<'ctx> RangeValue<'ctx> { pub fn load_end(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { let pend = self.get_end_ptr(ctx); let var_name = name - .map(|v| v.to_string()) + .map(ToString::to_string) .or_else(|| self.1.map(|v| format!("{v}.end"))) .unwrap_or_default(); @@ -387,7 +398,7 @@ impl<'ctx> RangeValue<'ctx> { pub fn load_step(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { let pstep = self.get_step_ptr(ctx); let var_name = name - .map(|v| v.to_string()) + .map(ToString::to_string) .or_else(|| self.1.map(|v| format!("{v}.step"))) .unwrap_or_default(); @@ -458,7 +469,8 @@ impl<'ctx> NDArrayValue<'ctx> { Ok(()) } - /// Creates an [NDArrayValue] from a [PointerValue]. + /// Creates an [`NDArrayValue`] from a [`PointerValue`]. + #[must_use] pub fn from_ptr_val( ptr: PointerValue<'ctx>, llvm_usize: IntType<'ctx>, @@ -468,7 +480,8 @@ impl<'ctx> NDArrayValue<'ctx> { NDArrayValue(ptr, name) } - /// Returns the underlying [PointerValue] pointing to the `NDArray` instance. + /// Returns the underlying [`PointerValue`] pointing to the `NDArray` instance. + #[must_use] pub fn get_ptr(&self) -> PointerValue<'ctx> { self.0 } @@ -539,8 +552,9 @@ impl<'ctx> NDArrayValue<'ctx> { } /// Returns a proxy object to the field storing the size of each dimension of this `NDArray`. + #[must_use] pub fn get_dims(&self) -> NDArrayDimsProxy<'ctx> { - NDArrayDimsProxy(self.clone()) + NDArrayDimsProxy(*self) } /// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr` @@ -575,8 +589,9 @@ impl<'ctx> NDArrayValue<'ctx> { } /// Returns a proxy object to the field storing the data of this `NDArray`. + #[must_use] pub fn get_data(&self) -> NDArrayDataProxy<'ctx> { - NDArrayDataProxy(self.clone()) + NDArrayDataProxy(*self) } } @@ -665,6 +680,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> { .unwrap() } + /// # Safety + /// + /// This function should be called with a valid index. pub unsafe fn ptr_to_data_flattened_unchecked( &self, ctx: &CodeGenContext<'ctx, '_>, @@ -710,6 +728,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> { } } + /// # Safety + /// + /// This function should be called with a valid index. pub unsafe fn get_flattened_unchecked( &self, ctx: &mut CodeGenContext<'ctx, '_>, @@ -732,6 +753,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> { ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap() } + /// # Safety + /// + /// This function should be called with valid indices. pub unsafe fn ptr_offset_unchecked( &self, ctx: &CodeGenContext<'ctx, '_>, @@ -750,7 +774,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> { ctx, self.0, indices, - ).unwrap(); + ); unsafe { ctx.builder.build_in_bounds_gep( @@ -761,6 +785,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> { } } + /// # Safety + /// + /// This function should be called with valid indices. pub unsafe fn ptr_offset_unchecked_const( &self, ctx: &mut CodeGenContext<'ctx, '_>, @@ -773,7 +800,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> { ctx, self.0, indices, - ).unwrap(); + ); unsafe { ctx.builder.build_in_bounds_gep( @@ -953,6 +980,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> { } } + /// # Safety + /// + /// This function should be called with valid indices. pub unsafe fn get_unsafe_const( &self, ctx: &mut CodeGenContext<'ctx, '_>, @@ -964,6 +994,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> { ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap() } + /// # Safety + /// + /// This function should be called with valid indices. pub unsafe fn get_unsafe( &self, ctx: &mut CodeGenContext<'ctx, '_>, diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 68e4f051..9f07247e 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -1180,22 +1180,21 @@ pub fn gen_binop_expr<'ctx, G: CodeGenerator>( } }; - let signature = match ctx.calls.get(&loc.into()) { - Some(call) => ctx.unifier.get_call_signature(*call).unwrap(), - None => { - let left_enum_ty = ctx.unifier.get_ty_immutable(left.custom.unwrap()); - let TypeEnum::TObj { fields, .. } = left_enum_ty.as_ref() else { - unreachable!("must be tobj") - }; + let signature = if let Some(call) = ctx.calls.get(&loc.into()) { + ctx.unifier.get_call_signature(*call).unwrap() + } else { + let left_enum_ty = ctx.unifier.get_ty_immutable(left.custom.unwrap()); + let TypeEnum::TObj { fields, .. } = left_enum_ty.as_ref() else { + unreachable!("must be tobj") + }; - let fn_ty = fields.get(&op_name).unwrap().0; - let fn_ty_enum = ctx.unifier.get_ty_immutable(fn_ty); - let TypeEnum::TFunc(sig) = fn_ty_enum.as_ref() else { - unreachable!() - }; + let fn_ty = fields.get(&op_name).unwrap().0; + let fn_ty_enum = ctx.unifier.get_ty_immutable(fn_ty); + let TypeEnum::TFunc(sig) = fn_ty_enum.as_ref() else { + unreachable!() + }; - sig.clone() - }, + sig.clone() }; let fun_id = { let defs = ctx.top_level.definitions.read(); @@ -1380,7 +1379,7 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>( .unwrap(), ctx.builder .build_int_mul( - ndarray_num_dims.into(), + ndarray_num_dims, llvm_usize.size_of(), "", ) @@ -1426,7 +1425,7 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>( .unwrap(), ctx.builder .build_int_mul( - ndarray_num_elems.into(), + ndarray_num_elems, llvm_ndarray_data_t.size_of().unwrap(), "", ) @@ -2078,7 +2077,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>( *ty, *ndims, v, - &*slice, + slice, ) } TypeEnum::TTuple { .. } => { diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index c5c6aedb..595313cd 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -94,9 +94,9 @@ pub trait CodeGenerator { /// Allocate memory for a variable and return a pointer pointing to it. /// The default implementation places the allocations at the start of the function. - fn gen_array_var_alloc<'ctx, 'a>( + fn gen_array_var_alloc<'ctx>( &mut self, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, ty: BasicTypeEnum<'ctx>, size: IntValue<'ctx>, name: Option<&str>, diff --git a/nac3core/src/codegen/irrt/mod.rs b/nac3core/src/codegen/irrt/mod.rs index dea0ceb6..fffbc426 100644 --- a/nac3core/src/codegen/irrt/mod.rs +++ b/nac3core/src/codegen/irrt/mod.rs @@ -569,11 +569,11 @@ pub fn call_j0<'ctx>( .unwrap() } -/// Generates a call to `__nac3_ndarray_calc_size`. Returns an [IntValue] representing the +/// Generates a call to `__nac3_ndarray_calc_size`. Returns an [`IntValue`] representing the /// calculated total size. /// -/// * `num_dims` - An [IntValue] containing the number of dimensions. -/// * `dims` - A [PointerValue] to an array containing the size of each dimensions. +/// * `num_dims` - An [`IntValue`] containing the number of dimensions. +/// * `dims` - A [`PointerValue`] to an array containing the size of each dimension. pub fn call_ndarray_calc_size<'ctx>( generator: &dyn CodeGenerator, ctx: &mut CodeGenContext<'ctx, '_>, @@ -619,9 +619,9 @@ pub fn call_ndarray_calc_size<'ctx>( /// Generates a call to `__nac3_ndarray_init_dims`. /// -/// * `ndarray` - LLVM pointer to the NDArray. This value must be the LLVM representation of an +/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an /// `NDArray`. -/// * `shape` - LLVM pointer to the `shape` of the NDArray. This value must be the LLVM +/// * `shape` - LLVM pointer to the `shape` of the `NDArray`. This value must be the LLVM /// representation of a `list`. pub fn call_ndarray_init_dims<'ctx>( generator: &dyn CodeGenerator, @@ -674,14 +674,14 @@ pub fn call_ndarray_init_dims<'ctx>( /// Generates a call to `__nac3_ndarray_calc_nd_indices`. /// /// * `index` - The index to compute the multidimensional index for. -/// * `ndarray` - LLVM pointer to the NDArray. This value must be the LLVM representation of an +/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an /// `NDArray`. pub fn call_ndarray_calc_nd_indices<'ctx>( generator: &dyn CodeGenerator, ctx: &mut CodeGenContext<'ctx, '_>, index: IntValue<'ctx>, ndarray: NDArrayValue<'ctx>, -) -> Result, String> { +) -> PointerValue<'ctx> { let llvm_void = ctx.ctx.void_type(); let llvm_usize = generator.get_size_type(ctx.ctx); @@ -728,7 +728,7 @@ pub fn call_ndarray_calc_nd_indices<'ctx>( ) .unwrap(); - Ok(indices) + indices } fn call_ndarray_flatten_index_impl<'ctx>( @@ -737,7 +737,7 @@ fn call_ndarray_flatten_index_impl<'ctx>( ndarray: NDArrayValue<'ctx>, indices: PointerValue<'ctx>, indices_size: IntValue<'ctx>, -) -> Result, String> { +) -> IntValue<'ctx> { let llvm_i32 = ctx.ctx.i32_type(); let llvm_usize = generator.get_size_type(ctx.ctx); @@ -746,7 +746,7 @@ fn call_ndarray_flatten_index_impl<'ctx>( debug_assert_eq!( IntType::try_from(indices.get_type().get_element_type()) - .map(|itype| itype.get_bit_width()) + .map(IntType::get_bit_width) .unwrap_or_default(), llvm_i32.get_bit_width(), "Expected i32 value for argument `indices` to `call_ndarray_flatten_index_impl`" @@ -795,13 +795,13 @@ fn call_ndarray_flatten_index_impl<'ctx>( .map(Either::unwrap_left) .unwrap(); - Ok(index) + index } /// Generates a call to `__nac3_ndarray_flatten_index`. Returns the flattened index for the /// multidimensional index. /// -/// * `ndarray` - LLVM pointer to the NDArray. This value must be the LLVM representation of an +/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an /// `NDArray`. /// * `indices` - The multidimensional index to compute the flattened index for. pub fn call_ndarray_flatten_index<'ctx>( @@ -809,7 +809,7 @@ pub fn call_ndarray_flatten_index<'ctx>( ctx: &CodeGenContext<'ctx, '_>, ndarray: NDArrayValue<'ctx>, indices: ListValue<'ctx>, -) -> Result, String> { +) -> IntValue<'ctx> { let indices_size = indices.load_size(ctx, None); let indices_data = indices.get_data(); @@ -824,7 +824,7 @@ pub fn call_ndarray_flatten_index<'ctx>( /// Generates a call to `__nac3_ndarray_flatten_index`. Returns the flattened index for the /// multidimensional index. /// -/// * `ndarray` - LLVM pointer to the NDArray. This value must be the LLVM representation of an +/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an /// `NDArray`. /// * `indices` - The multidimensional index to compute the flattened index for. pub fn call_ndarray_flatten_index_const<'ctx>( @@ -832,7 +832,7 @@ pub fn call_ndarray_flatten_index_const<'ctx>( ctx: &mut CodeGenContext<'ctx, '_>, ndarray: NDArrayValue<'ctx>, indices: ArrayValue<'ctx>, -) -> Result, String> { +) -> IntValue<'ctx> { let llvm_usize = generator.get_size_type(ctx.ctx); let indices_size = indices.get_type().len(); @@ -841,7 +841,7 @@ pub fn call_ndarray_flatten_index_const<'ctx>( indices.get_type().get_element_type(), llvm_usize.const_int(indices_size as u64, false), None - )?; + ).unwrap(); for i in 0..indices_size { let v = ctx.builder.build_extract_value(indices, i, "") .unwrap() diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index ebe8e4b2..d69ac2b3 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -408,6 +408,7 @@ pub struct CodeGenTask { /// /// This function is used to obtain the in-memory representation of `ty`, e.g. a `bool` variable /// would be represented by an `i8`. +#[allow(clippy::too_many_arguments)] fn get_llvm_type<'ctx>( ctx: &'ctx Context, module: &Module<'ctx>, @@ -543,6 +544,7 @@ fn get_llvm_type<'ctx>( /// ABI representation is that the in-memory representation must be at least byte-sized and must /// be byte-aligned for the variable to be addressable in memory, whereas there is no such /// restriction for ABI representations. +#[allow(clippy::too_many_arguments)] fn get_llvm_abi_type<'ctx>( ctx: &'ctx Context, module: &Module<'ctx>, @@ -809,7 +811,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte /* filename */ &task .body - .get(0) + .first() .map_or_else( || "".to_string(), |f| f.location.file.0.to_string(), @@ -839,7 +841,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte inkwell::debug_info::DIFlags::PUBLIC, ); let (row, col) = - task.body.get(0).map_or_else(|| (0, 0), |b| (b.location.row, b.location.column)); + task.body.first().map_or_else(|| (0, 0), |b| (b.location.row, b.location.column)); let func_scope: DISubprogram<'_> = dibuilder.create_function( /* scope */ compile_unit.as_debug_info_scope(), /* func name */ symbol, diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index 810cfe0f..ef1ec629 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -55,7 +55,7 @@ pub fn gen_var<'ctx>( Ok(ptr) } -/// See [CodeGenerator::gen_array_var_alloc]. +/// See [`CodeGenerator::gen_array_var_alloc`]. pub fn gen_array_var<'ctx, 'a, T: BasicType<'ctx>>( ctx: &mut CodeGenContext<'ctx, 'a>, ty: T, @@ -484,7 +484,7 @@ pub fn gen_for_callback<'ctx, 'a, I, InitFn, CondFn, BodyFn, UpdateFn>( BodyFn: FnOnce(&mut dyn CodeGenerator, &mut CodeGenContext<'ctx, 'a>, I) -> Result<(), String>, UpdateFn: FnOnce(&mut dyn CodeGenerator, &mut CodeGenContext<'ctx, 'a>, I) -> Result<(), String>, { - let current = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap(); + let current = ctx.builder.get_insert_block().and_then(BasicBlock::get_parent).unwrap(); let init_bb = ctx.ctx.append_basic_block(current, "for.init"); // The BB containing the loop condition check let cond_bb = ctx.ctx.append_basic_block(current, "for.cond"); diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 53b852f5..a2a663f5 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -119,7 +119,6 @@ impl SymbolValue { /// * `constant` - The constant to create the value from. pub fn from_constant_inferred( constant: &Constant, - unifier: &mut Unifier ) -> Result { match constant { Constant::None => Ok(SymbolValue::OptionNone), @@ -140,7 +139,7 @@ impl SymbolValue { Constant::Tuple(t) => { let elems = t .iter() - .map(|constant| Self::from_constant_inferred(constant, unifier)) + .map(Self::from_constant_inferred) .collect::, _>>()?; Ok(SymbolValue::Tuple(elems)) } @@ -507,7 +506,7 @@ pub fn parse_type_annotation( let values = if let Tuple { elts, .. } = &slice.node { elts.iter() - .map(|elt| parse_literal(elt)) + .map(&mut parse_literal) .collect::, _>>()? } else { vec![parse_literal(slice)?] @@ -577,8 +576,8 @@ pub fn parse_type_annotation( ])) } } - Constant { value, .. } => SymbolValue::from_constant_inferred(value, unifier) - .map(|v| unifier.get_fresh_literal(vec![v], Some(expr.location.clone()))) + Constant { value, .. } => SymbolValue::from_constant_inferred(value) + .map(|v| unifier.get_fresh_literal(vec![v], Some(expr.location))) .map_err(|err| HashSet::from([err])), _ => Err(HashSet::from([ format!("unsupported type expression at {}", expr.location), diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index bd619fc7..c060ddc2 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -18,6 +18,7 @@ use crate::{ gen_ndarray_empty, gen_ndarray_eye, gen_ndarray_full, + gen_ndarray_identity, gen_ndarray_ones, gen_ndarray_zeros, }, @@ -30,7 +31,6 @@ use inkwell::{ IntPredicate }; use itertools::Either; -use crate::toplevel::numpy::gen_ndarray_identity; type BuiltinInfo = Vec<(Arc>, Option)>; @@ -903,7 +903,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { // type variable &[(list_int32, "shape")], Box::new(|ctx, obj, fun, args, generator| { - gen_ndarray_empty(ctx, obj, fun, args, generator) + gen_ndarray_empty(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }), ), @@ -916,7 +916,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { // type variable &[(list_int32, "shape")], Box::new(|ctx, obj, fun, args, generator| { - gen_ndarray_empty(ctx, obj, fun, args, generator) + gen_ndarray_empty(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }), ), @@ -929,7 +929,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { // type variable &[(list_int32, "shape")], Box::new(|ctx, obj, fun, args, generator| { - gen_ndarray_zeros(ctx, obj, fun, args, generator) + gen_ndarray_zeros(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }), ), @@ -942,7 +942,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { // type variable &[(list_int32, "shape")], Box::new(|ctx, obj, fun, args, generator| { - gen_ndarray_ones(ctx, obj, fun, args, generator) + gen_ndarray_ones(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }), ), @@ -958,7 +958,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { // type variable &[(list_int32, "shape"), (tv, "fill_value")], Box::new(|ctx, obj, fun, args, generator| { - gen_ndarray_full(ctx, obj, fun, args, generator) + gen_ndarray_full(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }), ) @@ -980,13 +980,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { ret: ndarray_float_2d, vars: var_map.clone(), })), - var_id: Default::default(), - instance_to_symbol: Default::default(), - instance_to_stmt: Default::default(), + var_id: Vec::default(), + instance_to_symbol: HashMap::default(), + instance_to_stmt: HashMap::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, obj, fun, args, generator| { - gen_ndarray_eye(ctx, obj, fun, args, generator) + gen_ndarray_eye(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }, )))), @@ -999,7 +999,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { ndarray_float_2d, &[(int32, "n")], Box::new(|ctx, obj, fun, args, generator| { - gen_ndarray_identity(ctx, obj, fun, args, generator) + gen_ndarray_identity(ctx, &obj, fun, &args, generator) .map(|val| Some(val.as_basic_value_enum())) }), ), @@ -1527,14 +1527,14 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { None, ).into_int_value(); - if len.get_type().get_bit_width() != 32 { + if len.get_type().get_bit_width() == 32 { + Some(len.into()) + } else { Some(ctx.builder .build_int_truncate(len, llvm_i32, "len") .map(Into::into) .unwrap() ) - } else { - Some(len.into()) } } _ => unreachable!(), diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 48f7c1ac..77895f89 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -1350,9 +1350,9 @@ impl TopLevelComposer { ])) } } - ast::StmtKind::Assign { .. } => {}, // we don't class attributes - ast::StmtKind::Pass { .. } => {} - ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior + ast::StmtKind::Assign { .. } // we don't class attributes + | ast::StmtKind::Expr { value: _, .. } // typically a docstring; ignoring all expressions matches CPython behavior + | ast::StmtKind::Pass { .. } => {} _ => { return Err(HashSet::from([ format!( diff --git a/nac3core/src/toplevel/numpy.rs b/nac3core/src/toplevel/numpy.rs index 357a29fd..a842fbf8 100644 --- a/nac3core/src/toplevel/numpy.rs +++ b/nac3core/src/toplevel/numpy.rs @@ -21,10 +21,10 @@ use crate::{ /// Creates an `NDArray` instance from a constant shape. /// /// * `elem_ty` - The element type of the `NDArray`. -/// * `shape` - The shape of the `NDArray`, represented as an LLVM [ArrayValue]. -fn create_ndarray_const_shape<'ctx, 'a>( +/// * `shape` - The shape of the `NDArray`, represented as an LLVM [`ArrayValue`]. +fn create_ndarray_const_shape<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, shape: ArrayValue<'ctx> ) -> Result, String> { @@ -94,9 +94,9 @@ fn create_ndarray_const_shape<'ctx, 'a>( Ok(ndarray) } -fn ndarray_zero_value<'ctx, 'a>( +fn ndarray_zero_value<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, ) -> BasicValueEnum<'ctx> { if [ctx.primitives.int32, ctx.primitives.uint32].iter().any(|ty| ctx.unifier.unioned(elem_ty, *ty)) { @@ -108,15 +108,15 @@ fn ndarray_zero_value<'ctx, 'a>( } else if ctx.unifier.unioned(elem_ty, ctx.primitives.bool) { ctx.ctx.bool_type().const_zero().into() } else if ctx.unifier.unioned(elem_ty, ctx.primitives.str) { - ctx.gen_string(generator, "").into() + ctx.gen_string(generator, "") } else { unreachable!() } } -fn ndarray_one_value<'ctx, 'a>( +fn ndarray_one_value<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, ) -> BasicValueEnum<'ctx> { if [ctx.primitives.int32, ctx.primitives.uint32].iter().any(|ty| ctx.unifier.unioned(elem_ty, *ty)) { @@ -130,7 +130,7 @@ fn ndarray_one_value<'ctx, 'a>( } else if ctx.unifier.unioned(elem_ty, ctx.primitives.bool) { ctx.ctx.bool_type().const_int(1, false).into() } else if ctx.unifier.unioned(elem_ty, ctx.primitives.str) { - ctx.gen_string(generator, "1").into() + ctx.gen_string(generator, "1") } else { unreachable!() } @@ -138,11 +138,11 @@ fn ndarray_one_value<'ctx, 'a>( /// LLVM-typed implementation for generating the implementation for constructing an `NDArray`. /// -/// * `elem_ty` - The element type of the NDArray. -/// * `shape` - The `shape` parameter used to construct the NDArray. -fn call_ndarray_empty_impl<'ctx, 'a>( +/// * `elem_ty` - The element type of the `NDArray`. +/// * `shape` - The `shape` parameter used to construct the `NDArray`. +fn call_ndarray_empty_impl<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, shape: ListValue<'ctx>, ) -> Result, String> { @@ -308,14 +308,14 @@ fn ndarray_fill_flattened<'ctx, 'a, ValueFn>( /// /// Note that this differs from `ndarray.fill`, which instead replaces all first-dimension elements /// with the given value (as opposed to all elements within the array). -fn ndarray_fill_indexed<'ctx, 'a, ValueFn>( +fn ndarray_fill_indexed<'ctx, ValueFn>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, ndarray: NDArrayValue<'ctx>, value_fn: ValueFn, ) -> Result<(), String> where - ValueFn: Fn(&mut dyn CodeGenerator, &mut CodeGenContext<'ctx, 'a>, PointerValue<'ctx>) -> Result, String>, + ValueFn: Fn(&mut dyn CodeGenerator, &mut CodeGenContext<'ctx, '_>, PointerValue<'ctx>) -> Result, String>, { ndarray_fill_flattened( generator, @@ -327,7 +327,7 @@ fn ndarray_fill_indexed<'ctx, 'a, ValueFn>( ctx, idx, ndarray, - )?; + ); value_fn(generator, ctx, indices) } @@ -336,11 +336,11 @@ fn ndarray_fill_indexed<'ctx, 'a, ValueFn>( /// LLVM-typed implementation for generating the implementation for `ndarray.zeros`. /// -/// * `elem_ty` - The element type of the NDArray. -/// * `shape` - The `shape` parameter used to construct the NDArray. -fn call_ndarray_zeros_impl<'ctx, 'a>( +/// * `elem_ty` - The element type of the `NDArray`. +/// * `shape` - The `shape` parameter used to construct the `NDArray`. +fn call_ndarray_zeros_impl<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, shape: ListValue<'ctx>, ) -> Result, String> { @@ -372,11 +372,11 @@ fn call_ndarray_zeros_impl<'ctx, 'a>( /// LLVM-typed implementation for generating the implementation for `ndarray.ones`. /// -/// * `elem_ty` - The element type of the NDArray. -/// * `shape` - The `shape` parameter used to construct the NDArray. -fn call_ndarray_ones_impl<'ctx, 'a>( +/// * `elem_ty` - The element type of the `NDArray`. +/// * `shape` - The `shape` parameter used to construct the `NDArray`. +fn call_ndarray_ones_impl<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, shape: ListValue<'ctx>, ) -> Result, String> { @@ -408,11 +408,11 @@ fn call_ndarray_ones_impl<'ctx, 'a>( /// LLVM-typed implementation for generating the implementation for `ndarray.ones`. /// -/// * `elem_ty` - The element type of the NDArray. -/// * `shape` - The `shape` parameter used to construct the NDArray. -fn call_ndarray_full_impl<'ctx, 'a>( +/// * `elem_ty` - The element type of the `NDArray`. +/// * `shape` - The `shape` parameter used to construct the `NDArray`. +fn call_ndarray_full_impl<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, shape: ListValue<'ctx>, fill_value: BasicValueEnum<'ctx>, @@ -465,7 +465,7 @@ fn call_ndarray_full_impl<'ctx, 'a>( copy.into() } else if fill_value.is_int_value() || fill_value.is_float_value() { - fill_value.into() + fill_value } else { unreachable!() }; @@ -479,10 +479,10 @@ fn call_ndarray_full_impl<'ctx, 'a>( /// LLVM-typed implementation for generating the implementation for `ndarray.eye`. /// -/// * `elem_ty` - The element type of the NDArray. -fn call_ndarray_eye_impl<'ctx, 'a>( +/// * `elem_ty` - The element type of the `NDArray`. +fn call_ndarray_eye_impl<'ctx>( generator: &mut dyn CodeGenerator, - ctx: &mut CodeGenContext<'ctx, 'a>, + ctx: &mut CodeGenContext<'ctx, '_>, elem_ty: Type, nrows: IntValue<'ctx>, ncols: IntValue<'ctx>, @@ -552,11 +552,11 @@ fn call_ndarray_eye_impl<'ctx, 'a>( } /// Generates LLVM IR for `ndarray.empty`. -pub fn gen_ndarray_empty<'ctx, 'a>( - context: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, ValueEnum<'ctx>)>, +pub fn gen_ndarray_empty<'ctx>( + context: &mut CodeGenContext<'ctx, '_>, + obj: &Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, ValueEnum<'ctx>)>, + args: &[(Option, ValueEnum<'ctx>)], generator: &mut dyn CodeGenerator, ) -> Result, String> { assert!(obj.is_none()); @@ -576,11 +576,11 @@ pub fn gen_ndarray_empty<'ctx, 'a>( } /// Generates LLVM IR for `ndarray.zeros`. -pub fn gen_ndarray_zeros<'ctx, 'a>( - context: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, ValueEnum<'ctx>)>, +pub fn gen_ndarray_zeros<'ctx>( + context: &mut CodeGenContext<'ctx, '_>, + obj: &Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, ValueEnum<'ctx>)>, + args: &[(Option, ValueEnum<'ctx>)], generator: &mut dyn CodeGenerator, ) -> Result, String> { assert!(obj.is_none()); @@ -600,11 +600,11 @@ pub fn gen_ndarray_zeros<'ctx, 'a>( } /// Generates LLVM IR for `ndarray.ones`. -pub fn gen_ndarray_ones<'ctx, 'a>( - context: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, ValueEnum<'ctx>)>, +pub fn gen_ndarray_ones<'ctx>( + context: &mut CodeGenContext<'ctx, '_>, + obj: &Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, ValueEnum<'ctx>)>, + args: &[(Option, ValueEnum<'ctx>)], generator: &mut dyn CodeGenerator, ) -> Result, String> { assert!(obj.is_none()); @@ -624,11 +624,11 @@ pub fn gen_ndarray_ones<'ctx, 'a>( } /// Generates LLVM IR for `ndarray.full`. -pub fn gen_ndarray_full<'ctx, 'a>( - context: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, ValueEnum<'ctx>)>, +pub fn gen_ndarray_full<'ctx>( + context: &mut CodeGenContext<'ctx, '_>, + obj: &Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, ValueEnum<'ctx>)>, + args: &[(Option, ValueEnum<'ctx>)], generator: &mut dyn CodeGenerator, ) -> Result, String> { assert!(obj.is_none()); @@ -652,11 +652,11 @@ pub fn gen_ndarray_full<'ctx, 'a>( } /// Generates LLVM IR for `ndarray.eye`. -pub fn gen_ndarray_eye<'ctx, 'a>( - context: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, ValueEnum<'ctx>)>, +pub fn gen_ndarray_eye<'ctx>( + context: &mut CodeGenContext<'ctx, '_>, + obj: &Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, ValueEnum<'ctx>)>, + args: &[(Option, ValueEnum<'ctx>)], generator: &mut dyn CodeGenerator, ) -> Result, String> { assert!(obj.is_none()); @@ -668,7 +668,7 @@ pub fn gen_ndarray_eye<'ctx, 'a>( let ncols_ty = fun.0.args[1].ty; let ncols_arg = args.iter() - .find(|arg| arg.0.map(|name| name == fun.0.args[1].name).unwrap_or(false)) + .find(|arg| arg.0.is_some_and(|name| name == fun.0.args[1].name)) .map(|arg| arg.1.clone().to_basic_value_enum(context, generator, ncols_ty)) .unwrap_or_else(|| { args[0].1.clone().to_basic_value_enum(context, generator, nrows_ty) @@ -676,7 +676,7 @@ pub fn gen_ndarray_eye<'ctx, 'a>( let offset_ty = fun.0.args[2].ty; let offset_arg = args.iter() - .find(|arg| arg.0.map(|name| name == fun.0.args[2].name).unwrap_or(false)) + .find(|arg| arg.0.is_some_and(|name| name == fun.0.args[2].name)) .map(|arg| arg.1.clone().to_basic_value_enum(context, generator, offset_ty)) .unwrap_or_else(|| { Ok(context.gen_symbol_val( @@ -697,11 +697,11 @@ pub fn gen_ndarray_eye<'ctx, 'a>( } /// Generates LLVM IR for `ndarray.identity`. -pub fn gen_ndarray_identity<'ctx, 'a>( - context: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, ValueEnum<'ctx>)>, +pub fn gen_ndarray_identity<'ctx>( + context: &mut CodeGenContext<'ctx, '_>, + obj: &Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, ValueEnum<'ctx>)>, + args: &[(Option, ValueEnum<'ctx>)], generator: &mut dyn CodeGenerator, ) -> Result, String> { assert!(obj.is_none()); diff --git a/nac3core/src/toplevel/type_annotation.rs b/nac3core/src/toplevel/type_annotation.rs index 94897ff2..4209a58f 100644 --- a/nac3core/src/toplevel/type_annotation.rs +++ b/nac3core/src/toplevel/type_annotation.rs @@ -519,7 +519,7 @@ pub fn get_type_from_type_annotation_kinds( TypeAnnotation::Primitive(ty) | TypeAnnotation::TypeVar(ty) => Ok(*ty), TypeAnnotation::Literal(values) => { let values = values.iter() - .map(|v| SymbolValue::from_constant_inferred(v, unifier)) + .map(SymbolValue::from_constant_inferred) .collect::, _>>() .map_err(|err| HashSet::from([err]))?; diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index 8f12685b..e1c638dd 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -52,6 +52,7 @@ pub struct PrimitiveStore { impl PrimitiveStore { /// Returns a [Type] representing `size_t`. + #[must_use] pub fn usize(&self) -> Type { match self.size_t { 32 => self.uint32, @@ -1074,6 +1075,7 @@ impl<'a> Inferencer<'a> { Ok(Located { location, custom: Some(ret), node: ExprKind::Call { func, args, keywords } }) } + #[allow(clippy::unnecessary_wraps)] fn infer_identifier(&mut self, id: StrRef) -> InferenceResult { Ok(if let Some(ty) = self.variable_mapping.get(&id) { *ty @@ -1126,6 +1128,7 @@ impl<'a> Inferencer<'a> { Ok(self.unifier.add_ty(TypeEnum::TList { ty })) } + #[allow(clippy::unnecessary_wraps)] fn infer_tuple(&mut self, elts: &[ast::Expr>]) -> InferenceResult { let ty = elts.iter().map(|x| x.custom.unwrap()).collect(); Ok(self.unifier.add_ty(TypeEnum::TTuple { ty })) @@ -1242,18 +1245,18 @@ impl<'a> Inferencer<'a> { &mut self, value: &ast::Expr>, dummy_tvar: Type, - ndims: &Type, + ndims: Type, ) -> InferenceResult { debug_assert!(matches!( &*self.unifier.get_ty_immutable(dummy_tvar), TypeEnum::TVar { is_const_generic: false, .. } )); - let constrained_ty = self.unifier.add_ty(TypeEnum::TNDArray { ty: dummy_tvar, ndims: *ndims }); + let constrained_ty = self.unifier.add_ty(TypeEnum::TNDArray { ty: dummy_tvar, ndims }); self.constrain(value.custom.unwrap(), constrained_ty, &value.location)?; - let TypeEnum::TLiteral { values, .. } = &*self.unifier.get_ty_immutable(*ndims) else { - panic!("Expected TLiteral for TNDArray.ndims, got {}", self.unifier.stringify(*ndims)) + let TypeEnum::TLiteral { values, .. } = &*self.unifier.get_ty_immutable(ndims) else { + panic!("Expected TLiteral for TNDArray.ndims, got {}", self.unifier.stringify(ndims)) }; let ndims = values.iter() @@ -1320,7 +1323,7 @@ impl<'a> Inferencer<'a> { } ExprKind::Constant { value: ast::Constant::Int(val), .. } => { if let TypeEnum::TNDArray { ndims, .. } = &*self.unifier.get_ty(value.custom.unwrap()) { - self.infer_subscript_ndarray(value, ty, ndims) + self.infer_subscript_ndarray(value, ty, *ndims) } else { // the index is a constant, so value can be a sequence. let ind: Option = (*val).try_into().ok(); @@ -1350,7 +1353,7 @@ impl<'a> Inferencer<'a> { } TypeEnum::TNDArray { ndims, .. } => { self.constrain(slice.custom.unwrap(), self.primitives.usize(), &slice.location)?; - self.infer_subscript_ndarray(value, ty, ndims) + self.infer_subscript_ndarray(value, ty, *ndims) } _ => unreachable!(), } diff --git a/nac3core/src/typecheck/typedef/mod.rs b/nac3core/src/typecheck/typedef/mod.rs index ae84b0a6..7a1c2b9d 100644 --- a/nac3core/src/typecheck/typedef/mod.rs +++ b/nac3core/src/typecheck/typedef/mod.rs @@ -206,7 +206,7 @@ impl TypeEnum { } } - /// Returns a [TypeEnum] representing a generic `ndarray` type. + /// Returns a [`TypeEnum`] representing a generic `ndarray` type. /// /// * `dtype` - The datatype of the `ndarray`, or `None` if the datatype is generic. /// * `ndims` - The number of dimensions of the `ndarray`, or `None` if the number of dimensions is generic. @@ -262,13 +262,13 @@ impl Unifier { } } - /// Sets the [PrimitiveStore] instance within this `Unifier`. + /// Sets the [`PrimitiveStore`] instance within this `Unifier`. /// /// This function can only be invoked once. Any subsequent invocations will result in an - /// assertion error.. + /// assertion error. pub fn put_primitive_store(&mut self, primitives: &PrimitiveStore) { assert!(self.primitive_store.is_none()); - self.primitive_store.replace(primitives.clone()); + self.primitive_store.replace(*primitives); } pub unsafe fn get_unification_table(&mut self) -> &mut UnificationTable> { @@ -496,18 +496,22 @@ impl Unifier { pub fn is_concrete(&mut self, a: Type, allowed_typevars: &[Type]) -> bool { use TypeEnum::*; match &*self.get_ty(a) { - TRigidVar { .. } | TLiteral { .. } => true, + TRigidVar { .. } + | TLiteral { .. } + // functions are instantiated for each call sites, so the function type can contain + // type variables. + | TFunc { .. } => true, + TVar { .. } => allowed_typevars.iter().any(|b| self.unification_table.unioned(a, *b)), TCall { .. } => false, - TList { ty } | TVirtual { ty } => self.is_concrete(*ty, allowed_typevars), - TNDArray { ty, .. } => self.is_concrete(*ty, allowed_typevars), + TList { ty } + | TVirtual { ty } + | TNDArray { ty, .. } => self.is_concrete(*ty, allowed_typevars), + TTuple { ty } => ty.iter().all(|ty| self.is_concrete(*ty, allowed_typevars)), TObj { params: vars, .. } => { vars.values().all(|ty| self.is_concrete(*ty, allowed_typevars)) } - // functions are instantiated for each call sites, so the function type can contain - // type variables. - TFunc { .. } => true, } } @@ -748,8 +752,7 @@ impl Unifier { self.unify_impl(x, b, false)?; self.set_a_to_b(a, x); } - (TVar { fields: Some(fields), range, is_const_generic: false, .. }, TList { ty }) | - (TVar { fields: Some(fields), range, is_const_generic: false, .. }, TNDArray { ty, .. }) => { + (TVar { fields: Some(fields), range, is_const_generic: false, .. }, TList { ty } | TNDArray { ty, .. }) => { for (k, v) in fields { match *k { RecordKey::Int(_) => { @@ -795,7 +798,7 @@ impl Unifier { SymbolValue::I64(v) => v as i128, SymbolValue::U32(v) => v as i128, SymbolValue::U64(v) => v as i128, - _ => return self.incompatible_types(a, b), + _ => return Self::incompatible_types(a, b), }; let can_convert = if self.unioned(ty, primitives.int32) { @@ -811,7 +814,7 @@ impl Unifier { }; if !can_convert { - return self.incompatible_types(a, b) + return Self::incompatible_types(a, b) } } @@ -836,7 +839,7 @@ impl Unifier { let v2i = symbol_value_to_int(v2); if v1i != v2i { - return self.incompatible_types(a, b) + return Self::incompatible_types(a, b) } } } @@ -863,10 +866,10 @@ impl Unifier { } (TNDArray { ty: ty1, ndims: ndims1 }, TNDArray { ty: ty2, ndims: ndims2 }) => { if self.unify_impl(*ty1, *ty2, false).is_err() { - return self.incompatible_types(a, b) + return Self::incompatible_types(a, b) } if self.unify_impl(*ndims1, *ndims2, false).is_err() { - return self.incompatible_types(a, b) + return Self::incompatible_types(a, b) } self.set_a_to_b(a, b); } @@ -945,7 +948,7 @@ impl Unifier { TObj { obj_id: id2, params: params2, .. }, ) => { if id1 != id2 { - self.incompatible_types(a, b)?; + Self::incompatible_types(a, b)?; } // Sort the type arguments by its UnificationKey first, since `HashMap::iter` visits @@ -1015,7 +1018,7 @@ impl Unifier { } _ => { if swapped { - return self.incompatible_types(a, b); + return Self::incompatible_types(a, b); } self.unify_impl(b, a, true)?; @@ -1179,7 +1182,7 @@ impl Unifier { table.set_value(a, ty_b); } - fn incompatible_types(&mut self, a: Type, b: Type) -> Result<(), TypeError> { + fn incompatible_types(a: Type, b: Type) -> Result<(), TypeError> { Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None)) } @@ -1326,7 +1329,7 @@ impl Unifier { None } } - _ => { + TypeEnum::TCall(_) => { unreachable!("{} not expected", ty.get_type_name()) } }