# Compilation of record-wrapped array fails when assignment to real is added

**URL:** <https://chapel.discourse.group/t/compilation-of-record-wrapped-array-fails-when-assignment-to-real-is-added/46083>\
**Category:** Users\
**Created:** [November 13, 2025, 6:37pm UTC](https://chapel.discourse.group/t/compilation-of-record-wrapped-array-fails-when-assignment-to-real-is-added/46083 "2025-11-13T18:37:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![nelsonluisdias](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/nelsonluisdias/32/691_2.png) [@nelsonluisdias](https://chapel.discourse.group/u/nelsonluisdias)\
**Post date:** [November 13, 2025, 6:37pm UTC](https://chapel.discourse.group/t/compilation-of-record-wrapped-array-fails-when-assignment-to-real-is-added/46083/1 "2025-11-13T18:37:18Z")

</div>

The code below compiles and runs nicely (Chapel 2.5), and does what it is meant to.  
However, if I uncomment the three procedures meant to include assignment to real, compilation fails with the message

overeq.chpl:35: In function 'main':  
overeq.chpl:49: error: an init= initializing 'narray(1)' from 'narray(1)' is missing  
overeq.chpl:1: note: expected because assignment is defined here between these two types

Any hints of how to uncomment _and_ make the original code work will be welcome. Thanks.

```chapel
record narray {
   param ran = 1; // the rank
   var dom: domain(ran) = {1..1}; // the domain                              
   var arr: [dom] real = 0.0; // the array                                  
   proc size: int { // the size of a narray
      return dom.size;
   }
   inline proc ref this(in k: int...?n) ref { // access arr[k]               
      return arr[k];
   }
   iter ref these() ref { // iterate over the whole narray         
      for i in dom do {
         yield arr[i];
      }
   }
   iter ref these( // iterate over several ranges           
      in rak: range(int)...?r
      ) ref {  
      for k in zip(rak) do {
         yield arr[k];
      }
   }
   /*
   proc init=(const in a: real) {
      this.arr = a;
   }
   operator :(a: real, type t: narray) {
      var v: narray = a;
      return v;
   }
   operator =(ref lhs: narray, const in a: real) {
      lhs.arr = a;
   }
   */
}

proc main() {
   writeln(isGeneric(narray));
   writeln(isGeneric(narray(1)));
   var a: narray(2);
   var b: narray(1);
   var c: narray(1);
   var z: [1..5] narray(1);
   a = new narray(2,{1..10,1..5});
   b = new narray(1,{1..10});
   c = new narray(1,{1..3});
   writeln(a);
   writeln(b);
   writeln(c);
   for i in 1..5 do {
      z[i] = new narray(1,{1..i});
      z[i].arr = 1..i ;
   }
   for i in 1..5 do {
      writeln(z[i]);
   }
}

```

---

<div class="post-metadata">

**Author:** ![bradcray](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/bradcray/32/72_2.png) [@bradcray](https://chapel.discourse.group/u/bradcray)\
**Post date:** [November 13, 2025, 7:17pm UTC](https://chapel.discourse.group/t/compilation-of-record-wrapped-array-fails-when-assignment-to-real-is-added/46083/2 "2025-11-13T19:17:59Z")

</div>

Hi Nelson —

What's happening here is that, currently, the Chapel compiler will only create default `init=` and `operator =` implementations for records if the user doesn't supply any overloads of those methods themselves. Once you have, it assumes "This type author wants to support these specific initializations/assignments (in your case, from a `real`), so I assume they want more explicit control over what the record can and cannot do" and as a result, it no longer creates the methods by default.

At present, the way to make your code work again is to add your own overloads for these record-to-record cases. For example, I did this by adding these overloads to your type:

```chapel
   proc init=(const in rhs: narray(?)) {
     this.ran = rhs.ran;
     this.dom = rhs.dom;
     this.arr = rhs.arr;
   }
   operator =(ref lhs: narray, rhs: narray(lhs.ran)) {
     lhs.dom = rhs.dom;
     lhs.arr = rhs.arr;
   }

```

as seen here [on ATO](https://ato.pxeger.com/run?1=jVXLrpswEN11ka-YJUgpN7SqVIGiu-xHXGXhEKdYcA2yfRMlEV_Szd20H9Wv6YwfPBJoiwQCz_Gcc2Zs8-NXUbKW1-_vP9_M8ePX3x-04kWjDiCZUuwCtxUAtEyxV1BMwhbSHB6upycwJSdARfATU3BoXjN6MCEjHI9x5i1NkrTLe7iLPmYbXyEdisngBWfsQHFWY7ZNsskn7E7vPy_rRzUFaHHlGQhp4LbghxDQHIH5YqxcVHHzpiTJTwiR03BHDyFrIbnLrvgRcwgdocPK0iRJ8ox1oMAtsLCi4FqT9JdqNyN0YHOQEZfhypNwzaNx3okPwjGDNk6IJ1Pnsql56O4d17FRIFArecPbNd9dF8Hrg1UhnIogZE7NfOXv1WiOT-wlLo_vXD86Rx2KYe1sHOtoYiqh8tHe8Uh7RXOuosUVV8WLBqoZA7ZnQgqzjYpGamPJS535QkXPcRySUVcTtxcQQW_5KECVcwF8Gwcwjw_g29DHpqWKoPZtRH7qgXM9EVA7qkFGXc6T1eUi15xJltkN1acdi2UzMrPIz1iDubQcTFA4ZKD9egrDfZphKZ_-z_2yxMFiUNitVtacPW488KxwtdUyEvobl1yJIvJC4_xv4SiNPcKeO30DPg2D-34wHQaLucErHlp46n3Z3cUYapf83Ode27NxsyZs5yD7KST1EB8t5qKfu6k1Nv3cTz8L99nveeIe75kr7vQ5FuFZPMR3ggIwNHYxa2CnqXHonvv3-F9Q-BX9AQ).

An intention we have for the future, which we haven't worked on designing yet, is to provide a way to say "Compiler, please provide the default overloads for these types in addition to the ones I've provided here." Basically, a way to opt back into having the defaults provided without writing them manually. Unfortunately, that does not exist yet today because it would save you a bit of typing in this case.

I also think we could arguably improve the error message in cases like this. For example, if we can't find a `t`-to-`t` assignment or `init=` and we see that the user defined overloads, we could provide an explanatory message like the one at the outset of this message explaining that the compiler didn't provide them due to the user overloads. If you would like to request that, please feel free to open an issue on our GitHub requesting it.

One other thing I want to mention, which could bite you down the line, is that by using the type signature `narray` rather than `narray(?)` in your argument lists, you are constraining them to the default generic instantiation of `narray` (which is to say `narray(ran=1)`). As a result, your overloads won't work for an `narray(ran=2)` case like `a = 2.5;`. You should be able to make them more general by using `narray(?)` as the type constraint, which says "take any instantiation of `narray()`" (in this case, an `narray` with any value of `param ran`). In the methods I wrote above, you can see that I did this for the `init=` but for the `=` operator, constrained the RHS to have the same `ran` value as the LHS (since an assignment cannot change the type—in this case the `ran` value—of the LHS).

Hope this is helpful, and please let us know if you have additional questions,  
-Brad

---

<div class="post-metadata">

**Author:** ![nelsonluisdias](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/nelsonluisdias/32/691_2.png) [@nelsonluisdias](https://chapel.discourse.group/u/nelsonluisdias)\
**Post date:** [November 13, 2025, 9:25pm UTC](https://chapel.discourse.group/t/compilation-of-record-wrapped-array-fails-when-assignment-to-real-is-added/46083/3 "2025-11-13T21:25:29Z")

</div>

Great Brad: thanks! Now everything works. I had suspected the need for an explicit  
init=(...), bumped my head around a few times, but could not make it work.

The extra code is not a problem (in my opinion), but an example of this situation in the documentation might be helpful (just thinking).

Cheers,

Nelson
