# Why does destructuring assignment require ImplicitlyCopyable instead of Copyable?

**URL:** <https://forum.modular.com/t/why-does-destructuring-assignment-require-implicitlycopyable-instead-of-copyable/3635>\
**Category:** Mojo\
**Created:** [November 5, 2026, 8:34pm UTC](https://forum.modular.com/t/why-does-destructuring-assignment-require-implicitlycopyable-instead-of-copyable/3635 "2026-11-05T20:34:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://forum.modular.com/u/muz)\
**Post date:** [November 5, 2026, 8:34pm UTC](https://forum.modular.com/t/why-does-destructuring-assignment-require-implicitlycopyable-instead-of-copyable/3635/1 "2026-11-05T20:34:01Z")

</div>

Hello!

I’m new to Mojo and am working with a custom `Point` struct in Mojo and found that destructuring assignment only works when the struct conforms to `ImplicitlyCopyable`, not just `Copyable`.

Here’s my struct:

```mojo
@fieldwise_init
struct Point[dtype: DType](Copyable, Writable) where dtype.is_numeric():
    comptime _coord_type = Scalar[Self.dtype]
    var x: Self._coord_type
    var y: Self._coord_type

```

With just `Copyable`, this doesn’t work:

```mojo
    comptime point_type = Point[dtype=DType.float64]
    var p: point_type
    var p1: point_type
    var p2: point_type

    p, p1, p2 = point_type(10, 0), point_type(0, 100), point_type(0, 1)

```

And this works:

```mojo
    p = point_type(10, 0)
    p1 = point_type(0, 100)
    p2 = point_type(0, 1)

```

But when I change it to `ImplicitlyCopyable`, destructuring assignment works as expected.

**My question:**  
What’s the fundamental difference between `Copyable` and `ImplicitlyCopyable` that makes destructuring assignment require the latter?

I understand that `Copyable` allows explicit copying, but why does destructuring assignment specifically need implicit copying behavior? Is there a technical reason related to how the compiler handles the unpacking operation?

I’d like to understand the rationale behind this requirement to better know when to use each trait.

Thanks!

* * *

EDIT: I’m using Mojo version 1.2.0.

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://forum.modular.com/u/muz)\
**Post date:** [November 6, 2026, 4:00am UTC](https://forum.modular.com/t/why-does-destructuring-assignment-require-implicitlycopyable-instead-of-copyable/3635/2 "2026-11-06T04:00:56Z")

</div>

Following up on my own question - I got this answered elsewhere (with AI assistance). The answer turned out to be straightforward once you see the mechanism, but it wasn’t obvious to me from the docs, so I’m posting it here rather than letting it stay buried in a private chat - in case it helps the next person who searches for this.

Destructuring assignment like `a, b = ..` desugars to reference - returning subscripts on the `Tuple`: each element is accessed through a borrow, and materializing an owned value from a borrow requires the compiler to insert a copy _implicitly_.

---

<div class="post-metadata">

**Author:** ![nate](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/nate/32/740_2.png) [@nate](https://forum.modular.com/u/nate)\
**Post date:** [November 7, 2026, 3:36am UTC](https://forum.modular.com/t/why-does-destructuring-assignment-require-implicitlycopyable-instead-of-copyable/3635/3 "2026-11-07T03:36:12Z")

</div>

This is actually a known compiler issue/limitation.  
When destructuring a tuple, the Mojo compiler should not require `ImplicitlyCopyable` and should ideally move the values out of the tuple.

Funnily enough you can achieve this via the `match/case` syntax which _does_ correctly move out of the tuple.

```mojo
def foo() -> Tuple[List[Int], List[Int]]:
    return ([], [])

def main():
    # (var a, var b) = foo() # should work
    # var a, b = foo() # should also work

    # This does work today
    var a: List[Int]
    var b: List[Int]
    match foo():
        case (var c, var d):
            a = c^
            b = d^
    print(a, b)

```

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://forum.modular.com/u/muz)\
**Post date:** [November 7, 2026, 4:11am UTC](https://forum.modular.com/t/why-does-destructuring-assignment-require-implicitlycopyable-instead-of-copyable/3635/4 "2026-11-07T04:11:29Z")

</div>

Thanks nate - that matches my intuition: for a temporary tuple the elements’ ownership should just transfer (with the move elided for trivial types). Good to know `match` already does this correctly.
