Question: <ins> // build-fail fn main() { let xs: [i32; 5] = [1, 2, 3, 4, 5]; let _ = &xs; let _ = xs[7]; //~ ERROR: this operation will panic at runtime [unconditional_panic] } </ins>

<!-- 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 this code: I expected to see this happen: Instead, this happened: Apparently, taking a shared reference of will suppress the lint. This seems like a false negative. While false negatives can't be avoided entirely, this case seems to be avoidable as taking a shared reference shouldn't change the type of (which is ) or modify any data in this example. Note that will trigger the lint properly. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
See also .
claim
Note this is a problem because which is supposed to fail to compile but this bug makes it fail at runtime instead
In case no one has dug into it yet, the error is suppressed in but not in and before:
label +regression-from-stable-to-stable
WG-prioritization assigning priority (). label -I-prioritize +P-medium
This is caused by . It only ever worked because the lint ran after optimizations. I made a fix . It specializes the length of arrays as constant, even if the array isn't. I'm going to open a PR when I have time, probably tomorrow. In the long term, I'd like to implement some more extensive tracking of "what parts of a value are constant". For example, the compiler currently assumes that anything that had its reference taken can change, but actually, this can only happen inside (as I understand it).
Labels from the closed duplicate , label A-diagnostics, A-lint, A-mir-opt, T-compiler.
Fixed on stable label E-needs-test
I claim the add test part
This lint only appears on full builds (not check), but this will be fixed once lands.
Reopening because I feel this is not yet solved, see on . As per the , should nail down this issue?
MRE: Also, duplicate of
Another variant of this same issue:


Question: impl Mumbo for usize { // Cannot have a larger effect than the trait: unsafe fn jumbo(&self, x: &usize) { *self + *x; } <del> //~^ ERROR expected normal fn, found unsafe fn </del> <ins> //~^ ERROR method `jumbo` has an incompatible type for trait //~| expected normal fn, //~| found unsafe fn </ins> } fn main() {}

The multi-line errors should be extended to include this testcase. missed this because the didn't go through . I tried but that didn't work either. If someone can point me to to where to catch it, I can probably fix this too. cc Code: Error: Change to:


Question: /// This function does not perform any I/O, it simply informs this object /// that some amount of its buffer, returned from `fill_buf`, has been /// consumed and should no longer be returned. <ins> /// /// This function is used to tell the buffer how many bytes you've consumed /// from the return value of `fill_buf`, and so may do odd things if /// `fill_buf` isn't called before calling this. /// /// The `amt` must be `<=` the number of bytes in the buffer returned by `fill_buf`. </ins> #[stable(feature = "rust1", since = "1.0.0")] fn consume(&mut self, amt: usize);

The behavior of .consume when the buffer is empty is weird : while :
Currently the contract of is that you can only pass a number the number of bytes you receive from . In this case the method is never being called, causing the weird behavior. I believe this is a documentation issue as the documentation for the method is pretty curt.
Maybe adding an assert_debug to check that could be useful too ?
What's the intended use of if it must always be passed a value the return value of ?
Oh sorry, I meant ! The function is intended to tell the buffer how many bytes you've consumed from the return value of


Question: //      } fn mk_decls( cx: &mut ExtCtxt<'_>, <del> custom_derives: &[ProcMacroDerive], custom_attrs: &[ProcMacroDef], custom_macros: &[ProcMacroDef], </del> <ins> macros: &[ProcMacro], </ins> ) -> P<ast::Item> { let expn_id = cx.resolver.expansion_for_ast_pass( DUMMY_SP,

The PR improved the situation about documenting proc macros. Thanks for that! However, I noticed a bug with it. I'm using . Running results in this: ! Looks like a simple typo or off-by-one or something like that bug. When using only and not s, everything looks good to me. CC
Oh, and also, running prints: Not sure if this warning is expected there. And not sure if related to this bug.
This is a consequence of the fact that has not yet been merged. Once it gets merged, and rust updates its Cargo submodule, this issue should go away.
It turns out that this issue was unrelated. I've opened a PR to fix it.
I see. Thanks for your work on this :)


Question: generic_ty: Ty<'tcx>, min: ty::Region<'tcx>, ) -> bool { <ins> if let ty::ReError(_) = *min { return true; } </ins> match bound { VerifyBound::IfEq(verify_if_eq_b) => { let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b);

<!-- 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


Question: <ins> error: lifetime may not live long enough --> $DIR/suggest-using-tick-underscore-lifetime-in-return-trait-object.rs:5:5 | LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> { |                       - let's call the lifetime of this reference `'1` LL |     Box::new(value) as Box<dyn Any> |     ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` | help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> { |                                          ++++ error: aborting due to previous error </ins>

we currently output The suggestion is incomplete and will not result in compilable code. Because the lifetime is coming from an argument of type , which is an unconstrained type parameter, itself will not have the needed lifetime and causes the obligation that we're trying to reverse by suggesting . The appropriate changes to the code would be either or , depending on whether appears in any other argument or not.
The suggested code .


Question: // Equate the headers to find their intersection (the general type, with infer vars, // that may apply both impls). <del> let Some(_equate_obligations) = </del> <ins> let Some(equate_obligations) = </ins> equate_impl_headers(infcx, param_env, &impl1_header, &impl2_header) else { return false;

<!-- 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 expected to see this happen: Compiles successfully 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. --: label A-coherence F-negative_impls requires-nightly T-compiler
I'll look into it


Question: lazy_state: LazyState::NoNode, type_shorthands: Default::default(), predicate_shorthands: Default::default(), <del> } .encode_crate_root(); </del> <ins> }; // Encode the rustc version string in a predictable location. rustc_version().encode(&mut ecx).unwrap(); // Encode all the entries and extra information in the crate, // culminating in the `CrateRoot` which points to all of it. ecx.encode_crate_root() }; </ins> let mut result = cursor.into_inner(); // Encode the root position.

thread 'rustc' panicked at 'index out of bounds: the len is but the index is ', ../src/libserialize kind of expected, after switching toolchain from 1.15 back to 1.14. cargo clean && cargo build "repaired it"
Do you have some more information on how to reproduce this?
I hit this compiling hyper with 1.13 stable.
Which version of hyper is that? I can't reproduce with latest .
It was with master. I tried and now it works. So rustc/cargo were using libs compiled when I tried this with 1.15nightly?
Sounds a bit like cargo was re-using libraries that it should have re-compiled because the compiler has changed. cc
Sorry if I did not save the full backtrace - It was my first issue report. I switched away from 1.15 nightly back to 1.14 nightly in order to solve a serde macro issue. Cargo cleaning and rebuilding fixed the issue. I will make sure to run again and capture the output if it happens again. On 11/16/2016 4:54 PM, Michael Woerister wrote:
Sounds suspiciously like a Cargo bug! If there's a reproduction I'd be more than willing to dig in.
I believe I just reproduced this in Cargo itself: When executing with the last few lines are: So what's happening here is: is populating the entire crate cache with a bunch of libraries on the nightly compiler. switching compilers, Cargo decides to recompile everything. doesn't delete everything as it recompiles, rather incrementally builds up a new crate cache compiler, given to that directory, will read crates in that directory. compiler panics when reading a crate compiled by a future compiler. So I take back what I said earlier about this likely being a Cargo bug, it seems like this may be a bug in the compiler trying to read stale metadata? I thought we had like 10 checks in place to ensure we didn't do that, but maybe it's still leaking through?
I'm going to tag this as a stable-to-nightly regression as this appears to have been introduced in nightly. If I build cargo with beta and then switch to beta, the compiler doesn't ICE.
The panic on stable happens in we check version information. Did we change how we encode version information?


Question: lazy_state: LazyState::NoNode, type_shorthands: Default::default(), predicate_shorthands: Default::default(), <del> } .encode_crate_root(); </del> <ins> }; // Encode the rustc version string in a predictable location. rustc_version().encode(&mut ecx).unwrap(); // Encode all the entries and extra information in the crate, // culminating in the `CrateRoot` which points to all of it. ecx.encode_crate_root() }; </ins> let mut result = cursor.into_inner(); // Encode the root position.

cc
I incremented the header version number though... It should be impossible for older rustc to get that far.
on it looks the same on . Perhaps we just need a PR to bump that?
Oh it looks like my changes have reached stable. I wonder if perhaps the is in a precarious spot and/or has been moved or the serialization otherwise changed. This requires further investigation.
Why is this even calling leb128? Are we using variable-length integers in the metadata header?
I assumed leb128 was the crate being built, not one used by the compiler.
Sure enough. Now every change to requires us to update the LLVM version number, because checking the rustc version number requires parsing . I think we should go back to JSON version guard.
Ahh that's what it was. We can put it at the start then, before/after the absolute address. I'd forgotten that the whole struct would have to be decoded.
What was the PR that modified the versioning scheme? I gather that something has changed about it. Can somebody explain more clearly what is going wrong here?
I mistakenly put the version string inside a larger , somehow thinking that it being at the start helped, but if the whole (that is, ) can't be decoded (e.g. because its definition changed) then you don't get to see the version string, whereas before it was separate. The fix would be to separate it again, put it back at the start and leave it there. Or just encode/decode it before instead of as part of it. Either will work as long as it can't be affected by changes to the metadata schema. The PR that introduced the new schema was , although breakage didn't happen until changed later, for procedural macros and/or the name resolution changes ( would know).
removed the field from for macro modularization.
I believe I have a fix ready. Does this affect beta too now, or just nightly?
AFAIK it's just nightly, not beta or stable


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_uppercase(&mut self) { self.inner.make_ascii_uppercase()

<!-- 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_uppercase(&mut self) { self.inner.make_ascii_uppercase()

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> # `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>

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: <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>

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: <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>

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: <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>

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: <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>

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: <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>

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: <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>

<!-- 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: <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>

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.