-
Notifications
You must be signed in to change notification settings - Fork 489
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
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 | ||
|
||
|
@@ -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 | ||
|
||
|
@@ -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: | ||
|
||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: | ||
|
@@ -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*) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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*) | ||
|
@@ -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 | ||
|
@@ -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` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think |
||
|
||
* `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: | ||
* `Foo` is a struct. | ||
|
@@ -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 |
There was a problem hiding this comment.
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.