Repository: godotengine/godot (language: cpp)

Issue:
Callable.callv() will make call with wrong arguments if a const Array is passed
### Tested versions

- Reproducible in 4.3.beta2.official [b75f0485b]

### System information

Windows 10 - Godot 4.3.beta2.official [b75f0485b]

### Issue description

Using Callable().callv() will result in a call using the wrong arguments, if the Array being passed is a const.
The bug does not occur if the Array being passed is a var.
The bug does not occur if we use Callable().bindv().call() instead.

### Steps to reproduce

The following code can demonstrate the bug. The debugger does not show any errors or warnings.
```extends Node2D

const arr_const = ['one','two','three','four']
var arr_var = ['one','two','three','four']

func _ready() -> void:
	# non-const works
	somefunc.callv(arr_var)
	# const fails
	somefunc.callv(arr_const)
	# temporary workaround
	somefunc.bindv(arr_const).call()
	
func somefunc(v1,v2,v3,v4):
	print('%s,%s,%s,%s'% [v1,v2,v3,v4])
```
will print:
```
one,two,three,four
four,four,four,four
one,two,three,four
```
The first and third calls work as expected, with the four arguments in the arrays.
Only the second call, which used a const Array and .callv(), made a call with all arguments replaced by the last argument.

In this example, I use a function directly, but this can be reproduced with any Callable().

This seems like a similar issue as #69237, with a similar workaround, but in this case the correct number of arguments was passed.


### Minimal reproduction project (MRP)

[callablecheck.zip](https://github.com/user-attachments/files/15974691/callablecheck.zip)



Discussion / hints:
Can confirm that this is still happening in `v4.3.stable.mono.official [77dcf97d8]`.

Thank you for the tip about `bindv(const_arr).call()`, I was very confused for a hot second after I realized I could make my actions array const only to have movement stop working 🤣

Fix patch:
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index d91612b420ca..2357e3f907ab 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -88,11 +88,11 @@ Array::Iterator Array::end() {
 }
 
 Array::ConstIterator Array::begin() const {
-	return ConstIterator(_p->array.ptr(), _p->read_only);
+	return ConstIterator(_p->array.ptr());
 }
 
 Array::ConstIterator Array::end() const {
-	return ConstIterator(_p->array.ptr() + _p->array.size(), _p->read_only);
+	return ConstIterator(_p->array.ptr() + _p->array.size());
 }
 
 Variant &Array::operator[](int p_idx) {
@@ -104,10 +104,6 @@ Variant &Array::operator[](int p_idx) {
 }
 
 const Variant &Array::operator[](int p_idx) const {
-	if (unlikely(_p->read_only)) {
-		*_p->read_only = _p->array[p_idx];
-		return *_p->read_only;
-	}
 	return _p->array[p_idx];
 }
 
diff --git a/core/variant/array.h b/core/variant/array.h
index 841b6ff8eaa4..a796a2581171 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -56,21 +56,19 @@ class Array {
 		_FORCE_INLINE_ bool operator==(const ConstIterator &p_other) const { return element_ptr == p_other.element_ptr; }
 		_FORCE_INLINE_ bool operator!=(const ConstIterator &p_other) const { return element_ptr != p_other.element_ptr; }
 
-		_FORCE_INLINE_ ConstIterator(const Variant *p_element_ptr, Variant *p_read_only = nullptr) :
-				element_ptr(p_element_ptr), read_only(p_read_only) {}
+		_FORCE_INLINE_ ConstIterator(const Variant *p_element_ptr) :
+				element_ptr(p_element_ptr) {}
 		_FORCE_INLINE_ ConstIterator() {}
 		_FORCE_INLINE_ ConstIterator(const ConstIterator &p_other) :
-				element_ptr(p_other.element_ptr), read_only(p_other.read_only) {}
+				element_ptr(p_other.element_ptr) {}
 
 		_FORCE_INLINE_ ConstIterator &operator=(const ConstIterator &p_other) {
 			element_ptr = p_other.element_ptr;
-			read_only = p_other.read_only;
 			return *this;
 		}
 
 	private:
 		const Variant *element_ptr = nullptr;
-		Variant *read_only = nullptr;
 	};
 
 	struct Iterator {
@@ -96,7 +94,7 @@ class Array {
 		}
 
 		operator ConstIterator() const {
-			return ConstIterator(element_ptr, read_only);
+			return ConstIterator(element_ptr);
 		}
 
 	private:
diff --git a/core/variant/variant.h b/core/variant/variant.h
index e38f7c9b0bae..f0bd7ec6824e 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -997,18 +997,10 @@ Array::Iterator &Array::Iterator::operator--() {
 }
 
 const Variant &Array::ConstIterator::operator*() const {
-	if (unlikely(read_only)) {
-		*read_only = *element_ptr;
-		return *read_only;
-	}
 	return *element_ptr;
 }
 
 const Variant *Array::ConstIterator::operator->() const {
-	if (unlikely(read_only)) {
-		*read_only = *element_ptr;
-		return read_only;
-	}
 	return element_ptr;
 }
 


Test patch: