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

Stabilize macros in some more positions #63931

Merged
merged 2 commits into from Oct 1, 2019
Merged

Conversation

@petrochenkov
Copy link
Contributor

petrochenkov commented Aug 27, 2019

  • Fn-like macros and attribute macros in extern blocks
  • Fn-like procedural macros in type positions
  • Attribute macros on inline modules (moved to #64273)

Stabilization report: #63931 (comment).

Closes #49476
cc #54727

@rust-highfive

This comment was marked as outdated.

Copy link
Collaborator

rust-highfive commented Aug 27, 2019

r? @eddyb

(rust_highfive has picked a reviewer for you, use r? to override)

src/libsyntax/ext/expand.rs Outdated Show resolved Hide resolved
src/libsyntax/ext/expand.rs Outdated Show resolved Hide resolved
@Centril

This comment was marked as resolved.

Copy link
Member

Centril commented Aug 27, 2019

  • Fn-like macros and attribute macros in extern blocks
  • Fn-like procedural macros in type positions
  • Attribute macros on inline modules

From a language POV these all seem orthogonal and it seems like that's true from the POV of the compiler code as well. As such, I would like us to consider these separately in 3 different stabilization PRs with associated reports & FCPs.

  • Fn-like procedural macros in type positions

In the associated report, it would be good to elaborate re. hygiene, how this may e.g. interact with expressions in type contexts, and give a recap (because issues re. hygiene isn't the best known subject...) of the issues wit proc macros expanding to expressions and why it isn't an issue here.

@bors

This comment was marked as resolved.

Copy link
Contributor

bors commented Aug 27, 2019

☔️ The latest upstream changes (presumably #63926) made this pull request unmergeable. Please resolve the merge conflicts.

@petrochenkov petrochenkov force-pushed the petrochenkov:stabmac branch from da2eadb to 910ba02 Aug 28, 2019
@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Aug 29, 2019

Stabilization report

All the features below target Rust 1.39 (November 7th 2019).
Tests can be found in test files touched by this PR.

Fn-like macros and attribute macros in extern blocks

Macro attributes are now supported on items in extern blocks, the behavior is the same as for attributes on free/trait/impl items available on stable.

The feature name is #![feature(macros_in_extern)].
The feature was implemented in April 2018 in #49350 to fix issue #48747.
It didn't go through an RFC because the feature seemed to be a trivial extension consistent with already supported macros in item and item-like positions.

Fn-like procedural macros in type positions

Proc macros can now be used in type positions (type A = foo!();), the behavior is the same as for macro_rules macros in the same position, which are available on stable.
The difference is that proc macros on stable use call-site hygiene, while macro_rules use mixed call-site/def-site hygiene, but that difference only affects local variables, labels and $crate so it doesn't apply to types (or at least applies to types no more than to item-position macros, which are available on stable).

The feature is also a part of the polyphyletic #![feature(proc_macro_hygiene)].
The feature was implemented together with all other proc macros somewhere in 2017-2018.
It wasn't stabilized yet because it somehow got lost during the Macro 1.2 stabilization wave, and nobody actively pushed it after that.

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Aug 29, 2019

@Centril

it would be good to elaborate re. hygiene, how this may e.g. interact with expressions in type contexts, and give a recap (because issues re. hygiene isn't the best known subject...) of the issues wit proc macros expanding to expressions and why it isn't an issue here.

Proc macros in expressions and patterns have mostly philosophical issues - they can 1) consume local variables from their environment code and 2) can produce local variables consumable from their environment code.
Given that proc macros on stable can only use "unhygienic" Span::call_site hygiene, and unhygienic local variables are bad, proc macros in expression and patterns are prohibited in general.
Those philosophical issues do not apply to types, they can neither produce nor consume local variables.

The technical issue with expressions and patterns is that local variables stress the hygiene algorithm more and are more likely to hit some corner cases that may certainly exist because the hygiene algorithm does a few questionable things and is not fully understood.
That said, you still can work that feature gate around with stable item macros (https://crates.io/crates/proc-macro-hack), but some hope exists that proc-macro-hack is still a more limited exposure than arbitrary stable expression/pattern macros would be.

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Aug 29, 2019

As such, I would like us to consider these separately in 3 different stabilization PRs with associated reports & FCPs.

The features are pretty trivial (that's why they were selected for immediate stabilization in the first place), I can split the PR if the lang team wants, but that would mostly create extra work for everyone involved, IMO.

@Centril

This comment has been minimized.

Copy link
Member

Centril commented Aug 31, 2019

The features are pretty trivial (that's why they were selected for immediate stabilization in the first place), I can split the PR if the lang team wants, but that would mostly create extra work for everyone involved, IMO.

Fair enough; the types bit is the only bit I currently have worries about (see below).

Those philosophical issues do not apply to types, they can neither produce nor consume local variables.

How does this affect interactions with VLAs in the style of #48055 or run-time-value-dependent typing more generally? For example, let x: type_mac!() = ...; looks like it could "consume" a local let n if unhygienic and producing [u8; dyn n] or some such?

@Centril

This comment has been minimized.

Copy link
Member

Centril commented Aug 31, 2019

r? @Centril (r=me on the code itself once FCP completes)

@rust-highfive rust-highfive assigned Centril and unassigned eddyb Aug 31, 2019
@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Aug 31, 2019

@Centril

How does this affect interactions with VLAs in the style of #48055 or run-time-value-dependent typing more generally? For example, let x: type_mac!() = ...; looks like it could "consume" a local let n if unhygienic and producing [u8; dyn n] or some such?

To clarify, Span::call_site hygiene generally works for local variables (I haven't seen bug reports for it at least), and already available on stable after jumping through a couple of hoops, e.g.

#[proc_macro]
fn item_macro(input) {
    "fn item() {
        ${input}
        let y = x; // OK    
    }"
}

item_macro!(let x = 10);

As I understand, the nrc's desire was to limit it (#52121 (comment)) rather than prohibit completely.
So further minor leaks like [u8; dyn n] should be ok.

@Centril

This comment has been minimized.

Copy link
Member

Centril commented Sep 3, 2019

First, sorry about the delay here but I think I need to understand better...

As I understand, the nrc's desire was to limit it (#52121 (comment)) rather than prohibit completely.

cc @nrc, @pnkfelix (maybe back from vacation soon?), @samth, and @rust-lang/lang

So further minor leaks like [u8; dyn n] should be ok.

So I feel a distinct lack of understanding re. what minor constitutes here. Would e.g. [u8; dyn { n = 3; n }] change anything?

@Centril Centril added the I-nominated label Sep 3, 2019
@nrc

This comment has been minimized.

Copy link
Member

nrc commented Sep 3, 2019

As I understand, the nrc's desire was to limit it (#52121 (comment)) rather than prohibit completely.
So further minor leaks like [u8; dyn n] should be ok.

To clarify, I don't have a specific objection, just a general level of uncertainty about our macro hygiene in general. I'd prefer to not stabilise anything until we resolve that uncertainty, but that might have happened since I was last involved (or might be unrealistic to expect).

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Sep 3, 2019

So I feel a distinct lack of understanding re. what minor constitutes here. Would e.g. [u8; dyn { n = 3; n }] change anything?

Minor as in amount of code it's used in, so it less likely to hit corner cases statistically.
(n = 3 doesn't change anything.)
Anyway, we can feature gate dyn n in expansions specifically, if it's ever implemented.

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Sep 3, 2019

[T; dyn expr] in types isn't at all a thing that I've ever seen proposed.

The VLA(-like) proposal was for [expr; dyn expr] evaluating to a [T] value.

Runtime expressions in types amount to dependent typing, which we can all agree is far away, if ever, and for the time being these proc macros don't really have issues like that.


That said, the interesting case IMO is this:

macro_rules! foo {
    ($x:ident, $e:expr) => ([(); {
        let $x = 0;
        let x = 1;
        $e
    }])
}

macro_rules! bar {
    ($x:ident, $e:expr) => ([(); {
        let $x = 0;
        let $x = 1;
        $e
    }])
}

const _: foo!(x, x + 1) = [()];
const _: bar!(x, x + 1) = [(), ()];

If you were to implement either foo or bar as proc macros, would they both behave like bar?

However, even if that is the case, since the expression using x must be passed into the macro for the distinction to matter, the proc macro could very well "scavenge" for the right identifier in the input to produce the unhygienic behavior anyway.

So it does help that types are "closed expressions", wrt local bindings in scope.

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Sep 5, 2019

I've just noticed that this PR stabilizes the next code as well:

#[my_attr]
mod m {
    mod n; // Out-of-line module, how should `my_attr` see it in its input?
}

So, we additionally need to feature gate out-of-line modules in attr/derive input.

This may affect stable in corner cases:

#[my_attr]
fn m() {
    #[path = "zzz.rs"]
    mod n;
}

UPDATE: Done in #64273.

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Sep 30, 2019

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.

Add some tests for macros in extern blocks, remove duplicate tests
@petrochenkov petrochenkov force-pushed the petrochenkov:stabmac branch from b9dcb72 to 5ae38bb Sep 30, 2019
@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Sep 30, 2019

@Centril
Rebased, the stabilization version is bumped to 1.40.

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Sep 30, 2019

@bors r=Centril
(This was actually r+'d in #63931 (comment).)

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Sep 30, 2019

📌 Commit 5ae38bb has been approved by Centril

Centril added a commit to Centril/rust that referenced this pull request Oct 1, 2019
Stabilize macros in some more positions

- Fn-like macros and attribute macros in `extern` blocks
- Fn-like procedural macros in type positions
- ~Attribute macros on inline modules~ (moved to rust-lang#64273)

Stabilization report: rust-lang#63931 (comment).

Closes rust-lang#49476
cc rust-lang#54727
bors added a commit that referenced this pull request Oct 1, 2019
Rollup of 9 pull requests

Successful merges:

 - #63649 (Upgrade Emscripten targets to use upstream LLVM backend)
 - #63674 (syntax: Support modern attribute syntax in the `meta` matcher)
 - #63931 (Stabilize macros in some more positions)
 - #64887 (syntax: recover trailing `|` in or-patterns)
 - #64907 (A small amount of tidying-up factored out from PR #64648)
 - #64928 (Add tests for some issues)
 - #64930 (Silence unreachable code lint from await desugaring)
 - #64935 (Improve code clarity)
 - #64937 (Deduplicate closure type errors)

Failed merges:

 - #64918 (Add long error explanation for E0551)

r? @ghost
Centril added a commit to Centril/rust that referenced this pull request Oct 1, 2019
Stabilize macros in some more positions

- Fn-like macros and attribute macros in `extern` blocks
- Fn-like procedural macros in type positions
- ~Attribute macros on inline modules~ (moved to rust-lang#64273)

Stabilization report: rust-lang#63931 (comment).

Closes rust-lang#49476
cc rust-lang#54727
bors added a commit that referenced this pull request Oct 1, 2019
Rollup of 10 pull requests

Successful merges:

 - #63674 (syntax: Support modern attribute syntax in the `meta` matcher)
 - #63931 (Stabilize macros in some more positions)
 - #64887 (syntax: recover trailing `|` in or-patterns)
 - #64895 (async/await: improve not-send errors)
 - #64896 (Remove legacy grammar)
 - #64907 (A small amount of tidying-up factored out from PR #64648)
 - #64928 (Add tests for some issues)
 - #64930 (Silence unreachable code lint from await desugaring)
 - #64935 (Improve code clarity)
 - #64937 (Deduplicate closure type errors)

Failed merges:

r? @ghost
@bors bors merged commit 5ae38bb into rust-lang:master Oct 1, 2019
4 checks passed
4 checks passed
pr Build #20190930.56 succeeded
Details
pr (Linux mingw-check) Linux mingw-check succeeded
Details
pr (Linux x86_64-gnu-llvm-6.0) Linux x86_64-gnu-llvm-6.0 succeeded
Details
pr (LinuxTools) LinuxTools succeeded
Details
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Dec 29, 2019
Stabilize attribute macros on inline modules

While still gating non-inline modules in proc macro input.

Split from rust-lang#63931
cc rust-lang#54727
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Dec 30, 2019
Stabilize attribute macros on inline modules

While still gating non-inline modules in proc macro input.

Split from rust-lang#63931
cc rust-lang#54727
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jan 6, 2020
Version 1.40.0 (2019-12-19)
===========================

Language
--------
- [You can now use tuple `struct`s and tuple `enum` variant's constructors in
  `const` contexts.][65188] e.g.

  ```rust
  pub struct Point(i32, i32);

  const ORIGIN: Point = {
      let constructor = Point;

      constructor(0, 0)
  };
  ```

- [You can now mark `struct`s, `enum`s, and `enum` variants with the `#[non_exhaustive]` attribute to
  indicate that there may be variants or fields added in the future.][64639]
  For example this requires adding a wild-card branch (`_ => {}`) to any match
  statements on a non-exhaustive `enum`. [(RFC 2008)]
- [You can now use function-like procedural macros in `extern` blocks and in
  type positions.][63931] e.g. `type Generated = macro!();`
- [Function-like and attribute procedural macros can now emit
  `macro_rules!` items, so you can now have your macros generate macros.][64035]
- [The `meta` pattern matcher in `macro_rules!` now correctly matches the modern
  attribute syntax.][63674] For example `(#[$m:meta])` now matches `#[attr]`,
  `#[attr{tokens}]`, `#[attr[tokens]]`, and `#[attr(tokens)]`.

Compiler
--------
- [Added tier 3 support\* for the
  `thumbv7neon-unknown-linux-musleabihf` target.][66103]
- [Added tier 3 support for the
  `aarch64-unknown-none-softfloat` target.][64589]
- [Added tier 3 support for the `mips64-unknown-linux-muslabi64`, and
  `mips64el-unknown-linux-muslabi64` targets.][65843]

\* Refer to Rust's [platform support page][forge-platform-support] for more
  information on Rust's tiered platform support.

Libraries
---------
- [The `is_power_of_two` method on unsigned numeric types is now a `const` function.][65092]

Stabilized APIs
---------------
- [`BTreeMap::get_key_value`]
- [`HashMap::get_key_value`]
- [`Option::as_deref_mut`]
- [`Option::as_deref`]
- [`Option::flatten`]
- [`UdpSocket::peer_addr`]
- [`f32::to_be_bytes`]
- [`f32::to_le_bytes`]
- [`f32::to_ne_bytes`]
- [`f64::to_be_bytes`]
- [`f64::to_le_bytes`]
- [`f64::to_ne_bytes`]
- [`f32::from_be_bytes`]
- [`f32::from_le_bytes`]
- [`f32::from_ne_bytes`]
- [`f64::from_be_bytes`]
- [`f64::from_le_bytes`]
- [`f64::from_ne_bytes`]
- [`mem::take`]
- [`slice::repeat`]
- [`todo!`]

Cargo
-----
- [Cargo will now always display warnings, rather than only on
  fresh builds.][cargo/7450]
- [Feature flags (except `--all-features`) passed to a virtual workspace will
  now produce an error.][cargo/7507] Previously these flags were ignored.
- [You can now publish `dev-dependencies` without including
  a `version`.][cargo/7333]

Misc
----
- [You can now specify the `#[cfg(doctest)]` attribute to include an item only
  when running documentation tests with `rustdoc`.][63803]

Compatibility Notes
-------------------
- [As previously announced, any previous NLL warnings in the 2015 edition are
  now hard errors.][64221]
- [The `include!` macro will now warn if it failed to include the
  entire file.][64284] The `include!` macro unintentionally only includes the
  first _expression_ in a file, and this can be unintuitive. This will become
  either a hard error in a future release, or the behavior may be fixed to include all expressions as expected.
- [Using `#[inline]` on function prototypes and consts now emits a warning under
  `unused_attribute` lint.][65294] Using `#[inline]` anywhere else inside traits
  or `extern` blocks now correctly emits a hard error.

[65294]: rust-lang/rust#65294
[66103]: rust-lang/rust#66103
[65843]: rust-lang/rust#65843
[65188]: rust-lang/rust#65188
[65092]: rust-lang/rust#65092
[64589]: rust-lang/rust#64589
[64639]: rust-lang/rust#64639
[64221]: rust-lang/rust#64221
[64284]: rust-lang/rust#64284
[63931]: rust-lang/rust#63931
[64035]: rust-lang/rust#64035
[63674]: rust-lang/rust#63674
[63803]: rust-lang/rust#63803
[cargo/7450]: rust-lang/cargo#7450
[cargo/7507]: rust-lang/cargo#7507
[cargo/7525]: rust-lang/cargo#7525
[cargo/7333]: rust-lang/cargo#7333
[(rfc 2008)]: https://rust-lang.github.io/rfcs/2008-non-exhaustive.html
[`f32::to_be_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_be_bytes
[`f32::to_le_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_le_bytes
[`f32::to_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_ne_bytes
[`f64::to_be_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_be_bytes
[`f64::to_le_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_le_bytes
[`f64::to_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_ne_bytes
[`f32::from_be_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_be_bytes
[`f32::from_le_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_le_bytes
[`f32::from_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_ne_bytes
[`f64::from_be_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_be_bytes
[`f64::from_le_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_le_bytes
[`f64::from_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_ne_bytes
[`option::flatten`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.flatten
[`option::as_deref`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_deref
[`option::as_deref_mut`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_deref_mut
[`hashmap::get_key_value`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.get_key_value
[`btreemap::get_key_value`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.get_key_value
[`slice::repeat`]: https://doc.rust-lang.org/std/primitive.slice.html#method.repeat
[`mem::take`]: https://doc.rust-lang.org/std/mem/fn.take.html
[`udpsocket::peer_addr`]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html#method.peer_addr
[`todo!`]: https://doc.rust-lang.org/std/macro.todo.html
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jan 14, 2020
Version 1.40.0 (2019-12-19)
===========================

Language
--------
- [You can now use tuple `struct`s and tuple `enum` variant's constructors in
  `const` contexts.][65188] e.g.

  ```rust
  pub struct Point(i32, i32);

  const ORIGIN: Point = {
      let constructor = Point;

      constructor(0, 0)
  };
  ```

- [You can now mark `struct`s, `enum`s, and `enum` variants with the `#[non_exhaustive]` attribute to
  indicate that there may be variants or fields added in the future.][64639]
  For example this requires adding a wild-card branch (`_ => {}`) to any match
  statements on a non-exhaustive `enum`. [(RFC 2008)]
- [You can now use function-like procedural macros in `extern` blocks and in
  type positions.][63931] e.g. `type Generated = macro!();`
- [Function-like and attribute procedural macros can now emit
  `macro_rules!` items, so you can now have your macros generate macros.][64035]
- [The `meta` pattern matcher in `macro_rules!` now correctly matches the modern
  attribute syntax.][63674] For example `(#[$m:meta])` now matches `#[attr]`,
  `#[attr{tokens}]`, `#[attr[tokens]]`, and `#[attr(tokens)]`.

Compiler
--------
- [Added tier 3 support\* for the
  `thumbv7neon-unknown-linux-musleabihf` target.][66103]
- [Added tier 3 support for the
  `aarch64-unknown-none-softfloat` target.][64589]
- [Added tier 3 support for the `mips64-unknown-linux-muslabi64`, and
  `mips64el-unknown-linux-muslabi64` targets.][65843]

\* Refer to Rust's [platform support page][forge-platform-support] for more
  information on Rust's tiered platform support.

Libraries
---------
- [The `is_power_of_two` method on unsigned numeric types is now a `const` function.][65092]

Stabilized APIs
---------------
- [`BTreeMap::get_key_value`]
- [`HashMap::get_key_value`]
- [`Option::as_deref_mut`]
- [`Option::as_deref`]
- [`Option::flatten`]
- [`UdpSocket::peer_addr`]
- [`f32::to_be_bytes`]
- [`f32::to_le_bytes`]
- [`f32::to_ne_bytes`]
- [`f64::to_be_bytes`]
- [`f64::to_le_bytes`]
- [`f64::to_ne_bytes`]
- [`f32::from_be_bytes`]
- [`f32::from_le_bytes`]
- [`f32::from_ne_bytes`]
- [`f64::from_be_bytes`]
- [`f64::from_le_bytes`]
- [`f64::from_ne_bytes`]
- [`mem::take`]
- [`slice::repeat`]
- [`todo!`]

Cargo
-----
- [Cargo will now always display warnings, rather than only on
  fresh builds.][cargo/7450]
- [Feature flags (except `--all-features`) passed to a virtual workspace will
  now produce an error.][cargo/7507] Previously these flags were ignored.
- [You can now publish `dev-dependencies` without including
  a `version`.][cargo/7333]

Misc
----
- [You can now specify the `#[cfg(doctest)]` attribute to include an item only
  when running documentation tests with `rustdoc`.][63803]

Compatibility Notes
-------------------
- [As previously announced, any previous NLL warnings in the 2015 edition are
  now hard errors.][64221]
- [The `include!` macro will now warn if it failed to include the
  entire file.][64284] The `include!` macro unintentionally only includes the
  first _expression_ in a file, and this can be unintuitive. This will become
  either a hard error in a future release, or the behavior may be fixed to include all expressions as expected.
- [Using `#[inline]` on function prototypes and consts now emits a warning under
  `unused_attribute` lint.][65294] Using `#[inline]` anywhere else inside traits
  or `extern` blocks now correctly emits a hard error.

[65294]: rust-lang/rust#65294
[66103]: rust-lang/rust#66103
[65843]: rust-lang/rust#65843
[65188]: rust-lang/rust#65188
[65092]: rust-lang/rust#65092
[64589]: rust-lang/rust#64589
[64639]: rust-lang/rust#64639
[64221]: rust-lang/rust#64221
[64284]: rust-lang/rust#64284
[63931]: rust-lang/rust#63931
[64035]: rust-lang/rust#64035
[63674]: rust-lang/rust#63674
[63803]: rust-lang/rust#63803
[cargo/7450]: rust-lang/cargo#7450
[cargo/7507]: rust-lang/cargo#7507
[cargo/7525]: rust-lang/cargo#7525
[cargo/7333]: rust-lang/cargo#7333
[(rfc 2008)]: https://rust-lang.github.io/rfcs/2008-non-exhaustive.html
[`f32::to_be_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_be_bytes
[`f32::to_le_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_le_bytes
[`f32::to_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_ne_bytes
[`f64::to_be_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_be_bytes
[`f64::to_le_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_le_bytes
[`f64::to_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_ne_bytes
[`f32::from_be_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_be_bytes
[`f32::from_le_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_le_bytes
[`f32::from_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_ne_bytes
[`f64::from_be_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_be_bytes
[`f64::from_le_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_le_bytes
[`f64::from_ne_bytes`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_ne_bytes
[`option::flatten`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.flatten
[`option::as_deref`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_deref
[`option::as_deref_mut`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_deref_mut
[`hashmap::get_key_value`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.get_key_value
[`btreemap::get_key_value`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.get_key_value
[`slice::repeat`]: https://doc.rust-lang.org/std/primitive.slice.html#method.repeat
[`mem::take`]: https://doc.rust-lang.org/std/mem/fn.take.html
[`udpsocket::peer_addr`]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html#method.peer_addr
[`todo!`]: https://doc.rust-lang.org/std/macro.todo.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.