Merge from rustc
This commit is contained in:
commit
3b2302ec0d
2331 changed files with 28713 additions and 17321 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 45f05367360f033f89235eacbbb54e8d73ce6b70
|
||||
Subproject commit d33916341d480caede1d0ae57cbeae23aab23e88
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 1e27e5e6d5133ae4612f5cc195c15fc8d51b1c9c
|
||||
Subproject commit 467f45637b73ec6aa70fb36bc3054bb50b8967ea
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit b4448fa406a6dccde62d1e2f34f70fc51814cdcc
|
||||
Subproject commit 0c10c30cc54736c5c194ce98c50e2de84eeb6e79
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit e95ebdfee02514d93f79ec92ae310a804e87f01f
|
||||
Subproject commit 3340922df189bddcbaad17dc3927d51a76bcd5ed
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 6f69823c28ae8d929d6c815181c73d3e99ef16d3
|
||||
Subproject commit 0d7964d5b22cf920237ef1282d869564b4883b88
|
||||
|
|
@ -31,7 +31,6 @@ Term | Meaning
|
|||
<span id="generics">generics</span> | The list of generic parameters defined on an item. There are three kinds of generic parameters: Type, lifetime and const parameters.
|
||||
<span id="hir">HIR</span> | The _high-level [IR](#ir)_, created by lowering and desugaring the AST. ([see more](../hir.md))
|
||||
<span id="hir-id">`HirId`</span> | Identifies a particular node in the HIR by combining a def-id with an "intra-definition offset". See [the HIR chapter for more](../hir.md#identifiers-in-the-hir).
|
||||
<span id="hir-map">HIR map</span> | The HIR map, accessible via `tcx.hir()`, allows you to quickly navigate the HIR and convert between various forms of identifiers.
|
||||
<span id="ice">ICE</span> | Short for _internal compiler error_, this is when the compiler crashes.
|
||||
<span id="ich">ICH</span> | Short for _incremental compilation hash_, these are used as fingerprints for things such as HIR and crate metadata, to check if changes have been made. This is useful in incremental compilation to see if part of a crate has changed and should be recompiled.
|
||||
<span id="infcx">`infcx`</span> | The type inference context (`InferCtxt`). (see `rustc_middle::infer`)
|
||||
|
|
|
|||
|
|
@ -109,11 +109,16 @@ like Python or LLVM.
|
|||
|
||||
Here is an example of how can `opt-dist` be used locally (outside of CI):
|
||||
|
||||
1. Build the tool with the following command:
|
||||
1. Enable metrics in your `bootstrap.toml` file, because `opt-dist` expects it to be enabled:
|
||||
```toml
|
||||
[build]
|
||||
metrics = true
|
||||
```
|
||||
2. Build the tool with the following command:
|
||||
```bash
|
||||
./x build tools/opt-dist
|
||||
```
|
||||
2. Run the tool with the `local` mode and provide necessary parameters:
|
||||
3. Run the tool with the `local` mode and provide necessary parameters:
|
||||
```bash
|
||||
./build/host/stage0-tools-bin/opt-dist local \
|
||||
--target-triple <target> \ # select target, e.g. "x86_64-unknown-linux-gnu"
|
||||
|
|
|
|||
|
|
@ -301,7 +301,8 @@ Right below you can find elaborate explainers on a selected few.
|
|||
|
||||
Some compiler options for debugging specific features yield graphviz graphs -
|
||||
e.g. the `#[rustc_mir(borrowck_graphviz_postflow="suffix.dot")]` attribute
|
||||
dumps various borrow-checker dataflow graphs.
|
||||
on a function dumps various borrow-checker dataflow graphs in conjunction with
|
||||
`-Zdump-mir-dataflow`.
|
||||
|
||||
These all produce `.dot` files. To view these files, install graphviz (e.g.
|
||||
`apt-get install graphviz`) and then run the following commands:
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ The HIR uses a bunch of different identifiers that coexist and serve different p
|
|||
a wrapper around a [`HirId`]. For more info about HIR bodies, please refer to the
|
||||
[HIR chapter][hir-bodies].
|
||||
|
||||
These identifiers can be converted into one another through the [HIR map][map].
|
||||
These identifiers can be converted into one another through the `TyCtxt`.
|
||||
|
||||
[`DefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
|
||||
[`LocalDefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.LocalDefId.html
|
||||
|
|
@ -110,30 +110,24 @@ These identifiers can be converted into one another through the [HIR map][map].
|
|||
[`CrateNum`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.CrateNum.html
|
||||
[`DefIndex`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefIndex.html
|
||||
[`Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html
|
||||
[hir-map]: ./hir.md#the-hir-map
|
||||
[hir-bodies]: ./hir.md#hir-bodies
|
||||
[map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html
|
||||
|
||||
## The HIR Map
|
||||
## HIR Operations
|
||||
|
||||
Most of the time when you are working with the HIR, you will do so via
|
||||
the **HIR Map**, accessible in the tcx via [`tcx.hir()`] (and defined in
|
||||
the [`hir::map`] module). The [HIR map] contains a [number of methods] to
|
||||
convert between IDs of various kinds and to lookup data associated
|
||||
with a HIR node.
|
||||
`TyCtxt`. It contains a number of methods, defined in the `hir::map` module and
|
||||
mostly prefixed with `hir_`, to convert between IDs of various kinds and to
|
||||
lookup data associated with a HIR node.
|
||||
|
||||
[`tcx.hir()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir
|
||||
[`hir::map`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/index.html
|
||||
[HIR map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html
|
||||
[number of methods]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#methods
|
||||
[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html
|
||||
|
||||
For example, if you have a [`LocalDefId`], and you would like to convert it
|
||||
to a [`HirId`], you can use [`tcx.hir().local_def_id_to_hir_id(def_id)`][local_def_id_to_hir_id].
|
||||
to a [`HirId`], you can use [`tcx.local_def_id_to_hir_id(def_id)`][local_def_id_to_hir_id].
|
||||
You need a `LocalDefId`, rather than a `DefId`, since only local items have HIR nodes.
|
||||
|
||||
[local_def_id_to_hir_id]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.local_def_id_to_hir_id
|
||||
[local_def_id_to_hir_id]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.local_def_id_to_hir_id
|
||||
|
||||
Similarly, you can use [`tcx.hir().find(n)`][find] to lookup the node for a
|
||||
Similarly, you can use [`tcx.hir_node(n)`][hir_node] to lookup the node for a
|
||||
[`HirId`]. This returns a `Option<Node<'hir>>`, where [`Node`] is an enum
|
||||
defined in the map. By matching on this, you can find out what sort of
|
||||
node the `HirId` referred to and also get a pointer to the data
|
||||
|
|
@ -142,15 +136,16 @@ that `n` must be some HIR expression, you can do
|
|||
[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the
|
||||
[`&hir::Expr`][Expr], panicking if `n` is not in fact an expression.
|
||||
|
||||
[find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find
|
||||
[hir_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_node
|
||||
[`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html
|
||||
[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr
|
||||
[Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html
|
||||
|
||||
Finally, you can use the HIR map to find the parents of nodes, via
|
||||
calls like [`tcx.hir().get_parent(n)`][get_parent].
|
||||
Finally, you can find the parents of nodes, via
|
||||
calls like [`tcx.parent_hir_node(n)`][parent_hir_node].
|
||||
|
||||
[get_parent_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node
|
||||
|
||||
[get_parent]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.get_parent
|
||||
|
||||
## HIR Bodies
|
||||
|
||||
|
|
@ -158,10 +153,10 @@ A [`rustc_hir::Body`] represents some kind of executable code, such as the body
|
|||
of a function/closure or the definition of a constant. Bodies are
|
||||
associated with an **owner**, which is typically some kind of item
|
||||
(e.g. an `fn()` or `const`), but could also be a closure expression
|
||||
(e.g. `|x, y| x + y`). You can use the HIR map to find the body
|
||||
associated with a given def-id ([`maybe_body_owned_by`]) or to find
|
||||
the owner of a body ([`body_owner_def_id`]).
|
||||
(e.g. `|x, y| x + y`). You can use the `TyCtxt` to find the body
|
||||
associated with a given def-id ([`hir_maybe_body_owned_by`]) or to find
|
||||
the owner of a body ([`hir_body_owner_def_id`]).
|
||||
|
||||
[`rustc_hir::Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html
|
||||
[`maybe_body_owned_by`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.maybe_body_owned_by
|
||||
[`body_owner_def_id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.body_owner_def_id
|
||||
[`hir_maybe_body_owned_by`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_maybe_body_owned_by
|
||||
[`hir_body_owner_def_id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.hir_body_owner_def_id
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ For opaque types in the defining scope and in the implicit-negative coherence mo
|
|||
always done in two steps. Outside of the defining scope `normalizes-to` for opaques always
|
||||
returns `Err(NoSolution)`.
|
||||
|
||||
We start by trying to to assign the expected type as a hidden type.
|
||||
We start by trying to assign the expected type as a hidden type.
|
||||
|
||||
In the implicit-negative coherence mode, this currently always results in ambiguity without
|
||||
interacting with the opaque types storage. We could instead add allow 'defining' all opaque types,
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ See [compiletest directives] for a listing of directives.
|
|||
- For `ignore-*`/`needs-*`/`only-*` directives, unless extremely obvious,
|
||||
provide a brief remark on why the directive is needed. E.g. `"//@ ignore-wasi
|
||||
(wasi codegens the main symbol differently)"`.
|
||||
- When using `//@ ignore-auxiliary`, specify the corresponding main test files,
|
||||
e.g. ``//@ ignore-auxiliary (used by `./foo.rs`)``.
|
||||
|
||||
## FileCheck best practices
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ for more details.
|
|||
| `normalize-stdout` | Normalize actual stdout with a rule `"<raw>" -> "<normalized>"` before comparing against snapshot | `ui`, `incremental` | `"<RAW>" -> "<NORMALIZED>"`, `<RAW>`/`<NORMALIZED>` is regex capture and replace syntax |
|
||||
| `dont-check-compiler-stderr` | Don't check actual compiler stderr vs stderr snapshot | `ui` | N/A |
|
||||
| `dont-check-compiler-stdout` | Don't check actual compiler stdout vs stdout snapshot | `ui` | N/A |
|
||||
| `dont-require-annotations` | Don't require line annotations for the given diagnostic kind (`//~ KIND`) to be exhaustive | `ui`, `incremental` | `ERROR`, `WARN`, `NOTE`, `HELP`, `SUGGESTION` |
|
||||
| `run-rustfix` | Apply all suggestions via `rustfix`, snapshot fixed output, and check fixed output builds | `ui` | N/A |
|
||||
| `rustfix-only-machine-applicable` | `run-rustfix` but only machine-applicable suggestions | `ui` | N/A |
|
||||
| `exec-env` | Env var to set when executing a test | `ui`, `crashes` | `<KEY>=<VALUE>` |
|
||||
|
|
@ -123,6 +124,9 @@ means the test won't be compiled or run.
|
|||
* `ignore-X` where `X` is a target detail or other criteria on which to ignore the test (see below)
|
||||
* `only-X` is like `ignore-X`, but will *only* run the test on that target or
|
||||
stage
|
||||
* `ignore-auxiliary` is intended for files that *participate* in one or more other
|
||||
main test files but that `compiletest` should not try to build the file itself.
|
||||
Please backlink to which main test is actually using the auxiliary file.
|
||||
* `ignore-test` always ignores the test. This can be used to temporarily disable
|
||||
a test if it is currently not working, but you want to keep it in tree to
|
||||
re-enable it later.
|
||||
|
|
@ -191,8 +195,13 @@ settings:
|
|||
specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
|
||||
16, ptr` will only run if it supports the comma-separated list of atomic
|
||||
widths.
|
||||
- `needs-dynamic-linking` - ignores if target does not support dynamic linking
|
||||
- `needs-dynamic-linking` — ignores if target does not support dynamic linking
|
||||
(which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
|
||||
- `needs-crate-type` — ignores if target platform does not support one or more
|
||||
of the comma-delimited list of specified crate types. For example,
|
||||
`//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored
|
||||
on `wasm32-unknown-unknown` target because the target does not support the
|
||||
`proc-macro` crate type.
|
||||
|
||||
The following directives will check LLVM support:
|
||||
|
||||
|
|
@ -229,14 +238,14 @@ ignoring debuggers.
|
|||
|
||||
### Affecting how tests are built
|
||||
|
||||
| Directive | Explanation | Supported test suites | Possible values |
|
||||
|---------------------|----------------------------------------------------------------------------------------------|---------------------------|------------------------------------------------------------------------------|
|
||||
| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental`. |
|
||||
| `edition` | Alias for `compile-flags: --edition=xxx` | All except for `run-make` | Any valid `--edition` value |
|
||||
| `rustc-env` | Env var to set when running `rustc` | All except for `run-make` | `<KEY>=<VALUE>` |
|
||||
| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make` | Any env var name |
|
||||
| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
|
||||
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
|
||||
| Directive | Explanation | Supported test suites | Possible values |
|
||||
|---------------------|----------------------------------------------------------------------------------------------|---------------------------|--------------------------------------------------------------------------------------------|
|
||||
| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
|
||||
| `edition` | The edition used to build the test | All except for `run-make` | Any valid `--edition` value |
|
||||
| `rustc-env` | Env var to set when running `rustc` | All except for `run-make` | `<KEY>=<VALUE>` |
|
||||
| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make` | Any env var name |
|
||||
| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
|
||||
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
|
||||
|
||||
<div class="warning">
|
||||
Tests (outside of `run-make`) that want to use incremental tests not in the
|
||||
|
|
|
|||
|
|
@ -303,8 +303,7 @@ It should be preferred to using `error-pattern`, which is imprecise and non-exha
|
|||
### `error-pattern`
|
||||
|
||||
The `error-pattern` [directive](directives.md) can be used for runtime messages, which don't
|
||||
have a specific span, or for compile time messages if imprecise matching is required due to
|
||||
multi-line platform specific diagnostics.
|
||||
have a specific span, or in exceptional cases for compile time messages.
|
||||
|
||||
Let's think about this test:
|
||||
|
||||
|
|
@ -318,7 +317,7 @@ fn main() {
|
|||
```
|
||||
|
||||
We want to ensure this shows "index out of bounds" but we cannot use the `ERROR`
|
||||
annotation since the error doesn't have any span. Then it's time to use the
|
||||
annotation since the runtime error doesn't have any span. Then it's time to use the
|
||||
`error-pattern` directive:
|
||||
|
||||
```rust,ignore
|
||||
|
|
@ -331,29 +330,51 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
But for strict testing, try to use the `ERROR` annotation as much as possible,
|
||||
including `//~?` annotations for diagnostics without span.
|
||||
For compile time diagnostics `error-pattern` should very rarely be necessary.
|
||||
Use of `error-pattern` is not recommended in general.
|
||||
|
||||
Per-line annotations (`//~`) are still checked in tests using `error-pattern`.
|
||||
To opt out of these checks, use `//@ compile-flags: --error-format=human`.
|
||||
Do that only in exceptional cases.
|
||||
For strict testing of compile time output, try to use the line annotations `//~` as much as
|
||||
possible, including `//~?` annotations for diagnostics without span.
|
||||
|
||||
### Error levels
|
||||
If the compile time output is target dependent or too verbose, use directive
|
||||
`//@ dont-require-annotations: <diagnostic-kind>` to make the line annotation checking
|
||||
non-exhaustive, some of the compiler messages can stay uncovered by annotations in this mode.
|
||||
|
||||
The error levels that you can have are:
|
||||
For checking runtime output `//@ check-run-results` may be preferable.
|
||||
|
||||
Only use `error-pattern` if none of the above works.
|
||||
|
||||
Line annotations `//~` are still checked in tests using `error-pattern`.
|
||||
In exceptional cases use `//@ compile-flags: --error-format=human` to opt out of these checks.
|
||||
|
||||
### Diagnostic kinds (error levels)
|
||||
|
||||
The diagnostic kinds that you can have are:
|
||||
|
||||
- `ERROR`
|
||||
- `WARN` or `WARNING`
|
||||
- `WARN` (or `WARNING`)
|
||||
- `NOTE`
|
||||
- `HELP` and `SUGGESTION`
|
||||
- `HELP`
|
||||
- `SUGGESTION`
|
||||
|
||||
You are allowed to not include a level, but you should include it at least for
|
||||
the primary message.
|
||||
|
||||
The `SUGGESTION` level is used for specifying what the expected replacement text
|
||||
The `SUGGESTION` kind is used for specifying what the expected replacement text
|
||||
should be for a diagnostic suggestion.
|
||||
|
||||
`ERROR` and `WARN` kinds are required to be exhaustively covered by line annotations
|
||||
`//~` by default.
|
||||
|
||||
Other kinds only need to be line-annotated if at least one annotation of that kind appears
|
||||
in the test file. For example, one `//~ NOTE` will also require all other `//~ NOTE`s in the file
|
||||
to be written out explicitly.
|
||||
|
||||
Use directive `//@ dont-require-annotations` to opt out of exhaustive annotations.
|
||||
E.g. use `//@ dont-require-annotations: NOTE` to annotate notes selectively.
|
||||
Avoid using this directive for `ERROR`s and `WARN`ings, unless there's a serious reason, like
|
||||
target-dependent compiler output.
|
||||
|
||||
Missing diagnostic kinds (`//~ message`) are currently accepted, but are being phased away.
|
||||
They will match any compiler output kind, but will not force exhaustive annotations for that kind.
|
||||
Prefer explicit kind and `//@ dont-require-annotations` to achieve the same effect.
|
||||
|
||||
UI tests use the `-A unused` flag by default to ignore all unused warnings, as
|
||||
unused warnings are usually not the focus of a test. However, simple code
|
||||
samples often have unused warnings. If the test is specifically testing an
|
||||
|
|
|
|||
|
|
@ -61,11 +61,11 @@ Here is a summary:
|
|||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Describe the *syntax* of a type: what the user wrote (with some desugaring). | Describe the *semantics* of a type: the meaning of what the user wrote. |
|
||||
| Each `rustc_hir::Ty` has its own spans corresponding to the appropriate place in the program. | Doesn’t correspond to a single place in the user’s program. |
|
||||
| `rustc_hir::Ty` has generics and lifetimes; however, some of those lifetimes are special markers like [`LifetimeName::Implicit`][implicit]. | `ty::Ty` has the full type, including generics and lifetimes, even if the user left them out |
|
||||
| `rustc_hir::Ty` has generics and lifetimes; however, some of those lifetimes are special markers like [`LifetimeKind::Implicit`][implicit]. | `ty::Ty` has the full type, including generics and lifetimes, even if the user left them out |
|
||||
| `fn foo(x: u32) → u32 { }` - Two `rustc_hir::Ty` representing each usage of `u32`, each has its own `Span`s, and `rustc_hir::Ty` doesn’t tell us that both are the same type | `fn foo(x: u32) → u32 { }` - One `ty::Ty` for all instances of `u32` throughout the program, and `ty::Ty` tells us that both usages of `u32` mean the same type. |
|
||||
| `fn foo(x: &u32) -> &u32)` - Two `rustc_hir::Ty` again. Lifetimes for the references show up in the `rustc_hir::Ty`s using a special marker, [`LifetimeName::Implicit`][implicit]. | `fn foo(x: &u32) -> &u32)`- A single `ty::Ty`. The `ty::Ty` has the hidden lifetime param. |
|
||||
| `fn foo(x: &u32) -> &u32)` - Two `rustc_hir::Ty` again. Lifetimes for the references show up in the `rustc_hir::Ty`s using a special marker, [`LifetimeKind::Implicit`][implicit]. | `fn foo(x: &u32) -> &u32)`- A single `ty::Ty`. The `ty::Ty` has the hidden lifetime param. |
|
||||
|
||||
[implicit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.LifetimeName.html#variant.Implicit
|
||||
[implicit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.LifetimeKind.html#variant.Implicit
|
||||
|
||||
**Order**
|
||||
|
||||
|
|
@ -323,4 +323,4 @@ When looking at the debug output of `Ty` or simply talking about different types
|
|||
- Generic parameters: `{name}/#{index}` e.g. `T/#0`, where `index` corresponds to its position in the list of generic parameters
|
||||
- Inference variables: `?{id}` e.g. `?x`/`?0`, where `id` identifies the inference variable
|
||||
- Variables from binders: `^{binder}_{index}` e.g. `^0_x`/`^0_2`, where `binder` and `index` identify which variable from which binder is being referred to
|
||||
- Placeholders: `!{id}` or `!{id}_{universe}` e.g. `!x`/`!0`/`!x_2`/`!0_2`, representing some unique type in the specified universe. The universe is often elided when it is `0`
|
||||
- Placeholders: `!{id}` or `!{id}_{universe}` e.g. `!x`/`!0`/`!x_2`/`!0_2`, representing some unique type in the specified universe. The universe is often elided when it is `0`
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
- [illumos](platform-support/illumos.md)
|
||||
- [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md)
|
||||
- [loongarch\*-unknown-none\*](platform-support/loongarch-none.md)
|
||||
- [\*-lynxos178-\*](platform-support/lynxos178.md)
|
||||
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
|
||||
- [m68k-unknown-none-elf](platform-support/m68k-unknown-none-elf.md)
|
||||
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
|
||||
|
|
|
|||
|
|
@ -110,6 +110,19 @@ It takes a path to [the dlltool executable](https://sourceware.org/binutils/docs
|
|||
If this flag is not specified, a dlltool executable will be inferred based on
|
||||
the host environment and target.
|
||||
|
||||
## dwarf-version
|
||||
|
||||
This option controls the version of DWARF that the compiler emits, on platforms
|
||||
that use DWARF to encode debug information. It takes one of the following
|
||||
values:
|
||||
|
||||
* `2`: DWARF version 2 (the default on certain platforms, like Android).
|
||||
* `3`: DWARF version 3 (the default on certain platforms, like AIX).
|
||||
* `4`: DWARF version 4 (the default on most platforms, like Linux & macOS).
|
||||
* `5`: DWARF version 5.
|
||||
|
||||
DWARF version 1 is not supported.
|
||||
|
||||
## embed-bitcode
|
||||
|
||||
This flag controls whether or not the compiler embeds LLVM bitcode into object
|
||||
|
|
|
|||
|
|
@ -407,6 +407,7 @@ target | std | host | notes
|
|||
[`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI)
|
||||
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
|
||||
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
|
||||
[`x86_64-lynx-lynxos178`](platform-support/lynxos178.md) | | | x86_64 LynxOS-178
|
||||
[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ✓ | | 64-bit x86 Cygwin |
|
||||
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
|
||||
[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
|
||||
|
|
|
|||
77
src/doc/rustc/src/platform-support/lynxos178.md
Normal file
77
src/doc/rustc/src/platform-support/lynxos178.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# `*-lynxos178-*`
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
Targets for the LynxOS-178 operating system.
|
||||
|
||||
[LynxOS-178](https://www.lynx.com/products/lynxos-178-do-178c-certified-posix-rtos)
|
||||
is a commercial RTOS designed for safety-critical real-time systems. It is
|
||||
developed by Lynx Software Technologies as part of the
|
||||
[MOSA.ic](https://www.lynx.com/solutions/safe-and-secure-operating-environment)
|
||||
product suite.
|
||||
|
||||
Target triples available:
|
||||
- `x86_64-lynx-lynxos178`
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- Renat Fatykhov, https://github.com/rfatykhov-lynx
|
||||
|
||||
## Requirements
|
||||
|
||||
To build Rust programs for LynxOS-178, you must first have LYNX MOSA.ic
|
||||
installed on the build machine.
|
||||
|
||||
This target supports only cross-compilation, from the same hosts supported by
|
||||
the Lynx CDK.
|
||||
|
||||
Currently only `no_std` programs are supported. Work to support `std` is in
|
||||
progress.
|
||||
|
||||
## Building the target
|
||||
|
||||
You can build Rust with support for x86_64-lynx-lynxos178 by adding that
|
||||
to the `target` list in `config.toml`, and then running `./x build --target
|
||||
x86_64-lynx-lynxos178 compiler`.
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust does not yet ship pre-compiled artifacts for this target. To compile for
|
||||
this target, you will need to build Rust with the target enabled (see "Building
|
||||
the target" above).
|
||||
|
||||
Before executing `cargo`, you must configure the environment to build LynxOS-178
|
||||
binaries by running `source setup.sh` from the los178 directory.
|
||||
|
||||
If your program/crates contain procedural macros, Rust must be able to build
|
||||
binaries for the host as well. The host gcc is hidden by sourcing setup.sh. To
|
||||
deal with this, add the following to your project's `.cargo/config.toml`:
|
||||
```toml
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
linker = "lynx-host-gcc"
|
||||
```
|
||||
(If necessary substitute your host target triple for x86_64-unknown-linux-gnu.)
|
||||
|
||||
To point `cargo` at the correct rustc binary, set the RUSTC environment
|
||||
variable.
|
||||
|
||||
The core library should be usable. You can try by building it as part of your
|
||||
project:
|
||||
```bash
|
||||
cargo +nightly build -Z build-std=core --target x86_64-lynx-lynxos178
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Binaries built with rust can be provided to a LynxOS-178 instance on its file
|
||||
system, where they can be executed. Rust binaries tend to be large, so it may
|
||||
be necessary to strip them first.
|
||||
|
||||
It is possible to run the Rust testsuite by providing a test runner that takes
|
||||
the test binary and executes it under LynxOS-178. Most (all?) tests won't run
|
||||
without std support though, which is not yet supported.
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
LYNX MOSA.ic comes with all the tools required to cross-compile C code for
|
||||
LynxOS-178.
|
||||
|
|
@ -521,8 +521,11 @@ self.pre_comment.as_ref().map_or(
|
|||
|
||||
## Control flow expressions
|
||||
|
||||
This section covers `if`, `if let`, `loop`, `while`, `while let`, and `for`
|
||||
expressions.
|
||||
This section covers `for` and `loop` expressions, as well as `if` and `while`
|
||||
expressions with their sub-expression variants. This includes those with a
|
||||
single `let` sub-expression (i.e. `if let` and `while let`)
|
||||
as well as "let-chains": those with one or more `let` sub-expressions and
|
||||
one or more bool-type conditions (i.e. `if a && let Some(b) = c`).
|
||||
|
||||
Put the keyword, any initial clauses, and the opening brace of the block all on
|
||||
a single line, if they fit. Apply the usual rules for [block
|
||||
|
|
@ -548,10 +551,11 @@ if let ... {
|
|||
}
|
||||
```
|
||||
|
||||
If the control line needs to be broken, prefer to break before the `=` in `*
|
||||
let` expressions and before `in` in a `for` expression; block-indent the
|
||||
following line. If the control line is broken for any reason, put the opening
|
||||
brace on its own line, not indented. Examples:
|
||||
If the control line needs to be broken, then prefer breaking after the `=` for any
|
||||
`let` sub-expression in an `if` or `while` expression that does not fit,
|
||||
and before `in` in a `for` expression; the following line should be block indented.
|
||||
If the control line is broken for any reason, then the opening brace should be on its
|
||||
own line and not indented. Examples:
|
||||
|
||||
```rust
|
||||
while let Some(foo)
|
||||
|
|
@ -572,6 +576,68 @@ if a_long_expression
|
|||
{
|
||||
...
|
||||
}
|
||||
|
||||
if let Some(a) = b
|
||||
&& another_long_expression
|
||||
&& a_third_long_expression
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
if let Some(relatively_long_thing)
|
||||
= a_long_expression
|
||||
&& another_long_expression
|
||||
&& a_third_long_expression
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
if some_expr
|
||||
&& another_long_expression
|
||||
&& let Some(relatively_long_thing) =
|
||||
a_long_long_long_long_long_long_really_reallllllllllyyyyyyy_long_expression
|
||||
&& a_third_long_expression
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
A let-chain control line is allowed to be formatted on a single line provided
|
||||
it only consists of two clauses, with the first, left-hand side operand being a literal or an
|
||||
`ident` (which can optionally be preceded by any number of unary prefix operators),
|
||||
and the second, right-hand side operand being a single-line `let` clause. Otherwise,
|
||||
the control line must be broken and formatted according to the above rules. For example:
|
||||
|
||||
```rust
|
||||
if a && let Some(b) = foo() {
|
||||
// ...
|
||||
}
|
||||
|
||||
if true && let Some(b) = foo() {
|
||||
// ...
|
||||
}
|
||||
|
||||
let operator = if !from_hir_call && let Some(p) = parent {
|
||||
// ...
|
||||
};
|
||||
|
||||
if let Some(b) = foo()
|
||||
&& a
|
||||
{
|
||||
// ..
|
||||
}
|
||||
|
||||
if foo()
|
||||
&& let Some(b) = bar
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
if gen_pos != GenericArgPosition::Type
|
||||
&& let Some(b) = gen_args.bindings.first()
|
||||
{
|
||||
// ..
|
||||
}
|
||||
```
|
||||
|
||||
Where the initial clause spans multiple lines and ends with one or more closing
|
||||
|
|
|
|||
14
src/doc/unstable-book/src/compiler-flags/allow-features.md
Normal file
14
src/doc/unstable-book/src/compiler-flags/allow-features.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# `allow-features`
|
||||
|
||||
This feature is perma-unstable and has no tracking issue.
|
||||
|
||||
----
|
||||
|
||||
This flag allows limiting the features which can be enabled with `#![feature(...)]` attributes.
|
||||
By default, all features are allowed on nightly and no features are allowed on stable or beta (but see [`RUSTC_BOOTSTRAP`]).
|
||||
|
||||
Features are comma-separated, for example `-Z allow-features=ffi_pure,f16`.
|
||||
If the flag is present, any feature listed will be allowed and any feature not listed will be disallowed.
|
||||
Any unrecognized feature is ignored.
|
||||
|
||||
[`RUSTC_BOOTSTRAP`]: ./rustc-bootstrap.html
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
## `dwarf-version`
|
||||
|
||||
The tracking issue for this feature is: <https://github.com/rust-lang/rust/issues/103057>
|
||||
|
||||
----------------------------
|
||||
|
||||
This option controls the version of DWARF that the compiler emits, on platforms
|
||||
that use DWARF to encode debug information. It takes one of the following
|
||||
values:
|
||||
|
||||
* `2`: DWARF version 2 (the default on certain platforms, like macOS).
|
||||
* `4`: DWARF version 4 (the default on certain platforms, like Linux).
|
||||
* `5`: DWARF version 5.
|
||||
56
src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
Normal file
56
src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# `RUSTC_BOOTSTRAP`
|
||||
|
||||
This feature is perma-unstable and has no tracking issue.
|
||||
|
||||
----
|
||||
|
||||
The `RUSTC_BOOTSTRAP` environment variable tells rustc to act as if it is a nightly compiler;
|
||||
in particular, it allows `#![feature(...)]` attributes and `-Z` flags even on the stable release channel.
|
||||
|
||||
Setting `RUSTC_BOOTSTRAP=1` instructs rustc to enable this for all crates.
|
||||
Setting `RUSTC_BOOTSTRAP=crate_name` instructs rustc to only apply this to crates named `crate_name`.
|
||||
Setting `RUSTC_BOOTSTRAP=-1` instructs rustc to act as if it is a stable compiler, even on the nightly release channel.
|
||||
Cargo disallows setting `cargo::rustc-env=RUSTC_BOOTSTRAP` in build scripts.
|
||||
Build systems can limit the features they enable with [`-Z allow-features=feature1,feature2`][Z-allow-features].
|
||||
Crates can fully opt out of unstable features by using [`#![forbid(unstable_features)]`][unstable-features] at the crate root (or any other way of enabling lints, such as `-F unstable-features`).
|
||||
|
||||
[Z-allow-features]: ./allow-features.html
|
||||
[unstable-features]: ../../rustc/lints/listing/allowed-by-default.html#unstable-features
|
||||
|
||||
## Why does this environment variable exist?
|
||||
|
||||
`RUSTC_BOOTSTRAP`, as the name suggests, is used for bootstrapping the compiler from an earlier version.
|
||||
In particular, nightly is built with beta, and beta is built with stable.
|
||||
Since the standard library and compiler both use unstable features, `RUSTC_BOOTSTRAP` is required so that we can use the previous version to build them.
|
||||
|
||||
## Why is this environment variable so easy to use for people not in the rust project?
|
||||
|
||||
Originally, `RUSTC_BOOTSTRAP` required passing in a hash of the previous compiler version, to discourage using it for any purpose other than bootstrapping.
|
||||
That constraint was later relaxed; see <https://github.com/rust-lang/rust/issues/36548> for the discussion that happened at that time.
|
||||
|
||||
People have at various times proposed re-adding the technical constraints.
|
||||
However, doing so is extremely disruptive for several major projects that we very much want to keep using the latest stable toolchain version, such as Firefox, Rust for Linux, and Chromium.
|
||||
We continue to allow `RUSTC_BOOTSTRAP` until we can come up with an alternative that does not disrupt our largest constituents.
|
||||
|
||||
## Stability policy
|
||||
|
||||
Despite being usable on stable, this is an unstable feature.
|
||||
Like any other unstable feature, we reserve the right to change or remove this feature in the future, as well as any other unstable feature that it enables.
|
||||
Using this feature opts you out of the normal stability/backwards compatibility guarantee of stable.
|
||||
|
||||
Although we do not take technical measures to prevent it from being used, we strongly discourage using this feature.
|
||||
If at all possible, please contribute to stabilizing the features you care about instead of bypassing the Rust project's stability policy.
|
||||
|
||||
For library crates, we especially discourage the use of this feature.
|
||||
The crates depending on you do not know that you use this feature, have little recourse if it breaks, and can be used in contexts that are hard to predict.
|
||||
|
||||
For libraries that do use this feature, please document the versions you support (including a *maximum* as well as minimum version), and a mechanism to disable it.
|
||||
If you do not have a mechanism to disable the use of `RUSTC_BOOTSTRAP`, consider removing its use altogether, such that people can only use your library if they are already using a nightly toolchain.
|
||||
This leaves the choice of whether to opt-out of Rust's stability guarantees up to the end user building their code.
|
||||
|
||||
## History
|
||||
|
||||
- [Allowed without a hash](https://github.com/rust-lang/rust/pull/37265) ([discussion](https://github.com/rust-lang/rust/issues/36548))
|
||||
- [Extended to crate names](https://github.com/rust-lang/rust/pull/77802) ([discussion](https://github.com/rust-lang/cargo/issues/7088))
|
||||
- [Disallowed for build scripts](https://github.com/rust-lang/cargo/pull/9181) ([discussion](https://github.com/rust-lang/compiler-team/issues/350))
|
||||
- [Extended to emulate stable](https://github.com/rust-lang/rust/pull/132993) ([discussion](https://github.com/rust-lang/rust/issues/123404))
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# `RUSTC_OVERRIDE_VERSION_STRING`
|
||||
|
||||
This feature is perma-unstable and has no tracking issue.
|
||||
|
||||
----
|
||||
|
||||
The `RUSTC_OVERRIDE_VERSION_STRING` environment variable overrides the version reported by `rustc --version`. For example:
|
||||
|
||||
```console
|
||||
$ rustc --version
|
||||
rustc 1.87.0-nightly (43f0014ef 2025-03-25)
|
||||
$ env RUSTC_OVERRIDE_VERSION_STRING=1.81.0-nightly rustc --version
|
||||
rustc 1.81.0-nightly
|
||||
```
|
||||
|
||||
Note that the version string is completely overwritten; i.e. rustc discards commit hash and commit date information unless it is explicitly included in the environment variable. The string only applies to the "release" part of the version; for example:
|
||||
```console
|
||||
$ RUSTC_OVERRIDE_VERSION_STRING="1.81.0-nightly (aaaaaaaaa 2025-03-22)" rustc -vV
|
||||
rustc 1.81.0-nightly (aaaaaaaaa 2025-03-22)
|
||||
binary: rustc
|
||||
commit-hash: 43f0014ef0f242418674f49052ed39b70f73bc1c
|
||||
commit-date: 2025-03-25
|
||||
host: x86_64-unknown-linux-gnu
|
||||
release: 1.81.0-nightly (aaaaaaaaa 2025-03-22)
|
||||
LLVM version: 20.1.1
|
||||
```
|
||||
|
||||
Note here that `commit-hash` and `commit-date` do not match the values in the string, and `release` includes the fake hash and date.
|
||||
|
||||
This variable has no effect on whether or not unstable features are allowed to be used. It only affects the output of `--version`.
|
||||
|
||||
## Why does this environment variable exist?
|
||||
|
||||
Various library crates have incomplete or incorrect feature detection.
|
||||
This environment variable allows bisecting crates that do incorrect detection with `version_check::supports_feature`.
|
||||
|
||||
This is not intended to be used for any other case (and, except for bisection, is not particularly useful).
|
||||
|
||||
See <https://github.com/rust-lang/rust/pull/124339> for further discussion.
|
||||
|
|
@ -6,6 +6,8 @@ The tracking issue for this feature is: [#29641]
|
|||
|
||||
------------------------
|
||||
|
||||
> **Note**: This feature will be superseded by [`deref_patterns`] in the future.
|
||||
|
||||
Box patterns let you match on `Box<T>`s:
|
||||
|
||||
|
||||
|
|
@ -28,3 +30,5 @@ fn main() {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
[`deref_patterns`]: ./deref-patterns.md
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
# `cfg_boolean_literals`
|
||||
|
||||
The tracking issue for this feature is: [#131204]
|
||||
|
||||
[#131204]: https://github.com/rust-lang/rust/issues/131204
|
||||
|
||||
------------------------
|
||||
|
||||
The `cfg_boolean_literals` feature makes it possible to use the `true`/`false`
|
||||
literal as cfg predicate. They always evaluate to true/false respectively.
|
||||
|
||||
## Examples
|
||||
|
||||
```rust
|
||||
#![feature(cfg_boolean_literals)]
|
||||
|
||||
#[cfg(true)]
|
||||
const A: i32 = 5;
|
||||
|
||||
#[cfg(all(false))]
|
||||
const A: i32 = 58 * 89;
|
||||
```
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# `deref_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#87121]
|
||||
|
||||
[#87121]: https://github.com/rust-lang/rust/issues/87121
|
||||
|
||||
------------------------
|
||||
|
||||
> **Note**: This feature is incomplete. In the future, it is meant to supersede
|
||||
> [`box_patterns`](./box-patterns.md) and [`string_deref_patterns`](./string-deref-patterns.md).
|
||||
|
||||
This feature permits pattern matching on [smart pointers in the standard library] through their
|
||||
`Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which
|
||||
is currently a placeholder).
|
||||
|
||||
```rust
|
||||
#![feature(deref_patterns)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
let mut v = vec![Box::new(Some(0))];
|
||||
|
||||
// Implicit dereferences are inserted when a pattern can match against the
|
||||
// result of repeatedly dereferencing but can't match against a smart
|
||||
// pointer itself. This works alongside match ergonomics for references.
|
||||
if let [Some(x)] = &mut v {
|
||||
*x += 1;
|
||||
}
|
||||
|
||||
// Explicit `deref!(_)` patterns may instead be used when finer control is
|
||||
// needed, e.g. to dereference only a single smart pointer, or to bind the
|
||||
// the result of dereferencing to a variable.
|
||||
if let deref!([deref!(opt_x @ Some(1))]) = &mut v {
|
||||
opt_x.as_mut().map(|x| *x += 1);
|
||||
}
|
||||
|
||||
assert_eq!(v, [Box::new(Some(2))]);
|
||||
```
|
||||
|
||||
Without this feature, it may be necessary to introduce temporaries to represent dereferenced places
|
||||
when matching on nested structures:
|
||||
|
||||
```rust
|
||||
let mut v = vec![Box::new(Some(0))];
|
||||
if let [b] = &mut *v {
|
||||
if let Some(x) = &mut **b {
|
||||
*x += 1;
|
||||
}
|
||||
}
|
||||
if let [b] = &mut *v {
|
||||
if let opt_x @ Some(1) = &mut **b {
|
||||
opt_x.as_mut().map(|x| *x += 1);
|
||||
}
|
||||
}
|
||||
assert_eq!(v, [Box::new(Some(2))]);
|
||||
```
|
||||
|
||||
[smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# `explicit_extern_abis`
|
||||
|
||||
The tracking issue for this feature is: #134986
|
||||
|
||||
------
|
||||
|
||||
Disallow `extern` without an explicit ABI. We should write `extern "C"`
|
||||
(or another ABI) instead of just `extern`.
|
||||
|
||||
By making the ABI explicit, it becomes much clearer that "C" is just one of the
|
||||
possible choices, rather than the "standard" way for external functions.
|
||||
Removing the default makes it easier to add a new ABI on equal footing as "C".
|
||||
|
||||
```rust,editionfuture,compile_fail
|
||||
#![feature(explicit_extern_abis)]
|
||||
|
||||
extern fn function1() {} // ERROR `extern` declarations without an explicit ABI
|
||||
// are disallowed
|
||||
|
||||
extern "C" fn function2() {} // compiles
|
||||
|
||||
extern "aapcs" fn function3() {} // compiles
|
||||
```
|
||||
|
|
@ -52,9 +52,9 @@ with any regular function.
|
|||
Various intrinsics have native MIR operations that they correspond to. Instead of requiring
|
||||
backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass
|
||||
will convert the calls to the MIR operation. Backends do not need to know about these intrinsics
|
||||
at all. These intrinsics only make sense without a body, and can either be declared as a "rust-intrinsic"
|
||||
or as a `#[rustc_intrinsic]`. The body is never used, as calls to the intrinsic do not exist
|
||||
anymore after MIR analyses.
|
||||
at all. These intrinsics only make sense without a body, and can be declared as a `#[rustc_intrinsic]`.
|
||||
The body is never used as the lowering pass implements support for all backends, so we never have to
|
||||
use the fallback logic.
|
||||
|
||||
## Intrinsics without fallback logic
|
||||
|
||||
|
|
@ -70,28 +70,3 @@ These are written without a body:
|
|||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
```
|
||||
|
||||
### Legacy extern ABI based intrinsics
|
||||
|
||||
*This style is deprecated, always prefer the above form.*
|
||||
|
||||
These are imported as if they were FFI functions, with the special
|
||||
`rust-intrinsic` ABI. For example, if one was in a freestanding
|
||||
context, but wished to be able to `transmute` between types, and
|
||||
perform efficient pointer arithmetic, one would import those functions
|
||||
via a declaration like
|
||||
|
||||
```rust
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
# fn main() {}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn transmute<T, U>(x: T) -> U;
|
||||
|
||||
fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
|
||||
}
|
||||
```
|
||||
|
||||
As with any other FFI functions, these are by default always `unsafe` to call.
|
||||
You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
# `macro_metavar_expr_concat`
|
||||
|
||||
The tracking issue for this feature is: [#124225]
|
||||
|
||||
------------------------
|
||||
|
||||
In stable Rust, there is no way to create new identifiers by joining identifiers to literals or other identifiers without using procedural macros such as [`paste`].
|
||||
`#![feature(macro_metavar_expr_concat)]` introduces a way to do this, using the concat metavariable expression.
|
||||
|
||||
> This feature uses the syntax from [`macro_metavar_expr`] but is otherwise
|
||||
> independent. It replaces the old unstable feature [`concat_idents`].
|
||||
|
||||
> This is an experimental feature; it and its syntax will require a RFC before stabilization.
|
||||
|
||||
|
||||
### Overview
|
||||
|
||||
`#![feature(macro_metavar_expr_concat)]` provides the `concat` metavariable expression for creating new identifiers:
|
||||
|
||||
```rust
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
|
||||
macro_rules! create_some_structs {
|
||||
($name:ident) => {
|
||||
pub struct ${ concat(First, $name) };
|
||||
pub struct ${ concat(Second, $name) };
|
||||
pub struct ${ concat(Third, $name) };
|
||||
}
|
||||
}
|
||||
|
||||
create_some_structs!(Thing);
|
||||
```
|
||||
|
||||
This macro invocation expands to:
|
||||
|
||||
```rust
|
||||
pub struct FirstThing;
|
||||
pub struct SecondThing;
|
||||
pub struct ThirdThing;
|
||||
```
|
||||
|
||||
### Syntax
|
||||
|
||||
This feature builds upon the metavariable expression syntax `${ .. }` as specified in [RFC 3086] ([`macro_metavar_expr`]).
|
||||
`concat` is available like `${ concat(items) }`, where `items` is a comma separated sequence of idents and/or literals.
|
||||
|
||||
### Examples
|
||||
|
||||
#### Create a function or method with a concatenated name
|
||||
|
||||
```rust
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
|
||||
macro_rules! make_getter {
|
||||
($name:ident, $field: ident, $ret:ty) => {
|
||||
impl $name {
|
||||
pub fn ${ concat(get_, $field) }(&self) -> &$ret {
|
||||
&self.$field
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Thing {
|
||||
description: String,
|
||||
}
|
||||
|
||||
make_getter!(Thing, description, String);
|
||||
```
|
||||
|
||||
This expands to:
|
||||
|
||||
```rust
|
||||
pub struct Thing {
|
||||
description: String,
|
||||
}
|
||||
|
||||
impl Thing {
|
||||
pub fn get_description(&self) -> &String {
|
||||
&self.description
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Create names for macro generated tests
|
||||
|
||||
```rust
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
|
||||
macro_rules! test_math {
|
||||
($integer:ident) => {
|
||||
#[test]
|
||||
fn ${ concat(test_, $integer, _, addition) } () {
|
||||
let a: $integer = 73;
|
||||
let b: $integer = 42;
|
||||
assert_eq!(a + b, 115)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ${ concat(test_, $integer, _, subtraction) } () {
|
||||
let a: $integer = 73;
|
||||
let b: $integer = 42;
|
||||
assert_eq!(a - b, 31)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_math!(i32);
|
||||
test_math!(u64);
|
||||
test_math!(u128);
|
||||
```
|
||||
|
||||
Running this returns the following output:
|
||||
|
||||
```text
|
||||
running 6 tests
|
||||
test test_i32_subtraction ... ok
|
||||
test test_i32_addition ... ok
|
||||
test test_u128_addition ... ok
|
||||
test test_u128_subtraction ... ok
|
||||
test test_u64_addition ... ok
|
||||
test test_u64_subtraction ... ok
|
||||
|
||||
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
[`paste`]: https://crates.io/crates/paste
|
||||
[RFC 3086]: https://rust-lang.github.io/rfcs/3086-macro-metavar-expr.html
|
||||
[`concat_idents!`]: https://doc.rust-lang.org/nightly/std/macro.concat_idents.html
|
||||
[`macro_metavar_expr`]: ../language-features/macro-metavar-expr.md
|
||||
[`concat_idents`]: ../library-features/concat-idents.md
|
||||
[#124225]: https://github.com/rust-lang/rust/issues/124225
|
||||
[declarative macros]: https://doc.rust-lang.org/stable/reference/macros-by-example.html
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# `macro_metavar_expr`
|
||||
|
||||
The tracking issue for this feature is: [#83527]
|
||||
|
||||
------------------------
|
||||
|
||||
> This feature is not to be confused with [`macro_metavar_expr_concat`].
|
||||
|
||||
[`macro_metavar_expr_concat`]: ./macro-metavar-expr-concat.md
|
||||
[#83527]: https://github.com/rust-lang/rust/issues/83527
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# `offset_of_slice`
|
||||
# `offset_of_enum`
|
||||
|
||||
The tracking issue for this feature is: [#120141]
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ The tracking issue for this feature is: [#87121]
|
|||
|
||||
------------------------
|
||||
|
||||
> **Note**: This feature will be superseded by [`deref_patterns`] in the future.
|
||||
|
||||
This feature permits pattern matching `String` to `&str` through [its `Deref` implementation].
|
||||
|
||||
```rust
|
||||
|
|
@ -42,4 +44,5 @@ pub fn is_it_the_answer(value: Value) -> bool {
|
|||
}
|
||||
```
|
||||
|
||||
[`deref_patterns`]: ./deref-patterns.md
|
||||
[its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ The tracking issue for this feature is: [#29599]
|
|||
|
||||
------------------------
|
||||
|
||||
> This feature is expected to be superseded by [`macro_metavar_expr_concat`](../language-features/macro-metavar-expr-concat.md).
|
||||
|
||||
The `concat_idents` feature adds a macro for concatenating multiple identifiers
|
||||
into one identifier.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue