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

Add f16 and f128 float types #3453

Merged
merged 6 commits into from
Oct 18, 2023

Conversation

aaronfranke
Copy link
Contributor

@aaronfranke aaronfranke commented Jul 2, 2023

Rendered

See the discussion leading up to this RFC in issue #2629, and see the RFC for further floating point types at #3456. This RFC is mostly a subset of what was originally proposed in #3451, and was split off to provide an easier path to consensus for types that don't have as many debatable implementation aspects.

Tracking issue: rust-lang/rust#116909


Editor: Link to FCP proposal: #3453 (comment)

text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
text/3453-f16-and-f128.md Show resolved Hide resolved
text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
@tgross35
Copy link
Contributor

tgross35 commented Jul 2, 2023

Fwiw this table describing platform support should be more or less accurate now (thanks to all the platform experts who helped out). https://hackmd.io/@8W5l8q6-Qyyn_vKh2-L0RQ/rJpZsmcdh. Maybe worth pulling the f128 and f16 columns into this RFC?

Would you consider including c_longdouble in this proposal for platforms where it is unambiguously f64 or f128? That includes all but four rows in the table (unfortunately x86 is a huge one, but I don't think that precludes introducing the type).

@ehuss ehuss added the T-lang Relevant to the language team, which will review and decide on the RFC. label Jul 2, 2023
@clarfonthey
Copy link
Contributor

Would you consider including c_longdouble in this proposal for platforms where it is unambiguously f64 or f128? That includes all but four rows in the table (unfortunately x86 is a huge one, but I don't think that precludes introducing the type).

IMHO, c_longdouble is not useful if it has to be gated by platform. If you're already required to limit the platforms you use the alias for, why not just use the exact type you already know it is on those platforms?

@aaronfranke
Copy link
Contributor Author

Would you consider including c_longdouble in this proposal for platforms where it is unambiguously f64 or f128?

@tgross35 No, c_longdouble is out of scope for this RFC. This RFC is only concerned with IEEE 754 compliant types. Types for interoperability with other languages can be added after this RFC is implemented. See #3451.

This RFC only mentions other languages as justification for the Rust types and to help implementers align the types with the existing work done on IEEE 754-compliant types in LLVM/C/C++/GCC, not just any type in those languages.

@tgross35
Copy link
Contributor

tgross35 commented Jul 2, 2023

@tgross35 No, c_longdouble is out of scope for this RFC. This RFC is only concerned with IEEE 754 compliant types. Types for interoperability with other languages can be added after this RFC is implemented. See #3451.

Fair enough; in the meantime I reserved the crate name longdouble to provide bindings whever this lands, in case there is a delay.

text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
- Rename doubledouble to f64f64
- Add architecture info about x86 and arm (as suggested)
- Add description to target related types (as suggested)
- Add link to IEEE-754 and LLVM LangRef
@djc
Copy link
Contributor

djc commented Jul 6, 2023

Just got here via This Week in Rust: it's really unclear to me how #3451 and #3453 are related. Is #3453 a newer instance of #3451 that restricts the set of types to be added? If so, should #3451 be closed? I think it would be useful to clarify this relation in the first comment to make it explicit for readers.

@aaronfranke
Copy link
Contributor Author

@djc The intention is to proceed with #3453 first, since f16 and f128 are much more likely to be accepted than architecture-specific types. This means we can kick the decisions on the other types in #3451 down the road. There is no specific need to close #3451, it can be kept open, but I am not against closing it either.

@djc
Copy link
Contributor

djc commented Jul 6, 2023

Okay, maybe clarify this in the initial posts for both PRs?

@tgross35
Copy link
Contributor

tgross35 commented Jul 7, 2023

A few last things I can think of that might be worth considering (including some nits):

  • Where will the soft float implementation come from? Even if we use the same source as for f32 and f64, it is worth calling that out. I think the current ones come from LLVM, but there are some other implementations (e.g. Berkely)

  • In "Future Possibilities", I'd expressly list what the other possible types are (bf16, x86_fp80, ppc_fp128, c_longdouble) rather than punting to the other RFC's link, since that RFC may change with time

  • On that note, say why these other types were not included in this RFC in the "Rationale & Alternatives" section

  • Could be worth saying that a MVP would just be providing softfloat for everything, and after that has been implemented we can go through and hardware accelerate targets that provide special support ("Implementation Plan" could be a new section under "Reference-level Explanation" if there's a lot to say about this)

  • A future possibility might be adding feature gates for whether or not hardware accelerates specific types

  • I think SIMD and GPUs seem to use bf16 more than f16, but is there anything under those two topics that having these types would unblock? Or any crates that would like to use these types? (@cwfitzgerald I believe you are the maintainer of wgpu, any comments here?)

  • Maybe say if there's anything we need to do for targets that support types as a storage format but have no other hardware acceleration. E.g. mips-*-gnu with MSA has specific instructions for f16 but doesn't support it in FPU (see this ref in the table)

  • s390x-*-gnu supports hardware f128

  • The issue description says:

    See also Suggestions for additional floating-point types #2629 and Additional float types #3451. This PR should be implemented in advance of Additional float types #3451, so we can kick Additional float types #3451 down the road.

    maybe something along these lines, to give a bit more context at a quick glance:

    See the discussion leading up to this RFC in issue Suggestions for additional floating-point types #2629, and see the RFC for further floating point types at Additional float types #3451. This RFC is a subset of what was originally proposed in Additional float types #3451, and was split off to provide an easier path to consensus for types that don't have as many debatable implementation aspects.

Other than that, I think somebody from the lang team will need to say what changes might be necessary before it can be nomincated for discussion. (Maybe @scottmcm? I think you are the resident expert on hardware-level types)

@aaronfranke
Copy link
Contributor Author

In "Future Possibilities", I'd expressly list what the other possible types are

I think that's out-of-scope for this RFC, even in that section. It should be sufficient to say that more exist.

On that note, say why these other types were not included in this RFC in the "Rationale & Alternatives" section

The RFC text already explicitly describes why. The types f16 and f128 are IEEE 754 while the others are not. The document mentions the text "IEEE 754" ten times.

@tgross35
Copy link
Contributor

tgross35 commented Jul 7, 2023

On that note, say why these other types were not included in this RFC in the "Rationale & Alternatives" section

The RFC text already explicitly describes why. The types f16 and f128 are IEEE 754 while the others are not. The document mentions the text "IEEE 754" ten times.

"Motivation" currently mentions that this RFC does not cover those types, but no reason is given. I meant to give an explicit note saying that it was considered and decided against (just to provide an easier path for more straightforward types) - i.e., the "Rationale" for why this RFC was split at all. Mentioning 754 is good to give scope, but RFCs also need to explain why their scope was chosen, and document the decision-making process that got there.

@tgross35
Copy link
Contributor

tgross35 commented Jul 7, 2023

Some other RFCs to maybe crosslink or take from:

  • int128 (adds i128/u128) it would be good to pull in the "runtime library support" section, and to reference this in "prior art" as an example of when we last added a new numeric primitive
  • float_next_up_down since this is still unstable, I would maybe call it out as an exception to "All operators, constants, and math functions defined for f32 and f64 in core, must also be defined for f16 and f128 in core". Sufficient to say it's not required for MVP but should be addressed if that feature starts heading to stabilization

@cwfitzgerald
Copy link

Re: GPU Graphics

GPUs are basically entirely ieee for all of their floats. We do have f16s on the gpu so a project like rust-gpu (which runs rust on the gpu) would be able to use native support for f16 to generate code using f16 on the gpu. Metal seems to be the only one that supports bf16 (in addition to f16) in modern graphics focused GPU apis and this was a very recent addition, I believe with the M2. CUDA supports both bf16 and f16 as well.

Having a native f16 type would certainly make uploading/reading f16s more convenient but it's not something that we need on the cpu.

@aaronfranke

This comment was marked as resolved.

@pvdrz
Copy link

pvdrz commented Jul 8, 2023

I think this would be good for bindgen as some people had requested support for f16 but the lack of a type in the standard library is a bit of a setback

@clarfonthey
Copy link
Contributor

clarfonthey commented Jul 9, 2023

Having a native f16 type would certainly make uploading/reading f16s more convenient but it's not something that we need on the cpu.

Honestly, this is one of the big reasons why I advocated for the inclusion of these to be unconditional, since it means just about any crate can implement traits for these types without having to worry about where it's being used, and stuff like Rust-GPU can just make use of that because it's available. If you had to conditionally include these types every time they were used it would be a big hassle and then native users might not be able to use it as often.

Binary crates basically don't care about the conditional inclusion since they've already only built for the targets they care about, whereas library crates care a lot about it since they have no idea who's going to be using their crates. I've seen and written code full of spaghetti #[cfg]s and it really makes it feel harder to justify the flexibility. Which is why it's so important to just have the standard library shoulder that burden, and optimise the support for those who need it.

@kpreid
Copy link
Contributor

kpreid commented Aug 31, 2023

The reason I suggest addressing code size via a separate filter mechanism is that every possibly-absent language feature or core item becomes additional pain for every library developer wanting to write a portable library (and it's easy to accidentally write cfgs wrong such that the library won't compile on some targets), and f128 in particular is likely to be often mentioned in a “implement this trait for it” way rather than a required way, which is harmless since it only takes effect if other code mentions f128.

@RalfJung
Copy link
Member

RalfJung commented Aug 31, 2023

Atomics can't effectively be emulated, whereas f128 and f16 can be implemented with softfloats.

That's not entirely true, C++ will use lock-based fallbacks for atomics on targets that don't have hardware support. Rust decided not to do that and just doesn't provide the Atomic* types on those targets.

I get that people want to opt-out of softfloats, but given that we already have targets with softfloats for f32/f64, I do feel like making that work is a separate RFC to this one. f16/f128 should then just pick up the same approach.

@programmerjake
Copy link
Member

Atomics can't effectively be emulated, whereas f128 and f16 can be implemented with softfloats.

That's not entirely true, C++ will use lock-based fallbacks for atomics on targets that don't have hardware support.

those aren't lock-free so I consider them to not be effective.

@tgross35
Copy link
Contributor

I think it could make sense to add #[cfg(target_has_fp = "x")] for all float sizes to allow configuring off of that (for tier1 targets I believe this is only z/Arch and some PPC and RiscV flavors)

The case of a library using f128 when a library user would rather not isn't entirely convincing to me. I could see this as something that the crate would provide a precision-f128 feature for, but this doesn't seem all that different to me than any other time a library provides potentially slow code. And I would not expect libraries to use f128 in the first place without good reason for needing the precision anyway.

To me, the bigger concern is related to binary size. Some growth in core's size is expected and it remains to be seen how signifcant this is, but it sounds like there are also cases where unused floating point code is not pruned from the final binary. Are there more details as to when this happens, or examples?

I am also curious how C/C++ does __float128 / std::float128_t / _Float128, if they have some specific approach we could learn from.

@nbdd0121
Copy link

nbdd0121 commented Aug 31, 2023

In C++ these types are optional and can be tested using feature test macros __STDCPP_FLOAT16_T/__STDCPP_BFLOAT16_T/__STDCPP_FLOAT128_T.

Quote from https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html#test-macros:

Since implementations may choose to support (or not) each of the fixed-layout aliases individually, there is a separate test macro for each of the type aliases. The names of the test macros are derived from the names of type alias names. These macros are different from all other library feature test macros in that they are conditionally supported. They don’t indicate that the implementation has implemented this proposal; instead they indicate that the type in question is available in this implementation. Therefore, they are not listed in the library feature test macros ([version.syn]), or in the language feature test macros, but in the list of conditionally predefined macros at the end of [cpp.predefined]. They are in the language section of the standard because they indicate the availability of a fundamental type in the language (even though the name of that type is not a keyword but is defined in the library).

The names of the proposed macros are:

  • __STDCPP_FLOAT16_T__
  • __STDCPP_FLOAT32_T__
  • __STDCPP_FLOAT64_T__
  • __STDCPP_FLOAT128_T__
  • __STDCPP_BFLOAT16_T__

@tmandry
Copy link
Member

tmandry commented Aug 31, 2023

I get that people want to opt-out of softfloats, but given that we already have targets with softfloats for f32/f64, I do feel like making that work is a separate RFC to this one. f16/f128 should then just pick up the same approach.

I agree with this comment. The situation with floating point is arguably not ideal, but that doesn't need to stop us from adding additional useful types.

@rfcbot reviewed

The thing I would most like to see in the RFC is a summary of which targets, particularly Tier 1 if any, would need softfloat implementations.

@aaronfranke
Copy link
Contributor Author

aaronfranke commented Aug 31, 2023

@tmandry This RFC already lists hardware targets that have hardware f16 and f128 support, I believe it should be sufficient to say that "everything else" needs software float if it does not have hardware float. The text "Most platforms do not have hardware support and therefore will need to use a software implementation." is a part of the RFC already.

@tgross35
Copy link
Contributor

In C++ these types are optional and can be tested using feature test macros __STDCPP_FLOAT16_T/__STDCPP_BFLOAT16_T/__STDCPP_FLOAT128_T.

Quote from https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html#test-macros:

[...]

  • __STDCPP_FLOAT16_T__
  • __STDCPP_FLOAT32_T__
  • __STDCPP_FLOAT64_T__
  • __STDCPP_FLOAT128_T__
  • __STDCPP_BFLOAT16_T__

Any clue how __float128 is currently handled? It seems to always be available on both clang and GCC https://gcc.godbolt.org/z/PncsrY31P. I am also having a hard time figuring out the behavior of those gates, even float32 and float64 don't seem to ever be set.

I know that wanting to forbid softfloat is a concern, but can you clarify the size concern? I am not sure if it is just the size of core or if there is more to the story - can you link some examples/context here if so

@tmandry
Copy link
Member

tmandry commented Aug 31, 2023

Performance cliffs and documentation

Taking a closer look at the RFC, it sounds like most Tier 1 platforms don't support hardware acceleration of these types. That does qualitatively change how I view the RFC. Right now if you're targeting Tier 1 platforms you can grab any of the builtin float types and not think too hard about it, whereas after this RFC you'll have to reason about which ones are hardware accelerated.

Does a user's behavior actually change based on this information? The counterargument would be "either you want the added precision or you don't; you should figure that out and, if you care about performance, you should also run benchmarks." That said, not everyone has time to do all the things they "should" do, and knowing where the performance cliffs lie is a very useful shortcut.

I think we can solve the performance question with clear documentation on which platforms support acceleration, and would like to see that before stabilizing these types. Currently the docs on primitive number types don't seem to say anything about this.

Motivation

I also think this raises the bar in terms of motivation. The RFC presents a pretty good motivation, but it would be even better if it contained a list of actual cases where the lack of these types in the standard libraries was a hurdle to users (e.g. #3453 (comment)).

The argument that it makes it more convenient to format floats in a binary format (e.g. for GPUs) is a good one, but it raises questions about whether we should support other types like bf16. Saying that we are starting with IEEE754 types is okay in that it gives a simple story to tell, but in terms of motivation it ultimately falls flat in my view. I think it would be much more compelling to show evidence that these types are more commonly used than alternatives (and/or that the alternatives like 80-bit are problematic for other reasons).

@ecnelises
Copy link
Contributor

Any clue how __float128 is currently handled? It seems to always be available on both clang and GCC https://gcc.godbolt.org/z/PncsrY31P. I am also having a hard time figuring out the behavior of those gates, even float32 and float64 don't seem to ever be set.

It really depends on the target (not only arch, but also OS and ABI): x86_64-pc-linux-gnu supports __float128, but x86_64-pc-windows-msvc does not. And on PowerPC, -mfloat128 option is needed (which implies vsx), and only available on little-endian targets.

GCC seems to support float128 on more targets (aarch64-apple-darwin for example), but I don't think either Clang or GCC has a gate to enable it for all. In LLVM, not every arch implements fp128 values (some ABI stuff for 128-bit value is necessary, I guess).

@clarfonthey
Copy link
Contributor

clarfonthey commented Sep 2, 2023

Since I was curious about how exactly this would work, I decided to take a look at how existing floating point maths is emitted on a riscvi target, i.e. one with no float instructions.

The result is, it always emits a function call to the relevant embedded ABI function: godbolt link

So, you're right that code bloat is a concern, if these are always included in the resulting binary and LTO is never done. Which, I'm not sure.

While there's certainly a lot of work to be done on this, it's clear that a lot of people not using these floats in embedded circumstances (or others where binary size is relevant) have already figured out how to get around these restrictions, likely by ensuring that LTO is always performed. So, while there's always room for improvement there, it's worth mentioning that this doesn't really change the problem, and I don't think that constantly avoiding new things that might add extra code is a very sustainable practice, and we should instead focus more heavily on ensuring that in cases like these the unused functions are never added to the resulting binary, either because they're linked in an external library or because they're just part of a special LTO that always gets performed.

@Amanieu
Copy link
Member

Amanieu commented Sep 10, 2023

You don't even need LTO. Normal linker operation will only include symbols from static libraries (such as libcompiler_builtins.rlib) that are actually referenced.

@rfcbot rfcbot added final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. and removed proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. labels Sep 27, 2023
@rfcbot
Copy link
Collaborator

rfcbot commented Sep 27, 2023

🔔 This is now entering its final comment period, as per the review above. 🔔

Copy link
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

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

Since this in FCP, the main content is agreed upon However, there were some things that came up during the design meeting that should be addressed before merge, mostly about motivation.

I added notes from the meeting plus a handful of polish things to help get this ready for merge.

text/3453-f16-and-f128.md Show resolved Hide resolved
text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
# Motivation
[motivation]: #motivation

The IEEE 754 standard defines many binary floating point formats. The most common of these types are the binary32 and binary64 formats, available in Rust as `f32` and `f64`. However, other formats are useful in various uncommon scenarios. The binary16 format is useful for situations where storage compactness is important and low precision is acceptable, such as HDR images, mesh quantization, and AI neural networks.[^1] The binary128 format is useful for situations where high precision is needed, such as scientific computing contexts.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The IEEE 754 standard defines many binary floating point formats. The most common of these types are the binary32 and binary64 formats, available in Rust as `f32` and `f64`. However, other formats are useful in various uncommon scenarios. The binary16 format is useful for situations where storage compactness is important and low precision is acceptable, such as HDR images, mesh quantization, and AI neural networks.[^1] The binary128 format is useful for situations where high precision is needed, such as scientific computing contexts.
The IEEE 754 standard defines many binary floating point formats. The most common of these types are the binary32 and binary64 formats, available in Rust as `f32` and `f64`. However, other formats are useful in various scenarios. The binary16 format is useful for situations where storage compactness is important and low precision is acceptable, such as HDR images, mesh quantization, and AI neural networks.[^1] The binary128 format is useful for situations where high precision is needed, such as scientific computing contexts.

I wouldn't call these scenarios uncommon since we are advocating for supporting them 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it would be dishonest to not say they are uncommon. 99% of use cases don't need 16-bit or 128-bit floats (thus, the reason most languages have been fine without them so far). But also, most use cases don't need 32-bit floats either (thus, the reason many languages like JavaScript and Python have their only float type as 64-bit). Our argument advocating for supporting these formats is that the 1% of use cases greatly benefit from language support and that this deserves to be a core feature in the Rust language, just like 32-bit floats.

Copy link
Contributor

@tgross35 tgross35 Oct 7, 2023

Choose a reason for hiding this comment

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

Maybe "less common" then? Doesn't really matter since it's passed RFC, uncommon just sounds a bit more like we maybe shouldn't be supporting it

text/3453-f16-and-f128.md Show resolved Hide resolved
Comment on lines +125 to +127
The main unresolved parts of this RFC are the implementation details in the context of the Rust compiler and standard library. The behavior of `f16` and `f128` is well-defined by the IEEE 754 standard, and is not up for debate. Whether these types should be included in the language is the main question of this RFC, which will be resolved when this RFC is accepted.

Several future questions are intentionally left unresolved, and should be handled by another RFC. This RFC does not have the goal of covering the entire IEEE 754 standard, since it does not include `f256` and the decimal-float types. This RFC also does not have the goal of adding existing platform-specific float types such as x86's 80-bit double-extended-precision.
Copy link
Contributor

Choose a reason for hiding this comment

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

We have come to consensus that this RFC will only support f16 and f128, so all these unresolved questions can be removed.

Unresolved question to add: based on @scottmcm's comment #3453 (comment), I don't know if we will be able to support f128 parsing at first. It requires changes within our float parsing library that we wouldn't want to do if there is any notable impact, so just note this as to be determined

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, it's resolved in that it's not the goal of this RFC to add those features, but it's still unresolved in terms of what will be done in the future.

As for f128 parsing, that seems like an implementation detail that needs to be figured out by the implementers to ensure we support f128 parsing. I don't think it's meaningful for this RFC to say "we don't need f128 parsing", if it's missing for now that's fine, but long-term I don't see a reason to not have it.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that since they other float types are covered in Future Possibilities they don't need to be here. Usually Unresolved Questions are the things that need to be figured out between the RFC being accepted and the feature being stabilized, Future Possibilities are out of scope things that could go in other RFCs. (I know the template has out of scope things in both, but I don't see any accepted RFCs that actually put them under unresolved questions)

text/3453-f16-and-f128.md Show resolved Hide resolved
text/3453-f16-and-f128.md Outdated Show resolved Hide resolved
text/3453-f16-and-f128.md Outdated Show resolved Hide resolved

Both this RFC and RFC 3451 are built upon the discussion in [issue 2629](https://github.com/rust-lang/rfcs/issues/2629).

The main consensus of the discussion thus far is that more float types would be useful, especially the IEEE 754 types proposed in this RFC as `f16` and `f128`. Other types can be discussed in a future RFC.
Copy link
Contributor

Choose a reason for hiding this comment

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

Move this to "rationale and alternatives", say a bit more about why f80/doubledouble were rejected as part of this RFC (because we want to support the most standard type)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know if it's worth restating the details of float types not a part of this RFC. It should be sufficient to say in this section that there are other types, and list a few in "Future possibilities".

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a one sentence statement at the end of future possibilities "These types were not included as part of this RFC since their implementation is more open to interpretation, this RFC focuses on well-defined types". Just as a hint to anyone reading this in a few years why we didn't include those types (in the case that the other RFC doesn't go forward).

But, I'm indifferent

text/3453-f16-and-f128.md Show resolved Hide resolved
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this RFC. to-announce and removed final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. labels Oct 7, 2023
@rfcbot
Copy link
Collaborator

rfcbot commented Oct 7, 2023

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.

This will be merged soon.

Co-authored-by: Trevor Gross <[email protected]>
@pvdrz
Copy link

pvdrz commented Oct 10, 2023

Thanks for putting the effort on pushing this :)

@traviscross
Copy link
Contributor

This RFC has been merged, and we've opened a tracking issue: rust-lang/rust#116909

Thanks go out to the authors of this RFC for making Rust better by drafting it and pushing it through to acceptance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this RFC. T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC. to-announce
Projects
None yet
Development

Successfully merging this pull request may close these issues.