# Idea: the \`into\` operator

**URL:** <https://internals.rust-lang.org/t/idea-the-into-operator/9955>\
**Category:** language design\
**Created:** [April 30, 2019, 11:26pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955 "2019-04-30T23:26:18Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [April 30, 2019, 11:26pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/1 "2019-04-30T23:26:18Z")

</div>

The `Into` trait is one of those most frequently used traits in Rust. In many cases it works well with type inference. However in cases it does not work, usually we have to write

```rust
let converted = <MyType>::from(v);

```

In cases that `Into` was not derived from `From`, it is more ugly:

```rust
let converted = <_ as Into<MyType>>::into(v);

```

The problem of above is that

1. It is verbose;
2. The way to call this and its sementic is like `from`, but the verb suggest otherwise, a code reader can be confused.

My proposal is to write

```rust
let converted = v into Mytype;

```

and let de-sugaring happen here.

The proposed way the new `into` keyword should work exactly like `as`, except that it is pure syntax sugar.

Another way is to introduce a mechanism that allow annotate the `into` call to specify the type.

```rust
let converted = v<as Into<MyType>>.into();

```

(Note, `(v as Into<MyType>).into()` technically requires `#![feature(unsized_local)]`, an I am not sure whether it have hidden costs)

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [April 30, 2019, 11:33pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/2 "2019-04-30T23:33:06Z")

</div>

Did you know you can write it with type ascription?

```rust
let converted: MyType = v.into();

```

---

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [April 30, 2019, 11:34pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/3 "2019-04-30T23:34:01Z")

</div>

Yes; but this is not possible in a complicated expression.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [April 30, 2019, 11:36pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/4 "2019-04-30T23:36:46Z")

</div>

Here’s a similar issue:

> <https://github.com/rust-lang/rfcs/issues/2425>

And you might also like this RFC:

> <https://github.com/rust-lang/rfcs/pull/2522>

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [April 30, 2019, 11:36pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/5 "2019-04-30T23:36:55Z")

</div>

If that is a problem, then you can do this

```rust
fn into<T, U: Into<T>>(u: U) -> T { u.into() }

```

which can be called like this `into::<i32, _>(foo)`

or if you want method syntax

```rust
trait IntoGeneral {
    fn into_general<T>(self) -> T where Self: Into<T> { self.into() }
}
impl<T> IntoGeneral for T {}

```

and can be called like this `foo.into_general::<u32>()`

name is not important

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [May 1, 2019, 1:18am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/6 "2019-05-01T01:18:43Z")

</div>

> [@earthengine](#):
>
> My proposal is to write
> 
> ```rust
> let converted = v into Mytype;
> 
> ```

Given type ascription in expressions, this would just be

```rust
let converted = v.into(): Mytype;

```

So I don't think I'd be interested in debating `into` sugar until decisions are made about ascription.

---

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [May 1, 2019, 1:21am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/7 "2019-05-01T01:21:01Z")

</div>

Fair enough.

---

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [May 1, 2019, 5:30am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/8 "2019-05-01T05:30:31Z")

</div>

I think, even type ascription works in this case, it would be better to have a way to distinguish methods from different trait implements. My `into` keyword does not work either in this case.

This is the piece missing in the current type ascription: `(v: impl Clone).clone()` is not the same as `(v: dyn Into<u8>).into()`. Ideally we should be able to do the former because this does not involve unsizing coercion.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [May 1, 2019, 6:40am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/9 "2019-05-01T06:40:55Z")

</div>

> [@earthengine](#):
>
> I think, even type ascription works in this case, it would be better to have a way to distinguish methods from different trait implements.

I agree: [Idea: Paths in method names](https://internals.rust-lang.org/t/idea-paths-in-method-names/6834)

---

<div class="post-metadata">

**Author:** ![H2CO3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/h2co3/32/2849_2.png) [@H2CO3](https://internals.rust-lang.org/u/H2CO3)\
**Post date:** [May 1, 2019, 6:49am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/10 "2019-05-01T06:49:31Z")

</div>

> [@earthengine](#):
>
> In cases that `Into` was not derived from `From` , it is more ugly:
> 
> ```rust
> let converted = <_ as Into<MyType>>::into(v);
> 
> ```

Since you can use trait methods directly, it's as simple as `Into::<MyType>::into()`.

Furthermore, it _shouldn't_ be the case that `Into` isn't defined in terms of `From`: it's meant to be syntactic sugar (the method call syntax equivalent) for `From`, so implementing `Into` but not `From` doesn't really make sense, and implementing `Into` and `From` inconsistently with one another would be even worse.

(In case it's not clear, I'm strongly against any sort of syntactic sugar that just expands to a simple method call on a trait. This could easily be a macro; let's not pack the language full of even more special-cased traits.)

---

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [May 1, 2019, 6:55am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/11 "2019-05-01T06:55:41Z")

</div>

> [@H2CO3](#):
>
> it _shouldn’t_ be the case that `Into` isn’t defined in terms of `From`

In the ideal world yes this is what we should do.

In reality however, the orphan rules can prevent us from doing this, making implementing `From` impossible yet having `Into` is possible. I learn this from a blog post but I forgot where it was.

> [@H2CO3](#):
>
> This could easily be a macro

It would be better a postfix macro though, which we didn't have right now.

---

<div class="post-metadata">

**Author:** ![Uther](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/uther/32/6225_2.png) [@Uther](https://internals.rust-lang.org/u/Uther)\
**Post date:** [May 1, 2019, 9:54am UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/12 "2019-05-01T09:54:22Z")

</div>

I like the idea, but it would require a new keyword, so a new edition. Personally I would use the opportunity to fix the `as` operator. The problem of the `as` operator is that it may do loosing conversion without warning.

Instead of a new operator, I would modify the `as` operator to use the conversion trait. If no trait is available, it would fall back to the original behavior for compatibility, but it would raise a warning, Maybe an error in future editions.

---

<div class="post-metadata">

**Author:** ![AGausmann](https://avatars.discourse-cdn.com/v4/letter/a/9de053/32.png) [@AGausmann](https://internals.rust-lang.org/u/AGausmann)\
**Post date:** [May 1, 2019, 9:12pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/13 "2019-05-01T21:12:52Z")

</div>

The `as` operator is well-defined in the [reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions), though I do think putting those specifics in the API docs would be helpful. It’s not meant for anything but the simple numeric (truncating / wrapping / padding) and pointer conversions which make sense in a systems programming context and are typically a no-op on most platforms (except for fp conversion).

There are several other issues with making `as` use conversion traits:

- Its name is nothing like `From` or `Into`, making it difficult to recognize those traits are involved.

- It gets complicated if you want to support interactions with `TryFrom` / `TryInto`: `8i64 as i32?` or `(8i64 as i32)?` (either way, ew), which leads me to:

- It isn’t backwards compatible with the current integer conversions using `as`. Integers implement `ib: TryFrom<ia>` if it can’t guarantee that `((xia as ib) as ia) == xia`.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [July 30, 2019, 9:12pm UTC](https://internals.rust-lang.org/t/idea-the-into-operator/9955/14 "2019-07-30T21:12:54Z")

</div>

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