Browse Source

Add `#no_broadcast` procedure parameter to disallow automatic array programming broadcasting on procedure arguments

gingerBill 1 year ago
parent
commit
29e5f94c2a

+ 6 - 6
base/runtime/core_builtin.odin

@@ -447,12 +447,12 @@ _append_elem :: #force_inline proc(array: ^$T/[dynamic]$E, arg: E, should_zero:
 }
 
 @builtin
-append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 	return _append_elem(array, arg, true, loc=loc)
 }
 
 @builtin
-non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 	return _append_elem(array, arg, false, loc=loc)
 }
 
@@ -496,12 +496,12 @@ _append_elems :: #force_inline proc(array: ^$T/[dynamic]$E, should_zero: bool, l
 }
 
 @builtin
-append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 	return _append_elems(array, true, loc, ..args)
 }
 
 @builtin
-non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 	return _append_elems(array, false, loc, ..args)
 }
 
@@ -556,7 +556,7 @@ append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: i
 
 
 @builtin
-inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
+inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
 	if array == nil {
 		return
 	}
@@ -574,7 +574,7 @@ inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle
 }
 
 @builtin
-inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
+inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
 	if array == nil {
 		return
 	}

+ 18 - 18
core/image/common.odin

@@ -651,7 +651,7 @@ alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator :=
 				// We have keyed alpha.
 				o: GA_Pixel
 				for p in inp {
-					if p == key.r {
+					if p.r == key.r {
 						o = GA_Pixel{0, key.g}
 					} else {
 						o = GA_Pixel{p.r, 255}
@@ -710,7 +710,7 @@ alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator :=
 				// We have keyed alpha.
 				o: GA_Pixel_16
 				for p in inp {
-					if p == key.r {
+					if p.r == key.r {
 						o = GA_Pixel_16{0, key.g}
 					} else {
 						o = GA_Pixel_16{p.r, 65535}
@@ -842,11 +842,11 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
 			bg  := G_Pixel{}
 			if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
 				// Background is RGB 16-bit, take just the red channel's topmost byte.
-				bg = u8(temp_bg.r >> 8)
+				bg.r = u8(temp_bg.r >> 8)
 			}
 
 			for p in inp {
-				out[0] = bg if p == key else p
+				out[0] = bg if p.r == key else p
 				out    = out[1:]
 			}
 
@@ -865,8 +865,8 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
 				for p in inp {
 					a := f32(p.g) / 255.0
 					c := ((1.0 - a) * bg + a * f32(p.r))
-					out[0] = u8(c)
-					out    = out[1:]
+					out[0].r = u8(c)
+					out      = out[1:]
 				}
 
 			} else if .alpha_premultiply in options {
@@ -874,14 +874,14 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
 				for p in inp {
 					a := f32(p.g) / 255.0
 					c := f32(p.r) * a
-					out[0] = u8(c)
-					out    = out[1:]
+					out[0].r = u8(c)
+					out      = out[1:]
 				}
 			} else {
 				// Just drop alpha on the floor.
 				for p in inp {
-					out[0] = p.r
-					out    = out[1:]
+					out[0].r = p.r
+					out      = out[1:]
 				}
 			}
 
@@ -951,11 +951,11 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
 			bg  := G_Pixel_16{}
 			if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
 				// Background is RGB 16-bit, take just the red channel.
-				bg = temp_bg.r
+				bg.r = temp_bg.r
 			}
 
 			for p in inp {
-				out[0] = bg if p == key else p
+				out[0] = bg if p.r == key else p
 				out    = out[1:]
 			}
 
@@ -974,8 +974,8 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
 				for p in inp {
 					a := f32(p.g) / 65535.0
 					c := ((1.0 - a) * bg + a * f32(p.r))
-					out[0] = u16(c)
-					out    = out[1:]
+					out[0].r = u16(c)
+					out      = out[1:]
 				}
 
 			} else if .alpha_premultiply in options {
@@ -983,14 +983,14 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
 				for p in inp {
 					a := f32(p.g) / 65535.0
 					c := f32(p.r) * a
-					out[0] = u16(c)
-					out    = out[1:]
+					out[0].r = u16(c)
+					out      = out[1:]
 				}
 			} else {
 				// Just drop alpha on the floor.
 				for p in inp {
-					out[0] = p.r
-					out    = out[1:]
+					out[0].r = p.r
+					out      = out[1:]
 				}
 			}
 

+ 1 - 1
core/math/big/prime.odin

@@ -1112,7 +1112,7 @@ internal_int_prime_next_prime :: proc(a: ^Int, trials: int, bbs_style: bool, all
 		Generate the restable.
 	*/
 	for x := 1; x < _PRIME_TAB_SIZE; x += 1 {
-		res_tab = internal_mod(a, _private_prime_table[x]) or_return
+		res_tab = cast(type_of(res_tab))(internal_mod(a, _private_prime_table[x]) or_return)
 	}
 
 	for {

+ 10 - 6
core/odin/ast/ast.odin

@@ -597,6 +597,7 @@ Field_Flag :: enum {
 	Any_Int,
 	Subtype,
 	By_Ptr,
+	No_Broadcast,
 
 	Results,
 	Tags,
@@ -616,6 +617,7 @@ field_flag_strings := [Field_Flag]string{
 	.Any_Int            = "#any_int",
 	.Subtype            = "#subtype",
 	.By_Ptr             = "#by_ptr",
+	.No_Broadcast       ="#no_broadcast",
 
 	.Results            = "results",
 	.Tags               = "field tag",
@@ -624,12 +626,13 @@ field_flag_strings := [Field_Flag]string{
 }
 
 field_hash_flag_strings := []struct{key: string, flag: Field_Flag}{
-	{"no_alias", .No_Alias},
-	{"c_vararg", .C_Vararg},
-	{"const",    .Const},
-	{"any_int",  .Any_Int},
-	{"subtype",  .Subtype},
-	{"by_ptr",   .By_Ptr},
+	{"no_alias",     .No_Alias},
+	{"c_vararg",     .C_Vararg},
+	{"const",        .Const},
+	{"any_int",      .Any_Int},
+	{"subtype",      .Subtype},
+	{"by_ptr",       .By_Ptr},
+	{"no_broadcast", .No_Broadcast},
 }
 
 
@@ -650,6 +653,7 @@ Field_Flags_Signature :: Field_Flags{
 	.Const,
 	.Any_Int,
 	.By_Ptr,
+	.No_Broadcast,
 	.Default_Parameters,
 }
 

+ 1 - 1
core/thread/thread.odin

@@ -163,7 +163,7 @@ create_and_start_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_co
 	t := create(thread_proc, priority)
 	t.data = rawptr(fn)
 	t.user_index = 1
-	t.user_args = data
+	t.user_args[0] = data
 	if self_cleanup {
 		t.flags += {.Self_Cleanup}
 	}

+ 48 - 28
src/check_expr.cpp

@@ -623,7 +623,7 @@ gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type);
 
 #define MAXIMUM_TYPE_DISTANCE 10
 
-gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type) {
+gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type, bool allow_array_programming) {
 	if (c == nullptr) {
 		GB_ASSERT(operand->mode == Addressing_Value);
 		GB_ASSERT(is_type_typed(operand->type));
@@ -832,7 +832,7 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
 
 		if (dst->Union.variants.count == 1) {
 			Type *vt = dst->Union.variants[0];
-			i64 score = check_distance_between_types(c, operand, vt);
+			i64 score = check_distance_between_types(c, operand, vt, allow_array_programming);
 			if (score >= 0) {
 				return score+2;
 			}
@@ -840,7 +840,7 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
 			i64 prev_lowest_score = -1;
 			i64 lowest_score = -1;
 			for (Type *vt : dst->Union.variants) {
-				i64 score = check_distance_between_types(c, operand, vt);
+				i64 score = check_distance_between_types(c, operand, vt, allow_array_programming);
 				if (score >= 0) {
 					if (lowest_score < 0) {
 						lowest_score = score;
@@ -863,14 +863,14 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
 	}
 
 	if (is_type_relative_pointer(dst)) {
-		i64 score = check_distance_between_types(c, operand, dst->RelativePointer.pointer_type);
+		i64 score = check_distance_between_types(c, operand, dst->RelativePointer.pointer_type, allow_array_programming);
 		if (score >= 0) {
 			return score+2;
 		}
 	}
 
 	if (is_type_relative_multi_pointer(dst)) {
-		i64 score = check_distance_between_types(c, operand, dst->RelativeMultiPointer.pointer_type);
+		i64 score = check_distance_between_types(c, operand, dst->RelativeMultiPointer.pointer_type, allow_array_programming);
 		if (score >= 0) {
 			return score+2;
 		}
@@ -896,19 +896,21 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
 		}
 	}
 
-	if (is_type_array(dst)) {
-		Type *elem = base_array_type(dst);
-		i64 distance = check_distance_between_types(c, operand, elem);
-		if (distance >= 0) {
-			return distance + 6;
+	if (allow_array_programming) {
+		if (is_type_array(dst)) {
+			Type *elem = base_array_type(dst);
+			i64 distance = check_distance_between_types(c, operand, elem, allow_array_programming);
+			if (distance >= 0) {
+				return distance + 6;
+			}
 		}
-	}
 
-	if (is_type_simd_vector(dst)) {
-		Type *dst_elem = base_array_type(dst);
-		i64 distance = check_distance_between_types(c, operand, dst_elem);
-		if (distance >= 0) {
-			return distance + 6;
+		if (is_type_simd_vector(dst)) {
+			Type *dst_elem = base_array_type(dst);
+			i64 distance = check_distance_between_types(c, operand, dst_elem, allow_array_programming);
+			if (distance >= 0) {
+				return distance + 6;
+			}
 		}
 	}
 	
@@ -918,7 +920,7 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
 		}
 		if (dst->Matrix.row_count == dst->Matrix.column_count) {
 			Type *dst_elem = base_array_type(dst);
-			i64 distance = check_distance_between_types(c, operand, dst_elem);
+			i64 distance = check_distance_between_types(c, operand, dst_elem, allow_array_programming);
 			if (distance >= 0) {
 				return distance + 7;
 			}
@@ -966,9 +968,9 @@ gb_internal i64 assign_score_function(i64 distance, bool is_variadic=false) {
 }
 
 
-gb_internal bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type *type, i64 *score_, bool is_variadic=false) {
+gb_internal bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type *type, i64 *score_, bool is_variadic=false, bool allow_array_programming=true) {
 	i64 score = 0;
-	i64 distance = check_distance_between_types(c, operand, type);
+	i64 distance = check_distance_between_types(c, operand, type, allow_array_programming);
 	bool ok = distance >= 0;
 	if (ok) {
 		score = assign_score_function(distance, is_variadic);
@@ -978,9 +980,9 @@ gb_internal bool check_is_assignable_to_with_score(CheckerContext *c, Operand *o
 }
 
 
-gb_internal bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type) {
+gb_internal bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type, bool allow_array_programming=true) {
 	i64 score = 0;
-	return check_is_assignable_to_with_score(c, operand, type, &score);
+	return check_is_assignable_to_with_score(c, operand, type, &score, /*is_variadic*/false, allow_array_programming);
 }
 
 gb_internal bool internal_check_is_assignable_to(Type *src, Type *dst) {
@@ -3142,6 +3144,14 @@ gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type
 		return true;
 	}
 
+
+	if (is_type_array(dst)) {
+		Type *elem = base_array_type(dst);
+		if (check_is_castable_to(c, operand, elem)) {
+			return true;
+		}
+	}
+
 	if (is_type_simd_vector(src) && is_type_simd_vector(dst)) {
 		if (src->SimdVector.count != dst->SimdVector.count) {
 			return false;
@@ -5853,15 +5863,20 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
 		}
 	}
 
-	auto eval_param_and_score = [](CheckerContext *c, Operand *o, Type *param_type, CallArgumentError &err, bool param_is_variadic, Entity *e, bool show_error) -> i64 {
+	auto eval_param_and_score = [](CheckerContext *c, Operand *o, Type *param_type, CallArgumentError &err, bool param_is_variadic, Entity *e, bool show_error, bool allow_array_programming) -> i64 {
 		i64 s = 0;
-		if (!check_is_assignable_to_with_score(c, o, param_type, &s, param_is_variadic)) {
+		if (!check_is_assignable_to_with_score(c, o, param_type, &s, param_is_variadic, allow_array_programming)) {
 			bool ok = false;
-			if (e && e->flags & EntityFlag_AnyInt) {
+			if (e && (e->flags & EntityFlag_AnyInt)) {
 				if (is_type_integer(param_type)) {
 					ok = check_is_castable_to(c, o, param_type);
 				}
 			}
+			if (!allow_array_programming && check_is_assignable_to_with_score(c, o, param_type, nullptr, param_is_variadic, !allow_array_programming)) {
+				if (show_error) {
+					error(o->expr, "'#no_broadcast' disallows automatic broadcasting a value across all elements of an array-like type in a procedure argument");
+				}
+			}
 			if (ok) {
 				s = assign_score_function(MAXIMUM_TYPE_DISTANCE);
 			} else {
@@ -5878,7 +5893,6 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
 				}
 				err = CallArgumentError_WrongTypes;
 			}
-
 		} else if (show_error) {
 			check_assignment(c, o, param_type, str_lit("procedure argument"));
 		}
@@ -5963,12 +5977,14 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
 			if (param_is_variadic) {
 				continue;
 			}
-			score += eval_param_and_score(c, o, e->type, err, param_is_variadic, e, show_error);
+			bool allow_array_programming = !(e && (e->flags & EntityFlag_NoBroadcast));
+			score += eval_param_and_score(c, o, e->type, err, param_is_variadic, e, show_error, allow_array_programming);
 		}
 	}
 
 	if (variadic) {
-		Type *slice = pt->params->Tuple.variables[pt->variadic_index]->type;
+		Entity *var_entity = pt->params->Tuple.variables[pt->variadic_index];
+		Type *slice = var_entity->type;
 		GB_ASSERT(is_type_slice(slice));
 		Type *elem = base_type(slice)->Slice.elem;
 		Type *t = elem;
@@ -5994,7 +6010,8 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
 					return CallArgumentError_MultipleVariadicExpand;
 				}
 			}
-			score += eval_param_and_score(c, o, t, err, true, nullptr, show_error);
+			bool allow_array_programming = !(var_entity && (var_entity->flags & EntityFlag_NoBroadcast));
+			score += eval_param_and_score(c, o, t, err, true, nullptr, show_error, allow_array_programming);
 		}
 	}
 
@@ -11148,6 +11165,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan
 		if (f->flags&FieldFlag_any_int) {
 			str = gb_string_appendc(str, "#any_int ");
 		}
+		if (f->flags&FieldFlag_no_broadcast) {
+			str = gb_string_appendc(str, "#no_broadcast ");
+		}
 		if (f->flags&FieldFlag_const) {
 			str = gb_string_appendc(str, "#const ");
 		}

+ 15 - 1
src/check_type.cpp

@@ -1869,6 +1869,10 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
 					error(name, "'#any_int' can only be applied to variable fields");
 					p->flags &= ~FieldFlag_any_int;
 				}
+				if (p->flags&FieldFlag_no_broadcast) {
+					error(name, "'#no_broadcast' can only be applied to variable fields");
+					p->flags &= ~FieldFlag_no_broadcast;
+				}
 				if (p->flags&FieldFlag_by_ptr) {
 					error(name, "'#by_ptr' can only be applied to variable fields");
 					p->flags &= ~FieldFlag_by_ptr;
@@ -1926,7 +1930,13 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
 							}
 						}
 					}
-					if (type != t_invalid && !check_is_assignable_to(ctx, &op, type)) {
+
+					bool allow_array_programming = true;
+					if (p->flags&FieldFlag_no_broadcast) {
+						allow_array_programming = false;
+					}
+
+					if (type != t_invalid && !check_is_assignable_to(ctx, &op, type, allow_array_programming)) {
 						bool ok = true;
 						if (p->flags&FieldFlag_any_int) {
 							if ((!is_type_integer(op.type) && !is_type_enum(op.type)) || (!is_type_integer(type) && !is_type_enum(type))) {
@@ -2002,6 +2012,10 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
 			if (p->flags&FieldFlag_no_alias) {
 				param->flags |= EntityFlag_NoAlias;
 			}
+			if (p->flags&FieldFlag_no_broadcast) {
+				param->flags |= EntityFlag_NoBroadcast;
+			}
+
 			if (p->flags&FieldFlag_any_int) {
 				if (!is_type_integer(param->type) && !is_type_enum(param->type)) {
 					gbString str = type_to_string(param->type);

+ 1 - 0
src/entity.cpp

@@ -61,6 +61,7 @@ enum EntityFlag : u64 {
 
 	EntityFlag_CVarArg       = 1ull<<22,
 
+	EntityFlag_NoBroadcast   = 1ull<<23,
 	EntityFlag_AnyInt        = 1ull<<24,
 
 	EntityFlag_Disabled      = 1ull<<25,

+ 9 - 8
src/parser.cpp

@@ -3898,14 +3898,15 @@ struct ParseFieldPrefixMapping {
 	FieldFlag       flag;
 };
 
-gb_global ParseFieldPrefixMapping parse_field_prefix_mappings[] = {
-	{str_lit("using"),      Token_using,     FieldFlag_using},
-	{str_lit("no_alias"),   Token_Hash,      FieldFlag_no_alias},
-	{str_lit("c_vararg"),   Token_Hash,      FieldFlag_c_vararg},
-	{str_lit("const"),      Token_Hash,      FieldFlag_const},
-	{str_lit("any_int"),    Token_Hash,      FieldFlag_any_int},
-	{str_lit("subtype"),    Token_Hash,      FieldFlag_subtype},
-	{str_lit("by_ptr"),     Token_Hash,      FieldFlag_by_ptr},
+gb_global ParseFieldPrefixMapping const parse_field_prefix_mappings[] = {
+	{str_lit("using"),        Token_using,     FieldFlag_using},
+	{str_lit("no_alias"),     Token_Hash,      FieldFlag_no_alias},
+	{str_lit("c_vararg"),     Token_Hash,      FieldFlag_c_vararg},
+	{str_lit("const"),        Token_Hash,      FieldFlag_const},
+	{str_lit("any_int"),      Token_Hash,      FieldFlag_any_int},
+	{str_lit("subtype"),      Token_Hash,      FieldFlag_subtype},
+	{str_lit("by_ptr"),       Token_Hash,      FieldFlag_by_ptr},
+	{str_lit("no_broadcast"), Token_Hash,      FieldFlag_no_broadcast},
 };
 
 

+ 2 - 1
src/parser.hpp

@@ -326,6 +326,7 @@ enum FieldFlag : u32 {
 	FieldFlag_any_int   = 1<<6,
 	FieldFlag_subtype   = 1<<7,
 	FieldFlag_by_ptr    = 1<<8,
+	FieldFlag_no_broadcast = 1<<9, // disallow array programming
 
 	// Internal use by the parser only
 	FieldFlag_Tags      = 1<<10,
@@ -336,7 +337,7 @@ enum FieldFlag : u32 {
 	FieldFlag_Invalid   = 1u<<31,
 
 	// Parameter List Restrictions
-	FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_const|FieldFlag_any_int|FieldFlag_by_ptr,
+	FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_const|FieldFlag_any_int|FieldFlag_by_ptr|FieldFlag_no_broadcast,
 	FieldFlag_Struct    = FieldFlag_using|FieldFlag_subtype|FieldFlag_Tags,
 };
 

+ 2 - 2
vendor/raylib/raymath.odin

@@ -159,7 +159,7 @@ Vector2Transform :: proc "c" (v: Vector2, m: Matrix) -> Vector2 {
 // Calculate linear interpolation between two vectors
 @(require_results, deprecated="Prefer = linalg.lerp(v1, v2, amount)")
 Vector2Lerp :: proc "c" (v1, v2: Vector2, amount: f32) -> Vector2 {
-	return linalg.lerp(v1, v2, amount)
+	return linalg.lerp(v1, v2, Vector2(amount))
 }
 // Calculate reflected vector to normal
 @(require_results, deprecated="Prefer = linalg.reflect(v, normal)")
@@ -405,7 +405,7 @@ Vector3Transform :: proc "c" (v: Vector3, m: Matrix) -> Vector3 {
 // Calculate linear interpolation between two vectors
 @(require_results, deprecated="Prefer = linalg.lerp(v1, v2, amount)")
 Vector3Lerp :: proc "c" (v1, v2: Vector3, amount: f32) -> Vector3 {
-	return linalg.lerp(v1, v2, amount)
+	return linalg.lerp(v1, v2, Vector3(amount))
 }
 // Calculate reflected vector to normal
 @(require_results, deprecated="Prefer = linalg.reflect(v, normal)")