diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f5ee4b21ea616..ee3ac3b62d9ec 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2771,7 +2771,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { } } else if tcx.sess.check_name(attr, sym::target_feature) { if !tcx.is_closure(id) && tcx.fn_sig(id).unsafety() == hir::Unsafety::Normal { - if tcx.sess.target.is_like_wasm { + if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { // The `#[target_feature]` attribute is allowed on // WebAssembly targets on all functions, including safe // ones. Other targets require that `#[target_feature]` is @@ -2785,6 +2785,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { // deterministic trap. There is no undefined behavior when // executing WebAssembly so `#[target_feature]` is allowed // on safe functions (but again, only for WebAssembly) + // + // Note that this is also allowed if `actually_rustdoc` so + // if a target is documenting some wasm-specific code then + // it's not spuriously denied. } else if !tcx.features().target_feature_11 { let mut err = feature_err( &tcx.sess.parse_sess, diff --git a/src/test/rustdoc-ui/wasm-safe.rs b/src/test/rustdoc-ui/wasm-safe.rs new file mode 100644 index 0000000000000..80b15ace0ee95 --- /dev/null +++ b/src/test/rustdoc-ui/wasm-safe.rs @@ -0,0 +1,7 @@ +// check-pass + +#![feature(wasm_target_feature)] + +#[cfg(any(target_arch = "wasm32", doc))] +#[target_feature(enable = "simd128")] +pub fn foo() {}