Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove incorrect coercion. Define type coercions. #342

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions src/type-coercions.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Type coercions

Coercions are defined in [RFC 401]. [RFC 1558] then expanded on that.
A coercion is implicit and has no syntax.
**Type coercions** are implicit changes of the type of a value. They happen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: An implicit coercion is essentially an implicit operation on a value. The value doesn't so much change type as there's an invisible "function call" on the value that produces a different value (this gets muddied a bit by subtyping and ownership). The language Idris allows one to define implicit functions and one can think of the implicit coercions in Rust as a set of those.

automatically at specific locations and are highly restricted in what types
actually coerce.

[RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
[RFC 1558]: https://github.com/rust-lang/rfcs/blob/master/text/1558-closure-to-fn-coercion.md
Coercions are originally defined in [RFC 401] and expanded upon in [RFC 1558].

## Coercion sites

Expand All @@ -21,7 +21,7 @@ sites are:
let _: i8 = 42;
```

* `static` and `const` statements (similar to `let` statements).
* `static` and `const` items (similar to `let` statements).

* Arguments for function calls

Expand All @@ -41,7 +41,7 @@ sites are:
For method calls, the receiver (`self` parameter) can only take advantage
of [unsized coercions](#unsized-coercions).

* Instantiations of struct or variant fields
* Instantiations of struct, union, or enum variant fields

For example, `42` is coerced to have type `i8` in the following:

Expand All @@ -53,7 +53,7 @@ sites are:
}
```

* Function results, either the final line of a block if it is not
* Function results – either the final line of a block if it is not
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nitpick: shouldn't this be an em dash without surrounding spaces?

semicolon-terminated or any expression in a `return` statement

For example, `42` is coerced to have type `i8` in the following:
Expand Down Expand Up @@ -91,7 +91,7 @@ the block has a known type.

Coercion is allowed between the following types:

* `T` to `U` if `T` is a subtype of `U` (*reflexive case*)
* `T` to `U` if `T` is a [subtype] of `U` (*reflexive case*)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the "reflexive case" annotation mean anything here? T to U when they are distinct is not reflexivity, although this does imply reflexivity because T is a subtype of T


* `T_1` to `T_3` where `T_1` coerces to `T_2` and `T_2` coerces to `T_3`
(*transitive case*)
Expand Down Expand Up @@ -140,7 +140,7 @@ Coercion is allowed between the following types:
- `*mut T`
- `Box<T>`

and where `T` can obtained from `U` by [unsized coercion](#unsized-coercions).
and where `T` can obtained from `U` by an [unsized coercion](#unsized-coercions).

<!--In the future, coerce_inner will be recursively extended to tuples and
structs. In addition, coercions from sub-traits to super-traits will be
Expand All @@ -164,8 +164,7 @@ the compiler will provide an implementation of `Unsize<U>` for `T`:

* `[T; n]` to `[T]`.

* `T` to `U`, when `U` is a trait object type and either `T` implements `U` or
`T` is a trait object for a subtrait of `U`.
* `T` to `dyn U`, when `T` implements `U + Sized`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think + Sized is accurate here; without it, coercions of references won't always work because going from &T to &U would require that T be sized. Unless that's actually how it works?


* `Foo<..., T, ...>` to `Foo<..., U, ...>`, when:
* `Foo` is a struct.
Expand All @@ -182,5 +181,8 @@ unsized coercion to `Foo<U>`.
> has been stabilized, the traits themselves are not yet stable and therefore
> can't be used directly in stable Rust.

[Unsize]: ../std/marker/trait.Unsize.html
[CoerceUnsized]: ../std/ops/trait.CoerceUnsized.html
[RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
[RFC 1558]: https://github.com/rust-lang/rfcs/blob/master/text/1558-closure-to-fn-coercion.md
[subtype]: subtyping.html
[`Unsize`]: ../std/marker/trait.Unsize.html
[`CoerceUnsized`]: ../std/ops/trait.CoerceUnsized.html