Repository: goplus/xgo

Issue:
auto reference for typed CompositeLit
In most cases, when a struct `T` is passed as an argument to a function `f`, it is typically passed as a pointer (`*T`), i.e., `f &T{...}`. We hope that when passing a typed CompositeLit (such as `T{...}`) to function `f`, it can automatically reference the CompositeLit. That is, `f T{...}` is equivalent to `f &T{...}`.


Discussion:
@xushiwei: /code@xgopilot: ### Implementation Complete ✓

Successfully implemented auto-reference for typed CompositeLit as requested in #2484.

### Changes Made

**Modified Files:**
- `cl/expr.go`: Enhanced `compileCompositeLitEx()` to automatically reference typed composite literals when passed to functions expecting pointer parameters

**New Files:**
- `cl/_testgop/autoref-2484/in.xgo`: Test input with examples for struct, slice, map, and array
- `cl/_testgop/autoref-2484/out.go`: Expected output showing auto-referencing behavior

### How It Works

When you pass a typed composite literal to a function expecting a pointer, XGo now automatically adds the `&` operator:

```go
// Before: Required explicit &
processPerson(&Person{Name: "Alice", Age: 30})

// Now: Both syntaxes work!
processPerson(Person{Name: "Alice", Age: 30})   // auto-referenced
processPerson(&Person{Name: "Alice", Age: 30})  // still works
```

This works for all composite literal types:
- Structs: `Person{...}` → `&Person{...}`
- Slices: `[]int{1,2,3}` → `&[]int{1,2,3}`
- Maps: `map[string]int{"a":1}` → `&map[string]int{"a":1}`
- Arrays: `[3]int{1,2,3}` → `&[3]int{1,2,3}`

### Testing

- ✓ All existing tests pass
- ✓ New comprehensive test cases added and passing
- ✓ Code formatted with `go fmt`

### Pull Request

Created PR #2485: https://github.com/goplus/xgo/pull/2485

The implementation follows the XGo project guidelines (Phase 2: Semantic Implementation) and maintains full backward compatibility with existing code.

Solution patch:
diff --git a/cl/_testgop/autoref-2484/in.xgo b/cl/_testgop/autoref-2484/in.xgo
new file mode 100644
index 00000000..bc4db722
--- /dev/null
+++ b/cl/_testgop/autoref-2484/in.xgo
@@ -0,0 +1,39 @@
+type Person struct {
+	Name string
+	Age  int
+}
+
+type Point struct {
+	X, Y int
+}
+
+func processPerson(p *Person) {
+	println p.Name, p.Age
+}
+
+func processPoint(p *Point) {
+	println p.X, p.Y
+}
+
+func processSlice(s *[]int) {
+	println len(*s)
+}
+
+func processMap(m *map[string]int) {
+	println len(*m)
+}
+
+func processArray(a *[3]int) {
+	println len(*a)
+}
+
+// Test auto-reference for typed composite literals
+processPerson Person{Name: "Alice", Age: 30}
+processPoint Point{X: 10, Y: 20}
+processSlice []int{1, 2, 3}
+processMap map[string]int{"a": 1, "b": 2}
+processArray [3]int{1, 2, 3}
+
+// Test that normal pointer usage still works
+processPerson &Person{Name: "Bob", Age: 25}
+processPoint &Point{X: 5, Y: 15}
diff --git a/cl/expr.go b/cl/expr.go
index 771d90a8..fb5d6802 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -1521,6 +1521,15 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
 	if v.Type != nil {
 		typ = toType(ctx, v.Type)
 		underlying = getUnderlying(ctx, typ)
+		// Auto-reference typed composite literal when expected type is pointer
+		if expected != nil {
+			if t, ok := expected.(*types.Pointer); ok {
+				telem := t.Elem()
+				if types.Identical(typ, telem) {
+					hasPtr = true
+				}
+			}
+		}
 	} else if expected != nil {
 		if t, ok := expected.(*types.Pointer); ok {
 			telem := t.Elem()



Test patch:
diff --git a/cl/_testgop/autoref-2484/out.go b/cl/_testgop/autoref-2484/out.go
new file mode 100644
index 00000000..c6ce5f01
--- /dev/null
+++ b/cl/_testgop/autoref-2484/out.go
@@ -0,0 +1,38 @@
+package main
+
+import "fmt"
+
+type Person struct {
+	Name string
+	Age  int
+}
+type Point struct {
+	X int
+	Y int
+}
+
+func processPerson(p *Person) {
+	fmt.Println(p.Name, p.Age)
+}
+func processPoint(p *Point) {
+	fmt.Println(p.X, p.Y)
+}
+func processSlice(s *[]int) {
+	fmt.Println(len(*s))
+}
+func processMap(m *map[string]int) {
+	fmt.Println(len(*m))
+}
+func processArray(a *[3]int) {
+	fmt.Println(len(*a))
+}
+// Test auto-reference for typed composite literals
+func main() {
+	processPerson(&Person{Name: "Alice", Age: 30})
+	processPoint(&Point{X: 10, Y: 20})
+	processSlice(&[]int{1, 2, 3})
+	processMap(&map[string]int{"a": 1, "b": 2})
+	processArray(&[3]int{1, 2, 3})
+	processPerson(&Person{Name: "Bob", Age: 25})
+	processPoint(&Point{X: 5, Y: 15})
+}