# Argument exclusivity with arguments from two list elements

**URL:** https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368
**Category:** Mojo
**Tags:** discussion, 24\_6
**Created:** [December 21, 2024, 10:43pm UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368 "2024-12-21T22:43:01Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![samufi](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@samufi](https://forum.modular.com/u/samufi)
#### Post date: [December 21, 2024, 10:43pm UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/1 "2024-12-21T22:43:01Z")

</div>

Consider the following case:

```auto
@value
struct SomeStruct:
    var a: Int

fn copy_to(from_struct: SomeStruct, inout to_struct: SomeStruct):
    to_struct.a = from_struct.a

def main():
    l = List[SomeStruct](SomeStruct(1), SomeStruct(2))
    copy_to(l[0], l[1])

```

This does not work, since both `l[0]` and `l[1]` have the same origin, which is `l`. However, the underlying memory is not the same. Is there a solution to deal with such issues other than inlining the content of `copy_to`?

---

<div class="post-metadata">

### Author: ![Nick](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/nick/32/115_2.png) [@Nick](https://forum.modular.com/u/Nick)
#### Post date: [December 22, 2024, 2:35am UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/2 "2024-12-22T02:35:55Z")

</div>

Hi @samufi, this is a great question.

I don’t believe there’s a way to make this program compile in today’s Mojo. Per Mojo’s borrowing rules, `from_struct` and `to_struct` cannot alias if one of them is mutable.

@clattner, you might be interested in this user’s predicament.

There are various ways that we could extend Mojo to allow your program to be safely expressed. For example, I’m hoping that we will allow arguments parameterized by the same origin to mutably alias:

```auto
fn copy_to[o: MutableOrigin](ref[o] from_struct: SomeStruct, ref[o] to_struct: SomeStruct):
    to_struct.a = from_struct.a

```

In the meantime, you can use UnsafePointers as a workaround. UnsafePointers are allowed to mutably alias:

```auto
from memory import UnsafePointer

@value
struct SomeStruct:
    var a: Int

fn copy_to(from_struct: UnsafePointer[SomeStruct], to_struct: UnsafePointer[SomeStruct]):
    to_struct[].a = from_struct[].a

def main():
    l = List[SomeStruct](SomeStruct(1), SomeStruct(2))
    copy_to(UnsafePointer.address_of(l[0]), UnsafePointer.address_of(l[1]))
    print(l[0].a, l[1].a)

```

---

<div class="post-metadata">

### Author: ![clattner](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/clattner/32/201_2.png) [@clattner](https://forum.modular.com/u/clattner)
#### Post date: [December 30, 2024, 9:52pm UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/3 "2024-12-30T21:52:19Z")

</div>

The simplest workaround is to introduce a copy of the element, so you’re passing a reference to the element instead of the original list, e.g. something like:

```auto
l = List[SomeStruct](SomeStruct(1), SomeStruct(2))
var tmp = SomeStruct(l[0])
copy_to(tmp, l[1])

```

or even:

```auto
l = List[SomeStruct](SomeStruct(1), SomeStruct(2))
copy_to(SomeStruct(l[0]), l[1])

```

It is important that mojo reject the original code. In this case, theoretically it could symbolically analyze that 0 != 1, but it would have to go look at the body of the List.getitem implementation to decide how and if that matters, and we don’t want the type checker to look at full interprocedural information like that.

* * *

I wouldn’t recommend or encourage the use of the `UnsafePointer` thing above btw. Nick is correct that they can mutably alias… but it is undefined behavior when they do. The only reason the code above work is that the list elements don’t alias in this one example, but it would be a dangerously unsafe API to expose to people.

This is why we want `UnsafePointer` to scream at you by being so visible and long - it is wildly unsafe unless you use it the right way. It is an important tool for building low level data structures, but not something that should generally be exposed for user-level APIs like the above.

---

<div class="post-metadata">

### Author: ![Nick](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/nick/32/115_2.png) [@Nick](https://forum.modular.com/u/Nick)
#### Post date: [December 30, 2024, 11:13pm UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/4 "2024-12-30T23:13:28Z")

</div>

> [@clattner](#):
>
> I wouldn’t recommend or encourage the use of the `UnsafePointer` thing above btw. Nick is correct that they can mutably alias… but it is undefined behavior when they do.

I am surprised by this. I thought Mojo’s `UnsafePointer`s are compiled the same as C pointers, i.e. they are treated as potentially mutably aliasing one another. (i.e. the compiler doesn’t perform optimizations based on the assumption that unsafe pointers don’t alias.)

Isn’t this why the [as\_noalias\_ptr](https://docs.modular.com/mojo/stdlib/memory/unsafe_pointer/UnsafePointer/#as_noalias_ptr) method exists: to allow programmers to _opt into_ `noalias` optimizations?

More generally though, I agree that `UnsafePointer`s are not something that 99% of Mojo users should be using, and I probably should have made this much more clear in my original post.

Your suggestion to make a _copy_ of the first argument is much more sensible. (In cases where this isn’t a performance bottleneck.)

---

<div class="post-metadata">

### Author: ![samufi](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@samufi](https://forum.modular.com/u/samufi)
#### Post date: [December 31, 2024, 1:49pm UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/5 "2024-12-31T13:49:04Z")

</div>

Thank you for the insightful responses. I guess the we would really need to see what comes out of Nick’s proposal. For the time being I inlined the entire function elsewhere to prevent the need for a copy or unsafe pointers. Maybe this could be an additional option, though, to allow this kind of stuff on `@always_inline` functions. (I would understand if this is not done, though, as this might give programmers wrong incentives and break consistency somehow…)

---

<div class="post-metadata">

### Author: ![clattner](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/clattner/32/201_2.png) [@clattner](https://forum.modular.com/u/clattner)
#### Post date: [January 5, 2025, 7:50pm UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/6 "2025-01-05T19:50:08Z")

</div>

> [@Nick](#):
>
> I am surprised by this. I thought Mojo’s `UnsafePointer`s are compiled the same as C pointers, i.e. they are treated as potentially mutably aliasing one another. (i.e. the compiler doesn’t perform optimizations based on the assumption that unsafe pointers don’t alias.)

There are definitely some analogies, C pointers are assumed they may alias in most cases (independent of mutability) but in C, `int*` and `float*` are assumed to not alias in C (with weird exceptions). C is a mess, and we shouldn’t define Mojo’s behavior in terms of it.

> Isn’t this why the [as\_noalias\_ptr](https://docs.modular.com/mojo/stdlib/memory/unsafe_pointer/UnsafePointer/#as_noalias_ptr) method exists: to allow programmers to _opt into_ `noalias` optimizations?

Yes, but beware that this is a low level hack and is likely to be redesigned or removed, don’t index too much on it 🙂

> More generally though, I agree that UnsafePointers are not something that 99% of Mojo users should be using, and I probably should have made this much more clear in my original post.

+1,

-Chris

---

<div class="post-metadata">

### Author: ![rcmpge](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/rcmpge/32/849_2.png) [@rcmpge](https://forum.modular.com/u/rcmpge)
#### Post date: [January 9, 2025, 4:33am UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/7 "2025-01-09T04:33:26Z")

</div>

I would like to be 1 of the 1% of Mojo users that uses this to see if something breaks 👍

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex001/uploads/modular/original/1X/2751e0fbdc595a99718b216730957e9db4448cfd.jpeg) [@system](https://forum.modular.com/u/system)
#### Post date: [July 8, 2025, 4:33am UTC](https://forum.modular.com/t/argument-exclusivity-with-arguments-from-two-list-elements/368/8 "2025-07-08T04:33:34Z")

</div>

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
