Question: <ins> # `wasm32-unknown-unknown` **Tier: 2** The `wasm32-unknown-unknown` target is a WebAssembly compilation target which does not import any functions from the host for the standard library. This is the "minimal" WebAssembly in the sense of making the fewest assumptions about the host environment. This target is often used when compiling to the web or JavaScript environments as there is no standard for what functions can be imported on the web. This target can also be useful for creating minimal or bare-bones WebAssembly binaries. The `wasm32-unknown-unknown` target has support for the Rust standard library but many parts of the standard library do not work and return errors. For example `println!` does nothing, `std::fs` always return errors, and `std::thread::spawn` will panic. There is no means by which this can be overridden. For a WebAssembly target that more fully supports the standard library see the [`wasm32-wasip1`](./wasm32-wasip1.md) or [`wasm32-wasip2`](./wasm32-wasip2.md) targets. The `wasm32-unknown-unknown` target has full support for the `core` and `alloc` crates. It additionally supports the `HashMap` type in the `std` crate, although hash maps are not randomized like they are on other platforms. One existing user of this target (please feel free to edit and expand this list too) is the [`wasm-bindgen` project](https://github.com/rustwasm/wasm-bindgen) which facilitates Rust code interoperating with JavaScript code. Note, though, that not all uses of `wasm32-unknown-unknown` are using JavaScript and the web. ## Target maintainers When this target was added to the compiler platform-specific documentation here was not maintained at that time. This means that the list below is not exhaustive and there are more interested parties in this target. That being said since when this document was last updated those interested in maintaining this target are: - Alex Crichton, https://github.com/alexcrichton ## Requirements This target is cross-compiled. The target includes support for `std` itself, but as mentioned above many pieces of functionality that require an operating system do not work and will return errors. This target currently has no equivalent in C/C++. There is no C/C++ toolchain for this target. While interop is theoretically possible it's recommended to instead use one of: * `wasm32-unknown-emscripten` - for web-based use cases the Emscripten toolchain is typically chosen for running C/C++. * [`wasm32-wasip1`](./wasm32-wasip1.md) - the wasi-sdk toolchain is used to compile C/C++ on this target and can interop with Rust code. WASI works on the web so far as there's no blocker, but an implementation of WASI APIs must be either chosen or reimplemented. This target has no build requirements beyond what's in-tree in the Rust repository. Linking binaries requires LLD to be enabled for the `wasm-ld` driver. This target uses the `dlmalloc` crate as the default global allocator. ## Building the target Building this target can be done by: * Configure the `wasm32-unknown-unknown` target to get built. * Configure LLD to be built. * Ensure the `WebAssembly` target backend is not disabled in LLVM. These are all controlled through `config.toml` options. It should be possible to build this target on any platform. ## Building Rust programs Rust programs can be compiled by adding this target via rustup: ```sh $ rustup target add wasm32-unknown-unknown ``` and then compiling with the target: ```sh $ rustc foo.rs --target wasm32-unknown-unknown $ file foo.wasm ``` ## Cross-compilation This target can be cross-compiled from any host. ## Testing This target is not tested in CI for the rust-lang/rust repository. Many tests must be disabled to run on this target and failures are non-obvious because `println!` doesn't work in the standard library. It's recommended to test the `wasm32-wasip1` target instead for WebAssembly compatibility. ## Conditionally compiling code It's recommended to conditionally compile code for this target with: ```text #[cfg(all(target_family = "wasm", target_os = "unknown"))] ``` Note that there is no way to tell via `#[cfg]` whether code will be running on the web or not. ## Enabled WebAssembly features WebAssembly is an evolving standard which adds new features such as new instructions over time. This target's default set of supported WebAssembly features will additionally change over time. The `wasm32-unknown-unknown` target inherits the default settings of LLVM which typically matches the default settings of Emscripten as well. Changes to WebAssembly go through a [proposals process][proposals] but reaching the final stage (stage 5) does not automatically mean that the feature will be enabled in LLVM and Rust by default. At this time the general guidance is that features must be present in most engines for a "good chunk of time" before they're enabled in LLVM by default. There is currently no exact number of months or engines that are required to enable features by default. [proposals]: https://github.com/WebAssembly/proposals As of the time of this writing the proposals that are enabled by default (the `generic` CPU in LLVM terminology) are: * `multivalue` * `mutable-globals` * `reference-types` * `sign-ext` If you're compiling WebAssembly code for an engine that does not support a feature in LLVM's default feature set then the feature must be disabled at compile time. Note, though, that enabled features may be used in the standard library or precompiled libraries shipped via rustup. This means that not only does your own code need to be compiled with the correct set of flags but the Rust standard library additionally must be recompiled. Compiling all code for the initial release of WebAssembly looks like: ```sh $ export RUSTFLAGS=-Ctarget-cpu=mvp $ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown ``` Here the `mvp` "cpu" is a placeholder in LLVM for disabling all supported features by default. Cargo's `-Zbuild-std` feature, a Nightly Rust feature, is then used to recompile the standard library in addition to your own code. This will produce a binary that uses only the original WebAssembly features by default and no proposals since its inception. To enable individual features it can be done with `-Ctarget-feature=+foo`. Available features for Rust code itself are documented in the [reference] and can also be found through: ```sh $ rustc -Ctarget-feature=help --target wasm32-unknown-unknown ``` You'll need to consult your WebAssembly engine's documentation to learn more about the supported WebAssembly features the engine has. [reference]: https://doc.rust-lang.org/reference/attributes/codegen.html#wasm32-or-wasm64 Note that it is still possible for Rust crates and libraries to enable WebAssembly features on a per-function level. This means that the build command above may not be sufficient to disable all WebAssembly features. If the final binary still has SIMD instructions, for example, the function in question will need to be found and the crate in question will likely contain something like: ```rust,ignore (not-always-compiled-to-wasm) #[target_feature(enable = "simd128")] fn foo() { // ... } ``` In this situation there is no compiler flag to disable emission of SIMD instructions and the crate must instead be modified to not include this function at compile time either by default or through a Cargo feature. For crate authors it's recommended to avoid `#[target_feature(enable = "...")]` except where necessary and instead use: ```rust,ignore (not-always-compiled-to-wasm) #[cfg(target_feature = "simd128")] fn foo() { // ... } ``` That is to say instead of enabling target features it's recommended to conditionally compile code instead. This is notably different to the way native platforms such as x86_64 work, and this is due to the fact that WebAssembly binaries must only contain code the engine understands. Native binaries work so long as the CPU doesn't execute unknown code dynamically at runtime. </ins>

Other solutions in this issue such as using or that in conjunction with or others don't work for one reason or another. Using the target-cpu, however, plus recompiling the standard library with , does work.


Question: ascription: thir::Ascription { variance, user_ty, user_ty_span }, } => { // Apply the type ascription to the value at `match_pair.place`, which is the <del> candidate.ascriptions.push(Ascription { span: user_ty_span, user_ty, source: match_pair.place.clone().into_place(self.tcx, self.typeck_results), variance, }); </del> <ins> if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results) { candidate.ascriptions.push(Ascription { span: user_ty_span, user_ty, source: place_resolved.into_place(self.tcx, self.typeck_results), variance, }); } </ins> candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern));

Encountered an ICE when building  0.18.0 on edition 2021. I have roughly narrowed it down to the following (can probably be reduced further). Seems to be an issue with closure captures. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</detailscc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
The code can be further simplified to: The issue seems to be around using type annotation. If a type annotation is included, the right hand side of the let statement should always be read.
Is there a runtime check/ is MIR generated for checking if is valid? Because if that's the case then we need props2 to be caputred.
claim I should have a fix later tonight
We found another instance of this ICE that still fails with included: Found trying to migrate . Let me know if you need any more information.


Question: /// assert_eq!(*guard, 1); /// ``` #[inline] <del> #[unstable(feature = "mutex_unpoison", issue = "96469")] </del> <ins> #[stable(feature = "mutex_unpoison", since = "CURRENT_RUSTC_VERSION")] </ins> pub fn clear_poison(&self) { self.poison.clear(); }

Feature gate: This is a tracking issue for functions to clear the poisoned flag on and . [x] [x] Implementation: [x] Final comment period (FCP) [ ] Stabilization PR <!-- Once the feature has gone through a few release cycles and there are no unresolved questions left, the feature might be ready for stabilization. If this feature didn't go through the RFC process, a final comment period (FCP) is always needed before stabilization. This works as follows: A library API team member can kick off the stabilization process, at which point the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final comment period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in that period of 10 days, a stabilzation PR can be opened by anyone. --<!-- Include any open questions that need to be answered before the feature can be stabilised. If multiple (unrelated) big questions come up, it can be a good idea to open a separate issue for each, to make it easier to keep track of the discussions. It's useful to link any relevant discussions and conclusions (whether on GitHub, Zulip, or the internals forum) here. --- None yet.
Hi, I read (wich got automatically closed by the way) and the PR It seems all good. What is the next step to make it in the stable API ? Can I help somehow ?
Hi, sorry if flooding but are there any updates regarding this issue?
I think the next step is one of the rust developers needs to start the final comment period. IDK what the criteria for doing so are.
fcp merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [ ] [x] [x] [ ] [x] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
I was wondering whether the idea of had been considered and found that addressed it. SGTM!


Question: /// assert_eq!(*guard, 1); /// ``` #[inline] <del> #[unstable(feature = "mutex_unpoison", issue = "96469")] </del> <ins> #[stable(feature = "mutex_unpoison", since = "CURRENT_RUSTC_VERSION")] </ins> pub fn clear_poison(&self) { self.poison.clear(); }

:bell: This is now entering its final comment period, as per the . :bell:
Given the state change this method causes, I am curious about rationale behind using vs ?
If it took , it wouldn't be possible to unpoison a mutex shared between threads despite that being the main case where poisoning can happen.
I just want to add that probably before stabilizing this method we should implement a lint which catches invalid patterns of using these methods since it is very easy to misuse. Or, at the very least, include information about potential footgun in documentation for these methods.
What kind of lint do you exactly want? What are the patterns in question that you are worried about?
The final comment period, with a disposition to merge, as per the , 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.
exactly the possible error outlined by Mara Bos: calling before acquiring a lock. The only way this usage is correct is when no other thread can act on mutex - either because they don't exist or because they are all blocked on something else. I believe that these situations are rare enough to flag such a pattern as at least suspicious.
If unpoison was a method of PoisonError or of MutexGuard instead of mutex, would it prevent such problems?
That was discussed here:


Question: }; append_arg(&mut cmd, arg, quote)?; } <ins> if is_batch_file { cmd.push(b'"' as u16); } </ins> return Ok(cmd); fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, quote: Quote) -> io::Result<()> {

I tried this code: I expected to see this happen: Instead, this happened: This is caused by different quote handling. The first (correct) command line for the spawned process (as observed by ) is: The broken one is: The command for must be in additional set of quotes, as the first and last one are stripped. It works when there are no spaces in the arguments due to the exception rule, see Stable. It worked up until nightly-2021-11-20 nightly-2021-11-21 modify labels: +regression-from-stable-to-nightly -regression-untriaged
This is caused by Rust now handling finding the exe to run itself (for security reasons). The fix here would be. as you say, to detect or extensions and add the extra quotes. The underlying function call here is . As the documentation says, this can only be used to run files. However, an undocumented feature of is that it will do this for us if given a or file. Previously we used to leave the argument blank and let it guess the right application from the argument. So apparently it would fill in for the application name and add plus the extra quotes to . But now that we do fill in the ourselves, it will still change to and add to but evidentially doesn't add the extra quotes. Thus we need to do this ourselves.
That seems reasonable; could you or someone on the Windows team submit a PR adding the requisite quoting (since quoting is hard to get right)?
Oops, sorry! I had a PR lined up but forgot to submit.


Question: <ins> // check-pass #![feature(type_alias_impl_trait)] pub trait Trait { type A; fn f() -> Self::A; } pub trait Tr2<'a, 'b> {} pub struct A<T>(T); pub trait Tr { type B; } impl<'a, 'b, T: Tr<B = dyn Tr2<'a, 'b>>> Trait for A<T> { type A = impl core::fmt::Debug; fn f() -> Self::A {} } fn main() {} </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Playground stable: Playground nightly: Somewhat similar to Edit: Actually, it's identical except this is with two lifetimes. Edit 2: And this one crashes stable, while the other does not. Also crashes without enabling features, and complains that However, constraining removes this error, but not the crash. Two lifetimes are required for the crash. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Also crashes on Rust Playground with stable <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
glacier ""
Seems related to
No longer ICEs since


Question: name: Symbol, ) -> Result<Self, &'static str> { // FIXME: use direct symbol comparison for register names <del> name.with(|name| { Ok(match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { Self::X86(X86InlineAsmReg::parse(arch, has_feature, name)?) } InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, name)?), InlineAsmArch::AArch64 => { Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, name)?) } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, name)?) } }) </del> <ins> // Use `Symbol::as_str` instead of `Symbol::with` here because `has_feature` may access `Symbol`. let name = name.as_str(); Ok(match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { Self::X86(X86InlineAsmReg::parse(arch, has_feature, &name)?) } InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, &name)?), InlineAsmArch::AArch64 => { Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, &name)?) } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, &name)?) } </ins> }) }

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
modify labels to +A-inline-assembly +F-asm +requires-nightly +O-riscv
Interestingly this does not reproduce when change register names to x86 ones; a error will be generated correctly.
I think I've located the issue. claim
claim


Question: } } <ins> // FIXME: This has the same issue as #108544, but since this isn't breaking // existing code, I'm not particularly inclined to do the same hack as above // where we process wf obligations manually. This can be fixed in a forward- // compatible way later. let collected_types = collector.types; for (_, &(ty, _)) in &collected_types { ocx.register_obligation(traits::Obligation::new( tcx, misc_cause.clone(), param_env, ty::ClauseKind::WellFormed(ty.into()), )); } </ins> // Check that all obligations are satisfied by the implementation's // RPITs. let errors = ocx.select_all_or_error();

This is a use-after-free that compiles with 1.74.0-nightly (2023-09-13 ): cc


Question: self.suggest_derive(err, &preds); } <del> fn suggest_derive( </del> <ins> pub fn suggest_derive( </ins> &self, err: &mut Diagnostic, unsatisfied_predicates: &[(

This gives the very unintuitive error: You expect to return , i.e. a . It mysteriously returns an instead. Because has a clone impl, it too, can be cloned (really, copied), returning a reference of the same lifetime. This is an operation you rarely want to do explicitly, except when dealing with generics. This error can crop up when you've forgotten to implement on , and have a reference (which could have been silently inserted using , as in the code above). However, it's not very obvious what's happening here. It can also crop up We should hint that itself isn't cloneable and thus we fell back to cloning here. This could be a lint on hitting the clone impl for references, but lints run too late. I'm not sure how this can be implemented, since we need to see the source of a value and that's a bit tricky.
cc
Interesting. This does seem like it would require some pretty special-case code to achieve, but I agree it'd be a nice case to capture.
A relatively easy way to catch most instances of this is to Pick up the expression which has a type error like this If it is a method call, check if that method call is a clone() call resolving to If it is a variable, find the variable's def If the def is a local def, look at the init expr, check if it's a bad clone This will miss things, but I think the majority of such bugs will be due to this. As it stands this feels like an incredibly easy case to hit (we've all forgotten to decorate structs).
cc
CC
As reported in : This reports:
Current output is even worse for the original report: The last comment's code is marginally different:
Current output: The last case should suggest constraining . Edit: that was easier than I thought (we already had the suggestion machinery): <img width="511" alt="Screen Shot 2022-12-13 at 6 41 23 PM" src="https://user-"


Question: /// let src = [1, 2, 3, 4]; /// let mut dst = [0, 0]; /// <ins> /// // Because the slices have to be the same length, /// // we slice the source slice from four elements /// // to two. It will panic if we don't do this. </ins> /// dst.copy_from_slice(&src[2..]); /// /// assert_eq!(src, [1, 2, 3, 4]);

Would you like to fix this issue? I'm dealing with a case where I have to send a byte array buffer to a destructive function multiple times. This function requires the buffer to start with an initialization sequence that I have to set. I want to be able to efficiently reset the header bytes but the size of the initialization sequence is less than the total buffer and so I hit the error. The real question is, why is this required? Here's the current code: In theory, if is big enough to hold shouldn't that be enough? The adjusted call should be this then: I think the same should be done for clonefromslice.
The discussion of that decision is in
Holy bikeshed Batman! It’s impossible to find in all those comments! Thanks for pointing me there. It does seem from the first 30 or so posts that it was intentionally meant to fill the destination. If it does stick around, I do think the size checking should be done a little smarter.
Isn't fine? Personally, I find a bunch of value in the explicitness of requiring equal lengths since slicing to get the other three possible behaviours is so easy.
That's not a bad argument. Maybe we can adjust this to suggest that in the error message? I wouldn't have found that on my own.
some examples to the docs of using subslices with these methods. I don't know what the libs policy is on adding guidance to panics -- it does feel like one wouldn't want a long explanatory string built into one's binary in release mode, at least...
Agreed. In general, the longer the message the less likely people are going to read it clearly. I also believe not just stating the problem, but also offering a suggestion. “Destination and source slices have different lengths. Try sub-slicing the longer of the two.” This offers a jumping off point for Googling and reminds those (like me) that sub-slicing is a thing.
I'm personally against lengthening panic messages to suggest fixes, rather I'd expect someone to ask a question about this on StackOverflow or a similar platform eventually which would then get indexed by search engines. I'm going to mark this as an easy documentation issue; we can update documentation to note that subslicing is likely what users want to fix the panic in the panic section or the main section.


Question: /// let src = [1, 2, 3, 4]; /// let mut dst = [0, 0]; /// <ins> /// // Because the slices have to be the same length, /// // we slice the source slice from four elements /// // to two. It will panic if we don't do this. </ins> /// dst.copy_from_slice(&src[2..]); /// /// assert_eq!(src, [1, 2, 3, 4]);

I'm happy to mentor anyone who wants to fix this issue! Here's how: The relevant documentation lives here: This should be extended to describe how to use slicing to make the lengths the same. Something like the example, but with text pointing out how without the slice, it would panic, so slicing to the same length would make the guarantee. I'm happy to answer any more questions about how to accomplish this!
PR:


Question: fn main() { let x = match { 5 } { 1 => 5, 2 => 6, _ => 7, }; <del> assert_eq!(x , 7); </del> <ins> assert_eq!(x, 7); </ins> }

proc-macro derive panicked All of the 62 regressions are due to old versions of having an assert expecting instead of . So this is again a consequence of whitespace changes in pretty-printing (). I think we should be able to fix this by special casing the comma token during token stream pretty-printing and not printing the space before it.
Fixed in
Just FYI, we discussed this in the meeting. We felt like the action here was appropriate -- while in general we do not guarantee stability of pretty printing, it makes sense to be judicious, and in this particular case not having a leading space before just looks better anyway.


Question: } self.print_ident(ident); if let Some(ref p) = *sub { <del> self.s.word("@"); </del> <ins> self.s.space(); self.s.word_space("@"); </ins> self.print_pat(p); } }

The compiler could suggest that identifier must precede the pattern in the following code: playpen link: Current error message: It could be improved as:
modify labels: A-diagnostics C-feature-request T-compiler
So what happens after is that we've parsed a and then follows which is not a valid token after a parsed . To fix this we can, after having parsed in , check if follows and then emit appropriate suggestions. We will need to use some heuristics to figure out what the user wants based on the structure of . Some of the suggestions would be and some not. cc


Question: | LL |         FarmAnimal::Chicken(_) => "cluck, cluck!".to_string(), |         ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant <ins> | help: the struct variant's field is being ignored | LL |         FarmAnimal::Chicken { num_eggs: _ } => "cluck, cluck!".to_string(), |                             ~~~~~~~~~~~~~~~ </ins> error: aborting due to 2 previous errors

I wrote code that looked like this while not having my brain turned on 100%. Due to said brain not functioning, it took me a while to understand what rustc was trying to tell me with the message pointing to the pattern with the text . sure looked like a unit variant to me! What rustc was trying to tell me was that the definition of the variant was a struct variant ("found struct variant") and my pattern wasn't matching the definition ("this pattern you specified looks like it's trying to match a variant that is not a unit struct, unit variant or constant"). The change I needed to make was adding to my pattern, because I was trying to distinguish different variants from each other, not use pieces within the variants. Suggesting seems like a decent starting point to me, but there could definitely be cases I'm not considering here and I'm totally open to hearing that No response No response <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
WEIRD this PR looks like it implements what I wish rustc did: but the test files in that PR say they're for and I'm getting
Aha ok this test shows that for tuple variants, rustc will suggest adding : and that test also shows that rustc isn't suggesting anything for struct variants!
Aha and it looks like adding struct fields was more complex so that's why it wasn't done?
claim


Question: /// /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` <del> #[unstable(feature = "osstring_ascii", issue = "70516")] </del> <ins> #[stable(feature = "osstring_ascii", since = "1.53.0")] </ins> #[inline] pub fn make_ascii_lowercase(&mut self) { self.inner.make_ascii_lowercase()

<!-- Thank you for creating a tracking issue! Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that case, you can use use in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be without an RFC. --Feature gate: <!-- For most library features, it'd be useful to include a summarized version of the public API. (E.g. just the public function signatures without their doc comments or implementation.) --<!-- For larger features, more steps might be involved. If the feature is changed later, please add those PRs here as well. --- [x] - Stabilized traits necessary to obtain [x] - Added ASCII methods on [x] Final commenting period (FCP) [x] - Stabilization PR <!-- Once the feature has gone through a few release cycles and there are no unresolved questions left, the feature might be ready for stabilization. If this feature didn't go through the RFC process, a final commenting period (FCP) is always needed before stabilization. This works as follows: A library team member can kick off the stabilization process, at which point the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final commenting period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in that period of 10 days, a stabilzation PR can be opened by anyone. --<!-- Include any open questions that need to be answered before the feature can be stabilised. If multiple (unrelated) big questions come up, it can be a good idea to open a separate issue for each, to make it easier to keep track of the discussions. It's useful to link any relevant discussions and conclusions (whether on GitHub, Zulip, or the internals forum) here. --- None yet.
Just needed to manipulate paths on windows -- I need to lower case driver letter, -.
Currently, SQLx contains The UTF-8 check that is included in there, while not a problem in practice, seems pointless. Changing to lands me here because of the .


Question: /// /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` <del> #[unstable(feature = "osstring_ascii", issue = "70516")] </del> <ins> #[stable(feature = "osstring_ascii", since = "1.53.0")] </ins> #[inline] pub fn make_ascii_lowercase(&mut self) { self.inner.make_ascii_lowercase()

Also, if somebody did a similar thing with instead of , the version could drop that and would then be a bit less noisy.
is a stabilization PR. Since lib team wants to do fcp in the tracking issue. could you start one ?
merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [x] [ ] Concerns: resolved by Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Slight question about -- normally when dealing with AsRef args, they come in without an explicit reference in the signature (), except when necessary to support a lifetime in the return value (). Currently is declared as: Is this supposed to be instead? concern eqignoreasciicase &S
I think it should be. I'm not sure why I wrote it like I did originally, but this makes more sense to me. I can make that PR if needed. Or can it be done in the stabilization PR? Not sure what the process is from here.
resolve eqignoreascii_case &S reviewed Fixed in .
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , 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.
you can tick the FCP box, as the FCP is complete.


Question: <ins> //@ compile-flags: -Zthreads=16 // original issue: https://github.com/rust-lang/rust/issues/129112 // Previously, the "next" solver asserted that each successful solution is only obtained once. // This test exhibits a repro that, with next-solver + -Zthreads, triggered that old assert. // In the presence of multithreaded solving, it's possible to concurrently evaluate things twice, // which leads to replacing already-solved solutions in the global solution cache! // We assume this is fine if we check to make sure they are solved the same way each time. // This test only nondeterministically fails but that's okay, as it will be rerun by CI many times, // so it should almost always fail before anything is merged. As other thread tests already exist, // we already face this difficulty, probably. If we need to fix this by reducing the error margin, // we should improve compiletest. #[derive(Clone, Eq)] //~ ERROR [E0277] pub struct Struct<T>(T); impl<T: Clone, U> PartialEq<U> for Struct<T> where U: Into<Struct<T>> + Clone { fn eq(&self, _other: &U) -> bool { todo!() } } fn main() {} </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --After adding to , I get the ICE. The resulting : The full project: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --
Looks like another label: +T-types +WG-trait-system-refactor +regression-from-stable-to-nightly
Stable passes, beta passes. Nightly passes with either or Discovered with It does sporadically succeed, thus needing to clean and rerun the build to make sure. Either something is up with or it only barely exercises these conditions in the parallel frontend, even after cleaning and running the build 100 times. Meanwhile, fails something like ~50% of the time on my machine.
stable passes obviously, as -Zthreads this is a unstable nightly-only flag?
Hm, not actually obvious given that works, though I suppose that does mean it isn't a regression per se. :^)
oh I thought you knew by now that this is the forbidden env flag that should only ever be used for bootstrapping and nothing else and we should not even tell users about it. If you set the flag, your "stable" will also eat nightly-only features, but why would that make a "to-stable" regression if you explicitly tell the compiler "please act like you are NOT a stable release"? I don't think it make sense to backport fixes for untable nightly features into stable lol
who mentioned backports?
The label is used to gather regressions between release channels, which are then discussed whether they are backport-worthy or not. Is that not how the label is used?
I don't really think regression-from-stable-to-nightly nor regression-from-stable-to-stable are used for that at all? Probably regression-from-stable-to-beta is?


Question: <ins> //@ compile-flags: -Zthreads=16 // original issue: https://github.com/rust-lang/rust/issues/129112 // Previously, the "next" solver asserted that each successful solution is only obtained once. // This test exhibits a repro that, with next-solver + -Zthreads, triggered that old assert. // In the presence of multithreaded solving, it's possible to concurrently evaluate things twice, // which leads to replacing already-solved solutions in the global solution cache! // We assume this is fine if we check to make sure they are solved the same way each time. // This test only nondeterministically fails but that's okay, as it will be rerun by CI many times, // so it should almost always fail before anything is merged. As other thread tests already exist, // we already face this difficulty, probably. If we need to fix this by reducing the error margin, // we should improve compiletest. #[derive(Clone, Eq)] //~ ERROR [E0277] pub struct Struct<T>(T); impl<T: Clone, U> PartialEq<U> for Struct<T> where U: Into<Struct<T>> + Clone { fn eq(&self, _other: &U) -> bool { todo!() } } fn main() {} </ins>

Pretty much what the title says, I've narrowed it down to and today's nightly with the following: I've attached some backtraces.
probably duplicate of but made more prevalent by next solver
Is it possible to provide a link to or a snippet of a reproducer? I know it probably happens to various crates, but it still would be nice to have something that reproduces.
See for an attached repro.
The repro case is basically the same as , but with other crates mentioned in the ICE logs from the issue comment.


Question: <ins> //@ compile-flags: -Zthreads=16 // original issue: https://github.com/rust-lang/rust/issues/129112 // Previously, the "next" solver asserted that each successful solution is only obtained once. // This test exhibits a repro that, with next-solver + -Zthreads, triggered that old assert. // In the presence of multithreaded solving, it's possible to concurrently evaluate things twice, // which leads to replacing already-solved solutions in the global solution cache! // We assume this is fine if we check to make sure they are solved the same way each time. // This test only nondeterministically fails but that's okay, as it will be rerun by CI many times, // so it should almost always fail before anything is merged. As other thread tests already exist, // we already face this difficulty, probably. If we need to fix this by reducing the error margin, // we should improve compiletest. #[derive(Clone, Eq)] //~ ERROR [E0277] pub struct Struct<T>(T); impl<T: Clone, U> PartialEq<U> for Struct<T> where U: Into<Struct<T>> + Clone { fn eq(&self, _other: &U) -> bool { todo!() } } fn main() {} </ins>

Compile with latest Nightly got ICE like below: when compiling in code OS: x86_64-apple-darwin
cc
Wyvern, could you provide some sort of reproducer? A link to some commit in some repository or better yet a smaller stripped down version of it?
Can you provide an example which triggers this behavior?
I'm not sure which commit/PR of lead to this crash, sometimes it compiled successfully, sometimes it not. Add this info to original post, hope to help investigation.
are you running with greater than 1? The cache is broken when used with more than 1 thread (which we should fix)
Sorry, I wasn't clear. I meant a link to your project (the project you are trying to compile) if publicly accessible / not proprietary.
I can hit plenty of these while fuzzing with -Zthreads so yeah its probably that.
Yeah, I think was the culprit. Comment out this option crashes disappears.
the easiest fix to rustc is to just disable this assert when we're using more than 1 thread. I've only it for debugging purposes to detect cases where we unnecessarily recompute cache entries
just hit this while trying to bootstrap with Zthreads :sweat_smile:
cc as this also showed up in your ci test run ^^
When I just disable this assert, all relevant UI tests passed with no other bugs or ICE
samle code that triggers this in around 5 of 6 cases with -Zthreads=16


Question: } } <ins> // for dbg!(x) which may take ownership, suggest dbg!(&x) instead // but here we actually do not check whether the macro name is `dbg!` // so that we may extend the scope a bit larger to cover more cases fn suggest_ref_for_dbg_args( &self, body: &hir::Expr<'_>, place: &Place<'tcx>, move_span: Span, err: &mut Diag<'infcx>, ) { let var_info = self.body.var_debug_info.iter().find(|info| match info.value { VarDebugInfoContents::Place(ref p) => p == place, _ => false, }); let arg_name = if let Some(var_info) = var_info { var_info.name } else { return; }; struct MatchArgFinder { expr_span: Span, match_arg_span: Option<Span>, arg_name: Symbol, } impl Visitor<'_> for MatchArgFinder { fn visit_expr(&mut self, e: &hir::Expr<'_>) { // dbg! is expanded into a match pattern, we need to find the right argument span if let hir::ExprKind::Match(expr, ..) = &e.kind && let hir::ExprKind::Path(hir::QPath::Resolved( _, path @ Path { segments: [seg], .. }, )) = &expr.kind && seg.ident.name == self.arg_name && self.expr_span.source_callsite().contains(expr.span) { self.match_arg_span = Some(path.span); } hir::intravisit::walk_expr(self, e); } } let mut finder = MatchArgFinder { expr_span: move_span, match_arg_span: None, arg_name }; finder.visit_expr(body); if let Some(macro_arg_span) = finder.match_arg_span { err.span_suggestion_verbose( macro_arg_span.shrink_to_lo(), "consider borrowing instead of transferring ownership", "&", Applicability::MachineApplicable, ); } } </ins> fn report_use_of_uninitialized( &self, mpi: MovePathIndex,

No response No response No response
I thought the intent with was to use it in a passthrough style, so you can insert it into existing expressions ie. becomes . In which case, maybe the lint should be for not using the value resulting from evaluating .
Not sure about the majority of users but for me is a convenience over . I use it without using the return value almost all of the time.
Probably a common thing to do, sure, but if we're talking about adding a lint, why not nudge the user in the direction of the intended and documented usage? You could at least do both: "insert into an existing expression or pass it a borrow" etc.
The fix in will only report a hint when there is already a happened. For example this code: before this fix the error is: with the fix, since there is already a error, the lint will try to find out the original macro, and suggest a borrow: The suggestion is not 100% right, since if we change it to , we need one more extra fix now(the return type is not expecting a reference), but there is a different issue, at least we have already moved one step on. If the original code is: Then suggest a borrow is a great and correct hint.
Similar in the scenario of function argument: original error is: new errors from the fix:
Would not also be a good hint? The suggestion wouldn't compile anyway right? Because would need to change to take ? Without involved, the compiler does indeed suggest that: Once that's addressed (whichever way it's done), once again becomes transparent, and eg. or works. does not, however, and I see why a "consider borrowing" hint would be good there. However, if you make the change first and leave as-is, the resulting error does not include the suggestion to change , which is unhelpful. (I agree that the message is even less helpful though, I'm not disputing that.)
Yes, it's a good hint, but from the implementation view of a hint, it's much harder to analyze the following code from the error point and then construct a new expression. Even it seems an easy thing for humans. You are right, the suggestion is not 100% right, we may need an extra follow-up fix after applying the hint, which is also a common thing in rustc diagnostics.


Question: /// /// assert_eq!(&v, &[0, 1, 2]); /// ``` <del> #[unstable(feature = "vec_spare_capacity", issue = "75017")] </del> <ins> #[stable(feature = "vec_spare_capacity", since = "1.60.0")] </ins> #[inline] pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { // Note:

The feature gate for the issue is . Tracking issues are used to record the overall progress of implementation. They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev- Initial implementation ()
FWIW, here is a full-featured API provided by an external crate:
I wonder how this API relates to . It would be great if there was some safe API that wrapped around the use of to access a 's spare capacity, then updated based on the s .
Maybe we should follow that example and generalize to return ?
has implemented that, albeit as a private function. Sounds like a good idea to me.
Since exists now I think is redundant.
That's not actually true due to pointer invalidation, see and
I think it would be better to have this feature sooner rather than later. I'm starting to notice instances where people are doing things that are probably or definitely UB because they want this functionality. So I think this API falls squarely into the standard library's mission to provide pre-built and correct implementations of things that are subtle or difficult to get right.   (originally posted on but per Ralf's comments there, it is probably better to have this method for the above use cases)
I agree. I've been using this in my code and found it to be very useful. Even though is more general, I've never had a need for it and I feel that is useful on its own. The API being stabilized is: merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!


Question: /// /// assert_eq!(&v, &[0, 1, 2]); /// ``` <del> #[unstable(feature = "vec_spare_capacity", issue = "75017")] </del> <ins> #[stable(feature = "vec_spare_capacity", since = "1.60.0")] </ins> #[inline] pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { // Note:

See for info about what commands tagged team members can give me.
while waiting for this feature to be stabilized, you should suggest that and use one of the convenience methods in:
:bell: This is now entering its final comment period, as per the . :bell:
Ralf mentioned this on , mostly rewording with my own opinion: I would prefer not to recommend that function, because even if you just want access to the spare region, under SB, these interfaces invalidate all pointers to the initialized region. I think that's too much of a footgun for codebases where people are already writing code that is rejected by Miri.
I wonder how many people do keep outstanding pointers to the initialized part while toying with the extra part 's implementation is already better than their 0-elems slices that get -ly converted into non-empty slices (and currently better than the stdlib one since it doesn't involve a 12-week delay for stable Rust). Anyhow, I've just released a new version () with a dedicated adapter: , for extra good measure.
To be clear, my concern is that the splitting interfaces are adding a landmine for the future. If I'm sending someone a PR I'll make sure it passes Miri at the time, but that's a hard condition to maintain. Especially because the two aforementioned codebases have dependencies that do int-ptr casts, an operation that Miri just doesn't understand at the moment, so it would be hard to advocate Miri in CI.
The final comment period, with a disposition to merge, as per the , 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.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

This can be replicated with a minimal : Compile it to WASM with Then, check if the generated WASM uses reference types: <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: (and previous stable rust versions) On those versions, compiling the above and then running with doesn't fail. <!-- Provide the version you are using that has the regression. --: <!-- If you know when this regression occurred, please add a line like below, replacing with one of stable, beta, or nightly. modify labels: +regression-from-stable-to-{channel} -regression-untriaged -- modify labels: +regression-from-stable-to-nightly -regression-untriaged This seems to have been caused by The compatibility note there says: However, the generated code seems to be indeed affected by default. Interestingly, reference types seem to be used unnecessarily, as using to turn the generated into wat and then to turn it back into wasm removes the reference types. As-is, this breaks compatibility with the WebAssembly 1.0 spec.
cc Looks like this causes issues in practice and we might want to do after all?
WG-prioritization assigning priority (). label -I-prioritize +P-high
I was unable to confirm the presence of any reference type instructions in the generated Wasm, even though I got the same error pointing towards a that looks perfectly valid to me. Interestingly enough, doing the back and forth conversion with and remove the issue, even though the output of both files is exactly the same, apart from the missing debug information. I'm assuming that this is another example of a tool making use of the , so this was already anticipated. Unfortunately (?) this isn't the first time LLVM has enabled features by default, in the past they even did affect code generation. From what I've read in the various WebAssembly specification groups, this was always intended. In conclusion, I agree this is a form of breakage, it seems to be intended, I believe if Rust wants to do anything about it the solution needs to a bit more comprehensive. E.g. actually disable all target features by default (I don't know if this is feasible with LLVM, would need research). See and .
I just spend some time digging into this error message that spits out.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

Locally I've produced exactly the same message, but it really doesn't make any sense to me. The location pointed out by the error message does indeed contain a call to , but the reserved value is , so I don't know what the issue is. Further, after using the -trick, it doesn't produce this error anymore, but the code location contains the exact same bytes. I also checked if reads the target feature section. While I confirmed it does, I don't believe it validates it from what I can see in the code. So maybe there is some sort of codegen difference, but I am unable to actually find it.
Could it be the encoding difference discussed in the description of this PR?
Yes, I just confirmed that's the issue. So it does affect codegen, even if in a minor way!
Yes the problem is the LEB-encoding of the table index immediate. Using on the output of rustc I see: which shows that 's type and table index are both using a 5-byte encoding of a zero value. This is not valid in MVP WebAssembly which required the table index to be a literal zero byte, not a LEB. Given I doubt LLVM will do anything here so it sounds like yes, we'll have to solve this in Rust. I believe this is due to the the binary encoding of the LEB. This isn't reflected in the text format and most other tools don't handle this well, so it's a subtle error. That's also why convert-to-text-and-back produces a working binary. To clarify, I don't believe that this is the case. I believe modifications to the target feature section are unrelated. Ok so the question now is what to do. I see a few possible routes: this change. That would entail updating the release notes for the LLVM upgrade PR to indicate that wasm targets are indeed affected. This would probably also detail the workaround of . Note that may not be enough given in . 't accept this change. That would require something along the lines of , perhaps modified to use then adding on features afterwards. "Fix" this change. This would require coordinating with upstream LLVM to change how this works. My guess is that given the existence of this seems unlikely to happen.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

There's not really a governing body per se around the Rust WebAssembly targets so there's not really a group of people we can point to and say "ok please tell us what to do". In lieu of that I would personally be tempted to go with route (1) because that keeps LLVM/C/C++ aligned with Rust and prevents divergence in the wasm ecosystem. Given the age of the proposal and the general intention for enabling more features by default over time as popular engines implement them this will also continue to change. So, concretely, I would propose: Do not change code as a result of this issue, leave it as-is. Update the release notes for LLVM 19 to indicate that WebAssembly targets are affected Update the WebAssembly documentation to explicitly document how to achieve and "MVP binary" by using and .
in the compiler team triage meeting. We think plan is reasonable at present but if there are additional issues or complications (such as it being more difficult to create an MVP binary than just using ), then option 2 (use by default) seems to be the way to go.
Looks like there may be complications. I am endeavouring to add a test to CI which asserts that a particular compiler invocation will generate MVP features. So far roadblocks are: Using is not sufficient. The attribute is not rewritten for IR of dependent libraries, like the standard library. That means that is only applied to the local crate and the standard library still codegens newer features. One can fix the above issue to additionally use but you'd have to pass for all active features. Not great. Even with there are still bulk-memory instructions in at least for example. These are coming from wasi-libc for the target which is what rustc tests in CI. This is not applicable to this issue as users typically use for this but would make adding a test difficult. Trying out the target locally I can't even get something to work it seems. LLVM is producing an invalid binary with alone when there's a memcpy in the binary. There's... a lot going on here apparently. Given the above I don't think that (2) I described above is a silver bullet by any means, even that seems doubtful to work. I need to investigate more what's going on here with all these features slinging all over the place.
Testing shows that plus Cargo's is sufficient.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

That's more-or-less the same as (1) so I'll take it on myself to document this and get it all written down. Unfortunately that doesn't lend itself well to a test in-repo but that's not necessarily worse than where we are at today.
I've proposed to close this issue as "this change is expected".


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

and WebAssembly book () In Rust some requirements for WebAssembly targets. This makes Wasm binaries compiled with Rust (at least with default options/out of the box std) incompatible with older runtime environments, in particular not-so-old iOS safari (). Here is for example the support for Safari iOS 15.5 simulator: ! I searched but did not find any place where these requirements are written down. I think that this is a problem.
In principle Rust can produce binaries that only target the core subset of wasm 1.0 just fine. You do need to set some additional options with and build your own standard libraries though. But point taken, is missing dedicated pages on the wasm target that could contain this information.
The 2nd sentence right after the one you quoted outlines exactly what you need to do to take advantage of rustc’s capability to emit outputs to the wasm 1.0 spec (or any superset of it:) Make sure to do this and report back if you're still seeing the unexpected instructions/types/other entities after rustc is told to produce wasm binaries the way you need them to be. AFAIK, not for WASM.
Sorry, I realized I misunderstood your answer and deleted my post while you were answering it. Do you know how to show which features are enabled by default for a given target? I searched and did not find. I'm trying to discover whether is enabled by default on nowadays. As it seems to be because I am seeing types in the emitted wasm, even though I disabled the feature by "" in an environment variable RUSTFLAGS. It would be surprising to me that is built with that feature by default on wasm32, but maybe it is.
Hm, I'm actually not sure why you might be seeing simd128 in your modules. As far as I can tell it is not enabled by default for any wasm target. In order to print out features used you should look for lines in: For what it is worth I’ve been using this exact target at my $DAYJOB with a pretty primitive runtime and it has been working largely OOB if my memory serves me right. So it indeed could have something to do with your dependencies possibly using something like ? Not sure!


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

It seems that the was built with as I see this WASM function: What I am not sure is whether 1. this was integrated with the standard library and then imported indirectly to my project, or 2. somehow one of the dependency managed to enable it by itself. I tend to favor 1 but I'm not sure. That is why it would be great for such things to be documented :-)
For reference, I asked on the about how the std lib is built.
I confirm that as of version 1.75, the standard library is not using any WebAssembly SIMD instructions. Here is my test: which shows nothing, so they get pulled in by the memchr package through some of my dependencies.
You yourself pointed out which crate produces the v128 types: . It uses to enable emission of these types, regardless of the global configuration it looks like. This is usually fine for other architectures, but rarely for wasm, so it might make sense to file an issue over there.
I fully agree and I just opened an issue there: BurntSushi/memchr
As a heads up I've proposed that close this issue with documentation of how to target MVP wasm.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried to build a wasm binary with MVP opcode only, so I disabled the features: I expected to see no in the wasm binary. Instead, this happened: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details
You can not deactivate default features, because std is prebuilt. You need to build std yourself. Also these features are considered the default by LLVM ever since the recent upgrade to LLVM 16: This should possibly be mentioned in the Rust 1.70 release notes though?
cc to confirm that we're fine with inheriting this change to default target features in Rust.
More context for this change can be found in these locations: - discussion about enabling new features in both Emscripten and LLVM. - the original LLVM patch for this - more follow-up discussion on LLVM In that sense this is an expected change, but at the same time the change was made with the expectation that most users are running on an engine that implements sign-extension. could you expand a bit more on your motivation for excluding these sign-extension instructions? I do agree, though, that this should be mentioned in the detailed release notes. It's unfortunately a bit opaque since not all users of wasm are intimately familiar with proposals and whether or not engines support them, but it's a change nonetheless worth mentioning.
I have tried to use , still not work: Our blockchain platform has used Wasm as a virtual machine running smart contracts and has been running steadily for many years. The MVP opcodes is fully sufficient for our use case. I hope there are ways to turn off these default extension features to avoid frequent upgrades every time a new feature is introduced.
Could you share the code used to reproduce this? These upgrades will not be frequent. This is the first time it's changed in 5 years.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

The use case I have for wanting to build without these extensions isn't critical (servers for a game which don't support the extensions in the old version of nodejs they're running), but a way to successfully disable them to be able to build for such environments would be appreciated!
It would be helpful to have a reproduction of this to run to test out fixes. I tested something locally and was sufficient to disable sign extension instructions. I don't know why isn't working and that may be an LLVM bug. I can't confirm whether this works for others though without a means of reproduction.
I just tried the following: compiled with: to make sure std being precompiled isn't causing problems, and it totally still contains the sign-ext instructions: So you are right, this is some sort of LLVM bug.
Confirming that results in a file without the sign-ext opcodes, while does not, in my testing as well.
would you perhaps know more about ? I would expect that with on the function then even without sign-extension instructions wouldn't get generated, but I'm not sure.
I wonder if this is a consequence of It looks like that might be unioning the module-level features along with the per-function features to form the effective feature set to use.
It can also be reproduced with:
FWIW, the above flags did not work for me with - the resulting binary still had sign-extension opcodes (namely ) - but this served as a workaround (): Command: ^ With the wasm-opt pass, sign-extension ops were gone; without the pass, still there. From the thread above, it sounds like those flags work for some people but not for others. My use case is (was) supporting old Apple devices stuck on iOS 12 and thus Safari 12. Now past this, the binary can load, but performance is enough of a problem to suggest dropping support anyway.
A slightly related issue is that the WebAssembly extensions used by default by the Rust compiler are not documented (besides in the change log, but new users won't look at it), I opened a specific issue for that () and just want to link it here.
As a heads up I've documentation about features to which I've currently got as flagged to close this issue. The documented solution for targetting MVP wasm is: which should solve the original OP of this issue.


Question: [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten <del> `wasm32-unknown-unknown` | ✓ | WebAssembly </del> <ins> [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly </ins> `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads

Other solutions in this issue such as using or that in conjunction with or others don't work for one reason or another. Using the target-cpu, however, plus recompiling the standard library with , does work.


Question: use test::{Bencher, black_box}; use super::BTreeMap; <del> use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; #[bench] pub fn insert_rand_100(b: &mut Bencher) { let mut m = BTreeMap::new(); insert_rand_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.remove(&i); }); } #[bench] pub fn insert_rand_10_000(b: &mut Bencher) { let mut m = BTreeMap::new(); insert_rand_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.remove(&i); }); } // Insert seq #[bench] pub fn insert_seq_100(b: &mut Bencher) { let mut m = BTreeMap::new(); insert_seq_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.remove(&i); }); } #[bench] pub fn insert_seq_10_000(b: &mut Bencher) { let mut m = BTreeMap::new(); insert_seq_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.remove(&i); }); } </del> <ins> map_insert_rand_bench!{insert_rand_100,    100,    BTreeMap} map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap} </ins> <del> // Find rand #[bench] pub fn find_rand_100(b: &mut Bencher) { let mut m = BTreeMap::new(); find_rand_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.get(&i); }); } #[bench] pub fn find_rand_10_000(b: &mut Bencher) { let mut m = BTreeMap::new(); find_rand_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.get(&i); }); } </del> <ins> map_insert_seq_bench!{insert_seq_100,    100,    BTreeMap} map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap} </ins> <del> // Find seq #[bench] pub fn find_seq_100(b: &mut Bencher) { let mut m = BTreeMap::new(); find_seq_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.get(&i); }); } </del> <ins> map_find_rand_bench!{find_rand_100,    100,    BTreeMap} map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap} </ins> <del> #[bench] pub fn find_seq_10_000(b: &mut Bencher) { let mut m = BTreeMap::new(); find_seq_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, |m, i| { m.get(&i); }); } </del> <ins> map_find_seq_bench!{find_seq_100,    100,    BTreeMap} map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap} </ins> fn bench_iter(b: &mut Bencher, size: i32) { let mut map = BTreeMap::<i32, i32>::new();

the closure being passed into in BTreeMap and VecMap's benches has a trailing semi-colon making the return value , and thus making the entire operation a no-op. Removing the semi-colon causes lifetime conflict issues. CC
I have a branch that just gives up and replaces these with macros. This results in clearer and more concise code like . Confirmed produces sane results in benchmark output. Hope to submit something tomorrow.


Question: <ins> // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Ensure assigning an owned or managed variable to itself works. In particular, // that we do not glue_drop before we glue_take (#3290). use std::rc::Rc; pub fn main() { let mut x = ~3; x = x; assert!(*x == 3); let mut x = Rc::new(3); x = x; assert!(*x.borrow() == 3); } </ins>

When a shared reference is assign, the gluedrop function is called with the old value before the gluetake function is called with the newvalue. With an assignment like "self.o = self.o;" the generated program will core. Of course, it's a silly example. All other examples I tried make a gluetake before calling the assignment (for example if you call a function with the argument "self.o" which will be then assigned) so you should never have this case in a real program. Maybe it doesn't need to be fixed as it shouldn't happen with a real program.
A simpler example: That segfaults for me. This should definitely be fixed!
Hm. At some point we had a test for this because I was quite careful to make this work correctly. Wonder when it broke.
Still segfaults as of
Not 0.6
Still segfaults as of . Nominating for milestone 5, production-ready
accepted for production-ready milestone
Still crashing
Still crashing with
accepted for P-high
Working on this
This no longer reproduces (with NIko's test case). I also tried with a managed pointer because apparently glue take/drop is only used for ref counting now and could not repro that way either. I tried to create a testcase as described in the first comment, but TBH I'm not really sure what was required. I tried a few things nothing crashed. I also examined the llvm ir and the 'problem' is that we never create these drop before take patterns. Anyone got an idea for how else this bug could be repro'ed (I really don't understand the glue stuff, so I might be missing something obvious)? Otherwise I suggest the bug should be closed.
I'm not sure if we have a test for this already. Perhaps there's one that was marked as ignored.
With a test case checked in, it looks like this can be closed (unless there's another subtler bug going on here).
I made a big effort to get this right as part of -- and totally forgot to write tests!


Question: /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] <del> #[rustc_deprecated(since = "1.41.0", reason = "use the Display impl or to_string()")] </del> <ins> #[rustc_deprecated(since = "1.42.0", reason = "use the Display impl or to_string()")] </ins> fn description(&self) -> &str { "description() is deprecated; use Display" }

has to but the PR made it only into Rust 1.42.0. Thus the version number should be adjusted. cc
We would be happy to accept a PR for this. I suppose it's a trivial enough fix that I would even be willing to backport it (so we avoid 1.42 indicating incorrectly), but only if we get it in quickly enough. cc re:backport, since you're doing release
I won't do it but it should be easy enough.
I just made a PR for updating this; this is my first contribution to the project (please let me know if I did the process right). Hope that helps!
I just noticed this and saw a PR already existed, amazing! to a backport.


Question: } } <del> #[derive(Clone, PartialEq, Encodable, Decodable)] </del> <ins> #[derive(Copy, Clone, PartialEq, Encodable, Decodable)] </ins> pub enum InlineAttr { None, Hint,

Currently, the compiler is allowed to inline naked functions if it wants to. For a normal function, inlining is fine because the compiler can remove the function prologue/epilogue and the remaining will behave as expected. However for naked functions, the developer provides the prologue/epilogue and those aren't removed by the compiler. This almost surely will result in incorrect behavior. Accordingly I think it would make sense for the compiler to not inline naked functions unless the developer explicitly opted-in.
In the other thread, alistair23 found that
Yes, functions should imply .


Question: fn vtable_impl( &mut self, impl_def_id: DefId, <del> mut substs: Normalized<'tcx, SubstsRef<'tcx>>, </del> <ins> substs: Normalized<'tcx, SubstsRef<'tcx>>, </ins> cause: ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>,

https://crater- modify labels: +regression-from-stable-to-beta I-ICE
searched nightlies: from nightly-2020-09-24 to nightly-2020-12-11 regressed nightly: nightly-2020-10-07 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: aarch64-unknown-linux-gnu Reproduce with: </details
cc -- seems like this one might be an actual bug
Small case that I think shows this issue, it incorrectly fails to compile on beta/nightly.
N.B. I haven't gotten it to ICE, so I can't add it to the


Question: // `allow(warnings)` in scope then we want to respect that instead. if level == Level::Warn { let (warnings_level, warnings_src) = <del> self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx); </del> <ins> self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx, aux); </ins> if let Some(configured_warning_level) = warnings_level { if configured_warning_level != Level::Warn { level = configured_warning_level;

The following snippet works fine before but now it reports a warning: Steps to reproduce: clone rustup override set nightly-2017-08-11 cargo test Is this an expected behavior, or a bug? Thank you!
cc -- probably related to the new lint implementation
Yes this was caused by The bug is on . The check for whether is in scope is not checking the current set of attributes being linted. For example this does not warn: but this warns: (as you've noticed) The fix is to just take the local variable into account which has the up-to-that-point set of lint attributes collected.
I've opened a PR for this at


Question: println!("running {}", test_file_name); let nodejs = build.config.nodejs.as_ref().expect("nodejs not configured"); let mut cmd = Command::new(nodejs); <del> cmd.arg(&test_file_name) .stderr(::std::process::Stdio::inherit()); </del> <ins> cmd.arg(&test_file_name); </ins> if build.config.quiet_tests { cmd.arg("--quiet"); }

Rustbuild now prints which is very not helpful.
I've hit this one too: When there's a stale in Rust's root directory, bootstrap reads paths from there and tries to convert them into windows format using (which it, of course, can't find since we are not running in msys shell). The error message comes from in buildhelper (called from ).


Question: /// /// Note that the argument is not passed through a shell, but given /// literally to the program. This means that shell syntax like quotes, <del> /// escaped characters, word splitting, glob patterns, substitution, etc. </del> <ins> /// escaped characters, word splitting, glob patterns, variable substitution, etc. </ins> /// have no effect. /// /// # Examples

I tried this code: I expected to see this happen: Print the content of the $123 environment variable Instead, this happened: It literally prints $123 : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
It is the shell that resolves environment variables. You're not using a shell here, just directly executing a command. This is behaving as expected.
Indeed, this is the expected behavior. This can be circumvented by actually using a shell, e.g. on POSIX:
I did a quick check on the doc for Note that the argument is not passed through a shell, but given literally to the program. This means that shell syntax like quotes, escaped characters, word splitting, glob patterns, substitution, etc. have no effect. I guess we can expand "substitution" into "variable substitution" to make it more clear.
so is this just a documentation change? claim


Question: /// # Examples /// /// ``` <del> /// #![feature(arc_unwrap_or_clone)] </del> /// # use std::{ptr, sync::Arc}; /// let inner = String::from("test"); /// let ptr = inner.as_ptr();

Feature gate: This is a tracking issue for . This feature adds methods to / to gain access to the contained value, by unwrapping if there is exactly one reference, or cloning otherwise. It is equivalent to cloning the inner value, but saves the clone operation if the caller has the only reference to the rc'd value. [x] Implementation: [ ] Final comment period (FCP) [ ] Stabilization PRThere seems to be consensus that the current name is good.
Apologies if this is the wrong place for this comment, feel free to delete. Is there a technical reason why is an associated function and not a method? If I have , I cannot call , but have to resort to which feels unwieldy.
it's because / are 'wrapper types' that implement . A lot of the methods are implemented as associated functions so they don't clash with method names on the . This makes it easier to change between different wrapper types like / etc without suddenly getting a name clash. Apologies if I'm using the wrong terminology but that's the gist of it.
That makes sense. Thanks for the explanation :)
sounds like a bad name to me: has a connotation of potentially panicking code in Rust. The other suggested names in all sound better to me. (Couldn't comment on the thread in IRLO as it has been closed.)
There is precedence for this pattern: for example.
True, I overlooked it.
I think this name is good, and it's easy for me to understand what it means. I'm really looking forward for this to be fcped and stabilized.
At $work we've been using the exact same implementation as the one used in nightly (), it works perfectly well
While I like the proposal very much (for it's convenience), I feel like I want to point out something that might be interesting as well in the future and is related: It's not possible to use where . In this case we have an , which is . However this is a conversion that is also very useful. It would be intersting to go from to . The other way is already possible, but this way is currently not possible, however there are sometimes cases where the count is known and converting back to a Box would be very useful. Consider wanting to remove an element from an for example.


Question: /// # Examples /// /// ``` <del> /// #![feature(arc_unwrap_or_clone)] </del> /// # use std::{ptr, sync::Arc}; /// let inner = String::from("test"); /// let ptr = inner.as_ptr();

The current way to do this is to clone the vec, remove an element and make a new Rc, even when an Rc is empty. I understand that there would need to be something like a first, but I just wanted to bring it up, so it's clear that there's potentially more things that could "unwrap" from an Rc.
Try this: The code above will copy vector if needed. (I didn't test the code)
Yes, good point, thanks for bringing it up. However a Vec is unfortunately another layer of indirection. Typically I have something like .
Is there something that still needs to be done before this can go to FCP? I just came across the need for this and noticed that the comments seem positive with confirmation that it works at $work for at least one commenter above, so am wondering what if anything is preventing it moving forward?
Pinging here for input. There seems to be consensus on stabilizing this. Can anyone start an FCP? I'd be happy to work on a stabilization PR (with some guidance)
fcp merge Both of these are already expressible on stable using the following incantation, which is exactly the standard library's implementation too: . The rationale for a dedicated method is that "I need a " is a common enough use case that it's worthwhile to have one easy function prominently available in the type's API doing the thing you most likely want to do in that scenario.
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
and others: is related
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , 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.
I believe that can check off the stabilization?
And update the documentation as this seems to have been stabilized.


Question: /// # Examples /// /// ``` <del> /// #![feature(arc_unwrap_or_clone)] </del> /// # use std::{ptr, sync::Arc}; /// let inner = String::from("test"); /// let ptr = inner.as_ptr();

I am getting this:
Arc<strstores the string inline on the heap together with the strongcount and weak_count of the Arc. This means it has a different in-memory representation than Box<strand thus can't be converted into a Box<strwithout copying the contents. A Box<strto Arc<strconversion also copies the string contents into the Arc allocation.
I understand that. But moving elements from an Rc to a Vec is different from cloning. The opposite direction is already possible. This means that you can write , but not . I understand that moving is different from . This would probably need to be named something like Vec::frommovedrcorclone`.
GitHub deleted all my angle brackets. I was specifically talking about converting between string types because there's no difference between moving and cloning characters.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ffa0a5; --trait-link-color: #39afd7; --assoc-item-link-color: #39afd7;

Following , we realized that rustdoc users would prefer to have a syntax extension rather than using plain HTML to have warning blocks. suggested the following: suggested: What do you think? cc
Personal Opinions: The first style will look fine for short forms, but I'm not sure for longer text. A possible syntax: Which to me pushes the text too far right. Not having any spacing, but just separating with newlines, seems hard to parse at a glance what is part of the WARNING, and prevents multiple line breaks inside the warning. Also, it's not as extensible. INFO can be , but if we ever want more extensions, they would increasingly possibly conflict with other things. The second style makes it immediately clear what is part of the block, and is unlikely to accidentally conflict if we ever want to add more block styles. It also supports multiple lines or inner blocks trivially. A final advantage is that it may support nested blocks, in case those ever come to be useful. Overall: I prefer the second form, both aesthetically and for future-proofing
I think I agree with in preferring the second form. I like the first form's simplicity, but it also seems surprising that is treated as a 'keyword' and will change the formatting of the docs.
That's why we have this debate. :stuckouttongue:
I personally actually prefer stabilizing a CSS class, I think we should do more of that, just because parsing can get annoying. But this is not that hard to parse anyway. The problem with is precisely that you can't scope it easily: what if you want to add code blocks? bullet points?
The problem with this is it ties rustdoc to the HTML backend; like I said nothing rustdoc currently does guarentees that it will generate HTML from the markdown. Changing that means that to make the JSON backend have the same info, we'd have to add a full HTML parser to rustdoc just to read the HTML in the markdown, because pulldown does not parse HTML for us. I really think we should avoid making the JSON backend a second-class citizen.
Also there's not much point to this if it's just a little CSS IMO, you can add that yourself with and it will look just as good and be more flexible since you can control the styles yourself.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ffa0a5; --trait-link-color: #39afd7; --assoc-item-link-color: #39afd7;

I'm not a giant fan of the syntax because it looks odd when rendered by anything other than rustdoc, which I'd rather avoid, one of the major design concerns for intra-doc links was compatibility with other markdown parsers:
So, I agree, but I'm not convinced that the warning class is something that needs to be surfaced in the JSON backend as anything special. Also, bear in mind, HTML is a part of markdown: valid HTML (well a subset of HTML) is valid markdown. Users already can , and they do that in many cases. Markdown parsers already need to be able to handle HTML. There's nothing new there. Whatever consumes the JSON backend will need to be able to handle that too. I mean, yes, in theory, in practice people don't do this because of the barrier to entry (you have to get your tools to use that, including )
Also, this is incorrect, pulldown absolutely parses HTML. It has to, like I said valid HTML is valid Markdown. It doesn't parse it thoroughly, I believe you can mess it up with sufficiently complex HTML, but it parses HTML. What this changes is subtler: up till now you did not need any particular stylesheet to acceptably render rustdoc markdown from the JSON backend on your own (just use your favorite markdown renderer's stylesheet), but now you will need other css classes to handle rendering warnings as warnings.
I do not agree that this is a problem. I've used Phabricator's implementation of this approach happily and it is by design that warning banners are one paragraph. It is not the intention that you would put entire sections of documentation into a warning banner. They are for a brief callout. It's fine to refer to a subsequent section of the documentation from the callout if needed. I suppose this is a matter of taste but it's one where I believe the opinionatedness of the syntax is a positive thing.
So I discussed this a bit with on the side, we agree that the effect on the JSON backend isn't major since HTML is already a subset of markdown and docs use HTML already (especially for images and tables). My position is as follows: I strictly prefer HTML over some other scoped syntax with nuances people have to learn. I don't think there's as much value in unscoped syntax which makes my position "HTML or nothing", basically.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ffa0a5; --trait-link-color: #39afd7; --assoc-item-link-color: #39afd7;

I'm not wholly against unscoped single-line syntax. We and syntax in W3C specs and you invariably need to add more stuff to it (there's an HTML class in these specs for this reason). Furthermore, Rust has a strong culture of wrapping text, so this means we need to work well while wrapped, and that means we're again introducing some form of scoping mechanism (e.g. indenting the text), which editors will have to learn, as well.
I don't know about admonitions specifically but there seems to be something of a community habit to use "magic tags" on fenced code blocks for this sort of features (e.g. github has a tag), maybe that could be an option? I don't know if pulldown_cmark has a hook for manipulating code blocks but… So a warning would be or maybe the tag would be to leave room for things like note/todo/danger/… Alternatively, take a gander at how other markdown implementations extend the language for this sort of features? e.g. seems to be using for admonitions.
Hmm, but is still for code, even if it has some extra behavior. Aside from the design concerns, this would be feasible to implement: we just extract the language string from the code block with pulldown.
Could you use something that's already built into markdown? For example, rustdoc could take and render it as an admonition.
That's what suggested: to use markdown and make some changes on rustdoc side. I think the codeblock approach is the best personally.
My bad, I didn't see that.
I wonder if it makes more sense to add this as a proc-macro. Rustdoc can still provide the CSS classes and things, and you could use them with HTML directly, but you could use or something and it would expand to the correct HTML tags and classes.
Might be better to have a then, no?
Is that going to be a special header similar to the "unsafe"/"experimental"/etc ones, or is that going to also be used within docs in an order-sensitive way? If the latter we should probably just use a CSS class; mixing and is ugly
Agreed.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ffa0a5; --trait-link-color: #39afd7; --assoc-item-link-color: #39afd7;

Among the suggested ideas, my favourite one remains the code block with "warning" as tag:
Yeah, but triple backticks is also for preformatted text without further markup, so you won't be able to e.g. use text formatting (or other code) in there
True... Finding the right syntax is much more complicated than expected...
That's the issue of using markdown, for all that it has a pretty nice baseline syntax it really was not designed for extensibility.
We can always use : it'd allow to have text formatting inside it.
I would use , it's not quite kosher to invent arbitrary HTML tags (though you can use Custom Elements, which is more heavyweight)
Sounds good to me. It's funny because we kinda came back to the . :rofl:
I just thought: we could use tag in the markdown and then transform it into in the generated HTML?
My main objection to all of these is that rustdoc shouldn't be adding custom markdown syntax that no one else supports. Any new syntax we use should look reasonable even if rendered with the default renderer.
Well, it remains valid markdown since it's HTML (even though it's custom tag). I'm completely fine with , but it might be simpler/better for users to simply write .
Coming back to this (because of ), it seems like the conversation kinda agreed on adding a CSS class directly and then it would look like this in the docs: . I'll send a PR in the next days and then we can open an FCP to see if everyone is ok with it (and if not, we'll have code to help the debate).
This indeed seems like a better solution than the HTML block. It also plays better with something said about not linking it too much too HTML. This will look like a proper warning or note, mostly independent of the HTML generation.
They also seemed to not be too favourable to anything that needs some extra parsing from rustdoc iuc. I'm fine with bot the github solution and the CSS class.
Maybe one more comment to make here. The note-taking app, which uses Markdown also has a similar syntax to create these blocks. It is called . It uses a syntax similar to the syntax that is used for doc intra-links currently, and it is fully compatible with them.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ffa0a5; --trait-link-color: #39afd7; --assoc-item-link-color: #39afd7;

I am uncertain if this is any better than what suggested from the GitHub syntax, but because of the similarity to the doc intra-link syntax. I do feel like this might be interesting because it should go well with backwards compatibility. However, this may look worse than the GitHub syntax solution when not going through cargo doc.
I thought I'd already left this comment, but I'd really like to avoid adding more markdown syntax where possible. This feature works fine without special syntax, I don't think we need it. edit: copying over the reasoning from the :
Although, I might not agree fully, I can fully appreciate and understand the reasoning you left in the corresponding PR. Still, I do think it might be worth to standardize some kind of syntax for some kind of warning block. This does not actually require customized markdown. Alternatively, I can suggest adding the GitHub flavor with emojis to the . This may help in standardizing short form warnings and notes within documentation. We could for example propose to standardize: which should look like the following I do value people's opinion on this. Is this a possible compromise?
That's a valid alternative, I think the yellow color is pretty important though, and it's useful for themes to be able to make styling decisions about warnings so I do think that having some way of marking it is important. I just don't think the way of marking it should be some magic invocation as opposed to CSS classes. (And I think that the bar for a feature that is adding new semantics to the Rustdoc markdown parser is much, much higher than that of one stabilizing a CSS class)
100% agree. I will look at the Rust API guidelines issue and possibly an RFC to rust to track the adoption in GitHub and possibly eventually merge. Thank you :smile:
Beyond all this discussion of third-party tools, I'd really like to make sure that whatever new syntax and presentation we add to rustdoc can also be to [mdBook]. That way, when the standard library starts using callouts, we can make sure the same style also gets used in The Book. Mostly, The Book seems to just use blockquotes, often with headings like [this one about ownership]. mdBook doesn't do anything special with it: it's [just a block quote with a header].