Commit Graph

74 Commits

Author SHA1 Message Date
Oli Scherer 1f7df1956a Replace `type_alias_impl_trait` by `min_type_alias_impl_trait` with no actual changes in behaviour
This makes `type_alias_impl_trait` not actually do anything anymore
2021-03-15 17:32:43 +00:00
bors 17a07d71bf Auto merge of #76570 - cratelyn:implement-rfc-2945-c-unwind-abi, r=Amanieu
Implement RFC 2945: "C-unwind" ABI

## Implement RFC 2945: "C-unwind" ABI

This branch implements [RFC 2945]. The tracking issue for this RFC is #74990.

The feature gate for the issue is `#![feature(c_unwind)]`.

This RFC was created as part of the ffi-unwind project group tracked at rust-lang/lang-team#19.

### Changes

Further details will be provided in commit messages, but a high-level overview
of the changes follows:

* A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI boundaries is
acceptable. The cases where each of these variants' `unwind` member is true
correspond with the `C-unwind`, `system-unwind`, `stdcall-unwind`, and
`thiscall-unwind` ABI strings introduced in RFC 2945 [3].

* This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`, which
ensure that this feature gate works correctly for each of the new ABIs.
A new language features entry in the unstable book is added as well.

* We adjust the `rustc_middle::ty::layout::fn_can_unwind` function,
used to compute whether or not a `FnAbi` object represents a function that
should be able to unwind when `panic=unwind` is in use.

* Changes are also made to
`rustc_mir_build::build::should_abort_on_panic` so that the function ABI is
used to determind whether it should abort, assuming that the `panic=unwind`
strategy is being used, and no explicit unwind attribute was provided.

[RFC 2945]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
2021-03-10 16:44:04 +00:00
Yuki Okushi c46f948a80
Rollup merge of #79208 - LeSeulArtichaut:stable-unsafe_op_in_unsafe_fn, r=nikomatsakis
Stabilize `unsafe_op_in_unsafe_fn` lint

This makes it possible to override the level of the `unsafe_op_in_unsafe_fn`, as proposed in https://github.com/rust-lang/rust/issues/71668#issuecomment-729770896.

Tracking issue: #71668
r? ```@nikomatsakis``` cc ```@SimonSapin``` ```@RalfJung```

# Stabilization report

This is a stabilization report for `#![feature(unsafe_block_in_unsafe_fn)]`.

## Summary

Currently, the body of unsafe functions is an unsafe block, i.e. you can perform unsafe operations inside.

The `unsafe_op_in_unsafe_fn` lint, stabilized here, can be used to change this behavior, so performing unsafe operations in unsafe functions requires an unsafe block.

For now, the lint is allow-by-default, which means that this PR does not change anything without overriding the lint level.

For more information, see [RFC 2585](https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md)

### Example

```rust
// An `unsafe fn` for demonstration purposes.
// Calling this is an unsafe operation.
unsafe fn unsf() {}

// #[allow(unsafe_op_in_unsafe_fn)] by default,
// the behavior of `unsafe fn` is unchanged
unsafe fn allowed() {
    // Here, no `unsafe` block is needed to
    // perform unsafe operations...
    unsf();

    // ...and any `unsafe` block is considered
    // unused and is warned on by the compiler.
    unsafe {
        unsf();
    }
}

#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn warned() {
    // Removing this `unsafe` block will
    // cause the compiler to emit a warning.
    // (Also, no "unused unsafe" warning will be emitted here.)
    unsafe {
        unsf();
    }
}

#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn denied() {
    // Removing this `unsafe` block will
    // cause a compilation error.
    // (Also, no "unused unsafe" warning will be emitted here.)
    unsafe {
        unsf();
    }
}
```
2021-03-10 08:01:25 +09:00
katelyn a. martin df45c579de rustc_target: add "unwind" payloads to `Abi`
### Overview

    This commit begins the implementation work for RFC 2945. For more
    information, see the rendered RFC [1] and tracking issue [2].

    A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
    and `Thiscall` variants, marking whether unwinding across FFI
    boundaries is acceptable. The cases where each of these variants'
    `unwind` member is true correspond with the `C-unwind`,
    `system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
    introduced in RFC 2945 [3].

 ### Feature Gate and Unstable Book

    This commit adds a `c_unwind` feature gate for the new ABI strings.
    Tests for this feature gate are included in `src/test/ui/c-unwind/`,
    which ensure that this feature gate works correctly for each of the
    new ABIs.

    A new language features entry in the unstable book is added as well.

 ### Further Work To Be Done

    This commit does not proceed to implement the new unwinding ABIs,
    and is intentionally scoped specifically to *defining* the ABIs and
    their feature flag.

 ### One Note on Test Churn

    This will lead to some test churn, in re-blessing hash tests, as the
    deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
    because we can no longer guarantee the ordering of the `Abi`
    variants.

    While this is a downside, this decision was made bearing in mind
    that RFC 2945 states the following, in the "Other `unwind` Strings"
    section [3]:

    >  More unwind variants of existing ABI strings may be introduced,
    >  with the same semantics, without an additional RFC.

    Adding a new variant for each of these cases, rather than specifying
    a payload for a given ABI, would quickly become untenable, and make
    working with the `Abi` enum prone to mistakes.

    This approach encodes the unwinding information *into* a given ABI,
    to account for the future possibility of other `-unwind` ABI
    strings.

 ### Ignore Directives

    `ignore-*` directives are used in two of our `*-unwind` ABI test
    cases.

    Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
    ignore architectures that do not support `stdcall` and
    `thiscall`, respectively.

    These directives are cribbed from
    `src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
    `src/test/ui/extern/extern-thiscall.rs` for `thiscall`.

    This would otherwise fail on some targets, see:
    fcf697f902

 ### Footnotes

[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2021-03-09 14:38:29 -05:00
Yuki Okushi 761ceab467
Rollup merge of #82697 - jplatte:patch-1, r=davidtwco
Fix stabilization version of move_ref_pattern

Both the [changelog](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1490-2020-12-31) and the milestone of the [stabilization PR](https://github.com/rust-lang/rust/pull/76119) say 1.49.0, but the source says 1.48.0. I think the former is correct.
2021-03-04 20:01:07 +09:00
Yuki Okushi 5e68c60406
Rollup merge of #82516 - PoignardAzur:inherent-impl-ty, r=oli-obk
Add incomplete feature gate for inherent associate types.

Mentored by ``````@oli-obk``````

So far the only change is that instead of giving an automatic error, the following code compiles:

```rust
struct Foo;

impl Foo {
    type Bar = isize;
}
```

The backend work to make it actually usable isn't there yet. In particular, this:

```rust
let x : Foo::Bar;
```

will give you:

```sh
error[E0223]: ambiguous associated type
  --> /$RUSTC_DIR/src/test/ui/assoc-inherent.rs:15:13
   |
LL |     let x : Foo::Bar;
   |             ^^^^^^^^ help: use fully-qualified syntax: `<Foo as Trait>::Bar`
```
2021-03-02 21:23:15 +09:00
Jonas Platte c194849a75
Fix stabilization version of move_ref_pattern 2021-03-02 12:54:25 +01:00
lcnr 67f17342ee update tracking issue for `relaxed_struct_unsize` 2021-02-26 08:32:38 +01:00
bors 98f8cce6db Auto merge of #82447 - Amanieu:legacy_const_generics, r=oli-obk
Add #[rustc_legacy_const_generics]

This is the first step towards removing `#[rustc_args_required_const]`: a new attribute is added which rewrites function calls of the form `func(a, b, c)` to `func::<{b}>(a, c)`. This allows previously stabilized functions in `stdarch` which use `rustc_args_required_const` to use const generics instead.

This new attribute is not intended to ever be stabilized, it is only intended for use in `stdarch` as a replacement for `#[rustc_args_required_const]`.

```rust
#[rustc_legacy_const_generics(1)]
pub fn foo<const Y: usize>(x: usize, z: usize) -> [usize; 3] {
    [x, Y, z]
}

fn main() {
    assert_eq!(foo(0 + 0, 1 + 1, 2 + 2), [0, 2, 4]);
    assert_eq!(foo::<{1 + 1}>(0 + 0, 2 + 2), [0, 2, 4]);
}
```

r? `@oli-obk`
2021-02-25 18:14:50 +00:00
Olivier FAURE 4f4e15d5eb Add feature gate for inherent associate types. 2021-02-25 14:10:25 +01:00
Amanieu d'Antras d87eec1bf6 Add #[rustc_legacy_const_generics] 2021-02-23 17:25:55 +00:00
Santiago Pastorino b3000ec0cd
Update pub_macro_rules since version 2021-02-19 13:53:02 -03:00
Vadim Petrochenkov 0fddc2f780
Support `pub` on `macro_rules` 2021-02-19 13:52:57 -03:00
LeSeulArtichaut ec20993c4d Stabilize `unsafe_op_in_unsafe_fn` lint 2021-02-18 17:12:15 +01:00
Vadim Petrochenkov f6caae52c1 Feature gate macro attributes in `#[derive]` output 2021-02-07 20:08:45 +03:00
Vadim Petrochenkov dbdbd30bf2 expand/resolve: Turn `#[derive]` into a regular macro attribute 2021-02-07 20:08:45 +03:00
Bastian Kauschke 031cce8cfc add `relaxed_struct_unsize` feature gate 2021-02-04 00:00:41 +01:00
Hugues de Valon ce9818f2b7 Add a new ABI to support cmse_nonsecure_call
This commit adds a new ABI to be selected via `extern
"C-cmse-nonsecure-call"` on function pointers in order for the compiler to
apply the corresponding cmse_nonsecure_call callsite attribute.
For Armv8-M targets supporting TrustZone-M, this will perform a
non-secure function call by saving, clearing and calling a non-secure
function pointer using the BLXNS instruction.

See the page on the unstable book for details.

Signed-off-by: Hugues de Valon <hugues.devalon@arm.com>
2021-02-02 13:04:31 +00:00
kadmin 6946534d84 Remove const_in_array_rep_expr 2021-01-30 23:20:24 +00:00
bors a8f7075532 Auto merge of #80692 - Aaron1011:feature/query-result-debug, r=estebank
Enforce that query results implement Debug

Currently, we require that query keys implement `Debug`, but we do not do the same for query values. This can make incremental compilation bugs difficult to debug - there isn't a good place to print out the result loaded from disk.

This PR adds `Debug` bounds to several query-related functions, allowing us to debug-print the query value when an 'unstable fingerprint' error occurs. This required adding `#[derive(Debug)]` to a fairly large number of types - hopefully, this doesn't have much of an impact on compiler bootstrapping times.
2021-01-26 05:47:23 +00:00
Joshua Nelson fc53594756 Feature-gate `pointer` and `reference` in intra-doc links
- Only feature gate associated items
- Add docs to unstable book
2021-01-17 15:27:35 -05:00
Aaron Hill 7afb32557d
Enforce that query results implement Debug 2021-01-16 17:53:02 -05:00
Mara Bos d651fa78ce Allow #[rustc_builtin_macro = "name"].
This makes it possible to have both std::panic and core::panic as a
builtin macro, by using different builtin macro names for each.

Also removes SyntaxExtension::is_derive_copy, as the macro name (e.g.
sym::Copy) is now tracked and provides that information directly.
2021-01-09 19:50:06 +01:00
oli 0b841846ba Allow references to interior mutable data behind a feature gate 2021-01-01 16:59:12 +00:00
Rémy Rakic ea8fa36bb4 mark `const_generics_defaults` as an incomplete feature 2021-01-01 10:55:16 +01:00
Rémy Rakic 5f4bb468c1 fix typo in feature gates file 2021-01-01 10:55:16 +01:00
Julian Knodt 61f33bfd29 first pass at default values for const generics
- Adds optional default values to const generic parameters in the AST
  and HIR
- Parses these optional default values
- Adds a `const_generics_defaults` feature gate
2021-01-01 10:55:10 +01:00
mark 40bf3c0f09 Implement edition-based macro pat feature 2020-12-30 09:57:49 -06:00
Bastian Kauschke 06cc9c26da stabilize min_const_generics 2020-12-26 18:24:10 +01:00
Vadim Petrochenkov ec09616078 tidy: Re-enable check for inline unit tests 2020-12-12 19:18:44 +03:00
Vadim Petrochenkov 31d72c2658 Accept arbitrary expressions in key-value attributes at parse time 2020-12-09 21:37:32 +03:00
Camelid 810324d1f3 Rename `optin_builtin_traits` to `auto_traits`
They were originally called "opt-in, built-in traits" (OIBITs), but
people realized that the name was too confusing and a mouthful, and so
they were renamed to just "auto traits". The feature flag's name wasn't
updated, though, so that's what this PR does.

There are some other spots in the compiler that still refer to OIBITs,
but I don't think changing those now is worth it since they are internal
and not particularly relevant to this PR.

Also see <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/opt-in.2C.20built-in.20traits.20(auto.20traits).20feature.20name>.
2020-11-23 14:14:06 -08:00
bors b5c37e86ff Auto merge of #78801 - sexxi-goose:min_capture, r=nikomatsakis
RFC-2229: Implement Precise Capture Analysis

### This PR introduces
- Feature gate for RFC-2229 (incomplete) `capture_disjoint_field`
- Rustc Attribute to print out the capture analysis `rustc_capture_analysis`
- Precise capture analysis

### Description of the analysis
1. If the feature gate is not set then all variables that are not local to the closure will be added to the list of captures. (This is for backcompat)
2. The rest of the analysis is based entirely on how the captured `Place`s are used within the closure. Precise information (i.e. projections) about the `Place` is maintained throughout.
3. To reduce the amount of information we need to keep track of, we do a minimization step. In this step, we determine a list such that no Place within this list represents an ancestor path to another entry in the list.  Check rust-lang/project-rfc-2229#9 for more detailed examples.
4. To keep the compiler functional as before we implement a Bridge between the results of this new analysis to existing data structures used for closure captures. Note the new capture analysis results are only part of MaybeTypeckTables that is the information is only available during typeck-ing.

### Known issues
- Statements like `let _ = x` will make the compiler ICE when used within a closure with the feature enabled. More generally speaking the issue is caused by `let` statements that create no bindings and are init'ed using a Place expression.

### Testing
We removed the code that would handle the case where the feature gate is not set, to enable the feature as default and did a bors try and perf run. More information here: #78762

### Thanks
This has been slowly in the works for a while now.
I want to call out `@Azhng` `@ChrisPardy` `@null-sleep` `@jenniferwills` `@logmosier` `@roxelo` for working on this and the previous PRs that led up to this, `@nikomatsakis` for guiding us.

Closes rust-lang/project-rfc-2229#7
Closes rust-lang/project-rfc-2229#9
Closes rust-lang/project-rfc-2229#6
Closes rust-lang/project-rfc-2229#19

r? `@nikomatsakis`
2020-11-17 03:56:03 +00:00
Jonas Schievink 8825942e86
Rollup merge of #77802 - jyn514:bootstrap-specific, r=nikomatsakis
Allow making `RUSTC_BOOTSTRAP` conditional on the crate name

Motivation: This came up in the [Zulip stream](https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Require.20users.20to.20confirm.20they.20know.20RUSTC_.E2.80.A6.20compiler-team.23350/near/208403962) for https://github.com/rust-lang/compiler-team/issues/350.
See also https://github.com/rust-lang/cargo/pull/6608#issuecomment-458546258; this implements https://github.com/rust-lang/cargo/issues/6627.
The goal is for this to eventually allow prohibiting setting `RUSTC_BOOTSTRAP` in build.rs (https://github.com/rust-lang/cargo/issues/7088).

## User-facing changes

- `RUSTC_BOOTSTRAP=1` still works; there is no current plan to remove this.
- Things like `RUSTC_BOOTSTRAP=0` no longer activate nightly features. In practice this shouldn't be a big deal, since `RUSTC_BOOTSTRAP` is the opposite of stable and everyone uses `RUSTC_BOOTSTRAP=1` anyway.
- `RUSTC_BOOTSTRAP=x` will enable nightly features only for crate `x`.
- `RUSTC_BOOTSTRAP=x,y` will enable nightly features only for crates `x` and `y`.

## Implementation changes

The main change is that `UnstableOptions::from_environment` now requires
an (optional) crate name. If the crate name is unknown (`None`), then the new feature is not available and you still have to use `RUSTC_BOOTSTRAP=1`. In practice this means the feature is only available for `--crate-name`, not for `#![crate_name]`; I'm interested in supporting the second but I'm not sure how.

Other major changes:

- Added `Session::is_nightly_build()`, which uses the `crate_name` of
the session
- Added `nightly_options::match_is_nightly_build`, a convenience method
for looking up `--crate-name` from CLI arguments.
`Session::is_nightly_build()`should be preferred where possible, since
it will take into account `#![crate_name]` (I think).
- Added `unstable_features` to `rustdoc::RenderOptions`

I'm not sure whether this counts as T-compiler or T-lang; _technically_ RUSTC_BOOTSTRAP is an implementation detail, but it's been used so much it seems like this counts as a language change too.

r? `@joshtriplett`
cc `@Mark-Simulacrum` `@hsivonen`
2020-11-15 13:39:43 +01:00
Aman Arora 88310cc0eb Indroduce feature flag for RFC-2229
Signed-off-by: Aman Arora <me@aman-arora.com>
2020-11-10 20:58:28 -05:00
David Hewitt 8d43b3cbb9 Add `#[cfg(panic = "...")]` 2020-11-09 15:30:49 +00:00
Joshua Nelson 622c48e4f1 Allow making `RUSTC_BOOTSTRAP` conditional on the crate name
The main change is that `UnstableOptions::from_environment` now requires
an (optional) crate name. If the crate name is unknown (`None`), then the new feature is not available and you still have to use `RUSTC_BOOTSTRAP=1`. In practice this means the feature is only available for `--crate-name`, not for `#![crate_name]`; I'm interested in supporting the second but I'm not sure how.

Other major changes:

- Added `Session::is_nightly_build()`, which uses the `crate_name` of
the session
- Added `nightly_options::match_is_nightly_build`, a convenience method
for looking up `--crate-name` from CLI arguments.
`Session::is_nightly_build()`should be preferred where possible, since
it will take into account `#![crate_name]` (I think).
- Added `unstable_features` to `rustdoc::RenderOptions`

  There is a user-facing change here: things like `RUSTC_BOOTSTRAP=0` no
  longer active nightly features. In practice this shouldn't be a big
  deal, since `RUSTC_BOOTSTRAP` is the opposite of stable and everyone
  uses `RUSTC_BOOTSTRAP=1` anyway.

- Add tests

  Check against `Cheat`, not whether nightly features are allowed.
  Nightly features are always allowed on the nightly channel.

- Only call `is_nightly_build()` once within a function

- Use booleans consistently for rustc_incremental

  Sessions can't be passed through threads, so `read_file` couldn't take a
  session. To be consistent, also take a boolean in `write_file_header`.
2020-11-07 13:45:11 -05:00
Fabian Zaiser 3a7a997323 Implement destructuring assignment for tuples
Co-authored-by: varkor <github@varkor.com>
2020-11-07 13:17:19 +00:00
Joshua Nelson 57c6ed0c07 Fix even more clippy warnings 2020-10-30 10:13:39 -04:00
Santiago Pastorino 953d7a64a5
Add unsized_locals to INCOMPLETE_FEATURES list 2020-10-27 14:45:28 -03:00
Santiago Pastorino 708fc3b1a2
Add unsized_fn_params feature 2020-10-27 14:45:02 -03:00
Yuki Okushi 46b8e46fe1
Rollup merge of #78396 - josephlr:ermsb, r=petrochenkov
Add compiler support for LLVM's x86_64 ERMSB feature

This change is needed for compiler-builtins to check for this feature
when implementing memcpy/memset. See:
  https://github.com/rust-lang/compiler-builtins/pull/365

Without this change, the following code compiles, but does nothing:
```rust
#[cfg(target_feature = "ermsb")]
pub unsafe fn ermsb_memcpy() { ... }
```

The change just does compile-time detection. I think that runtime
detection will have to come in a follow-up CL to std-detect.

Like all the CPU feature flags, this just references #44839

Signed-off-by: Joe Richey <joerichey@google.com>
2020-10-27 08:45:24 +09:00
Joe Richey ad552bc17e
Add compiler support for LLVM's x86 ERMSB feature
This change is needed for compiler-builtins to check for this feature
when implementing memcpy/memset. See:
  https://github.com/rust-lang/compiler-builtins/pull/365

The change just does compile-time detection. I think that runtime
detection will have to come in a follow-up CL to std-detect.

Like all the CPU feature flags, this just references #44839

Signed-off-by: Joe Richey <joerichey@google.com>
2020-10-26 03:46:54 -07:00
Yuki Okushi 72e02b015e
Rollup merge of #78208 - liketechnik:issue-69399, r=oli-obk
replace `#[allow_internal_unstable]` with `#[rustc_allow_const_fn_unstable]` for `const fn`s

`#[allow_internal_unstable]` is currently used to side-step feature gate and stability checks.
While it was originally only meant to be used only on macros, its use was expanded to `const fn`s.

This pr adds stricter checks for the usage of `#[allow_internal_unstable]` (only on macros) and introduces the `#[rustc_allow_const_fn_unstable]` attribute for usage on `const fn`s.

This pr does not change any of the functionality associated with the use of `#[allow_internal_unstable]` on macros or the usage of `#[rustc_allow_const_fn_unstable]` (instead of `#[allow_internal_unstable]`) on `const fn`s (see https://github.com/rust-lang/rust/issues/69399#issuecomment-712911540).

Note: The check for `#[rustc_allow_const_fn_unstable]` currently only validates that the attribute is used on a function, because I don't know how I would check if the function is a `const fn` at the place of the check. I therefore openend this as a 'draft pull request'.

Closes rust-lang/rust#69399

r? @oli-obk
2020-10-25 18:43:40 +09:00
varkor e0b61111f8 Mark `repr128` as `incomplete_features` 2020-10-21 23:41:26 +01:00
Florian Warzecha 3948b054dc
add rustc_allow_const_fn_unstable attribute
allow_internal_unstable is currently used
to side-step feature gate and stability checks.
While it was originally only meant to be used
only on macros, its use was expanded to
const functions.

This commit prepares stricter checks for the usage of allow_internal_unstable (only on macros)
and introduces the rustc_allow_const_fn_unstable attribute for usage on functions.

See rust-lang/rust#69399
2020-10-21 18:04:18 +02:00
est31 b87e4f36e7 Remove redundant 'static in the compiler 2020-10-18 17:30:15 +02:00
Santiago Pastorino 03321b8cca
Add inline const to INCOMPLETE_FEATURES 2020-10-16 18:15:57 -03:00
Santiago Pastorino 3c4ad55082
Add inline_const feature flag 2020-10-16 15:13:28 -03:00
Dylan DPC 85dbb03490
Rollup merge of #76119 - Amjad50:stabilizing-move_ref_pattern, r=nikomatsakis
Stabilize move_ref_pattern

# Implementation
- Initially the rule was added in the run-up to 1.0. The AST-based borrow checker was having difficulty correctly enforcing match expressions that combined ref and move bindings, and so it was decided to simplify forbid the combination out right.
- The move to MIR-based borrow checking made it possible to enforce the rules in a finer-grained level, but we kept the rule in place in an effort to be conservative in our changes.
- In #68376, @Centril lifted the restriction but required a feature-gate.
- This PR removes the feature-gate.

Tracking issue: #68354.

# Description
This PR is to stabilize the feature `move_ref_pattern`, which allows patterns
containing both `by-ref` and `by-move` bindings at the same time.

For example: `Foo(ref x, y)`, where `x` is `by-ref`,
and `y` is `by-move`.

The rules of moving a variable also apply here when moving *part* of a variable,
such as it can't be referenced or moved before.

If this pattern is used, it would result in *partial move*, which means that
part of the variable is moved. The variable that was partially moved from
cannot be used as a whole in this case, only the parts that are still
not moved can be used.

## Documentation
- The reference (rust-lang/reference#881)
- Rust by example (rust-lang/rust-by-example#1377)

## Tests
There are many tests, but I think one of the comperhensive ones:
- [borrowck-move-ref-pattern-pass.rs](85fbf49ce0/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs)
- [borrowck-move-ref-pattern.rs](85fbf49ce0/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs)

# Examples

```rust
#[derive(PartialEq, Eq)]
struct Finished {}

#[derive(PartialEq, Eq)]
struct Processing {
    status: ProcessStatus,
}

#[derive(PartialEq, Eq)]
enum ProcessStatus {
    One,
    Two,
    Three,
}

#[derive(PartialEq, Eq)]
enum Status {
    Finished(Finished),
    Processing(Processing),
}

fn check_result(_url: &str) -> Status {
    // fetch status from some server
    Status::Processing(Processing {
        status: ProcessStatus::One,
    })
}

fn wait_for_result(url: &str) -> Finished {
    let mut previous_status = None;
    loop {
        match check_result(url) {
            Status::Finished(f) => return f,
            Status::Processing(p) => {
                match (&mut previous_status, p.status) {
                    (None, status) => previous_status = Some(status), // first status
                    (Some(previous), status) if *previous == status => {} // no change, ignore
                    (Some(previous), status) => { // Now it can be used
                        // new status
                        *previous = status;
                    }
                }
            }
        }
    }
}
```

Before, we would have used:
```rust
                match (&previous_status, p.status) {
                    (Some(previous), status) if *previous == status => {} // no change, ignore
                    (_, status) => {
                        // new status
                        previous_status = Some(status);
                    }
                }
```

Demonstrating *partial move*
```rust
fn main() {
    #[derive(Debug)]
    struct Person {
        name: String,
        age: u8,
    }

    let person = Person {
        name: String::from("Alice"),
        age: 20,
    };

    // `name` is moved out of person, but `age` is referenced
    let Person { name, ref age } = person;

    println!("The person's age is {}", age);

    println!("The person's name is {}", name);

    // Error! borrow of partially moved value: `person` partial move occurs
    //println!("The person struct is {:?}", person);

    // `person` cannot be used but `person.age` can be used as it is not moved
    println!("The person's age from person struct is {}", person.age);
}
```
2020-10-16 02:10:07 +02:00