]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #89709 - clemenswasser:apply_clippy_suggestions_2, r=petrochenkov
authorbors <bors@rust-lang.org>
Mon, 11 Oct 2021 11:14:47 +0000 (11:14 +0000)
committerbors <bors@rust-lang.org>
Mon, 11 Oct 2021 11:14:47 +0000 (11:14 +0000)
Apply clippy suggestions for rustc and core

234 files changed:
compiler/rustc_codegen_gcc/src/debuginfo.rs
compiler/rustc_codegen_llvm/src/callee.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
compiler/rustc_codegen_ssa/src/meth.rs
compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_middle/src/traits/select.rs
compiler/rustc_middle/src/ty/layout.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs [new file with mode: 0644]
compiler/rustc_target/src/spec/mod.rs
compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
library/alloc/src/boxed.rs
library/alloc/src/collections/binary_heap.rs
library/alloc/src/collections/btree/map.rs
library/alloc/src/collections/btree/map/entry.rs
library/alloc/src/collections/btree/map/tests.rs
library/alloc/src/collections/btree/set.rs
library/alloc/src/lib.rs
library/alloc/src/rc.rs
library/alloc/src/string.rs
library/alloc/src/sync.rs
library/core/src/array/mod.rs
library/core/src/cell.rs
library/core/src/char/methods.rs
library/core/src/hash/mod.rs
library/core/src/lib.rs
library/core/src/num/f32.rs
library/core/src/num/f64.rs
library/core/src/num/int_macros.rs
library/core/src/num/mod.rs
library/core/src/num/nonzero.rs
library/core/src/num/saturating.rs
library/core/src/num/uint_macros.rs
library/core/src/num/wrapping.rs
library/core/src/option.rs
library/core/src/pin.rs
library/core/src/ptr/unique.rs
library/core/src/slice/iter.rs
library/core/src/str/mod.rs
library/core/src/time.rs
library/core/src/unicode/printable.rs
library/core/src/unicode/unicode_data.rs
library/core/tests/array.rs
library/core/tests/lib.rs
library/proc_macro/src/lib.rs
library/std/src/collections/hash/map.rs
library/std/src/ffi/c_str.rs
library/std/src/ffi/os_str.rs
library/std/src/io/buffered/bufreader.rs
library/std/src/io/buffered/bufwriter.rs
library/std/src/io/error.rs
library/std/src/io/stdio.rs
library/std/src/net/tcp.rs
library/std/src/path.rs
library/std/src/process.rs
library/std/src/sys/unix/mod.rs
library/std/src/sys/unix/stack_overflow.rs
library/std/src/sys/unix/thread.rs
library/std/src/sys/windows/fs.rs
library/std/src/sys/windows/stack_overflow.rs
library/std/src/sys_common/backtrace.rs
library/std/src/sys_common/process.rs
library/unwind/src/lib.rs
src/bootstrap/test.rs
src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config
src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config
src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config
src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config
src/doc/rustc/src/platform-support.md
src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md [new file with mode: 0644]
src/doc/unstable-book/src/library-features/asm.md
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/blanket_impl.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/simplify.rs
src/librustdoc/clean/types.rs
src/librustdoc/clean/utils.rs
src/librustdoc/formats/cache.rs
src/librustdoc/formats/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render/cache.rs
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/render/templates.rs [new file with mode: 0644]
src/librustdoc/html/static/css/rustdoc.css
src/librustdoc/html/static_files.rs
src/librustdoc/html/templates/print_item.html [new file with mode: 0644]
src/librustdoc/json/conversions.rs
src/librustdoc/passes/collect_trait_impls.rs
src/librustdoc/passes/stripper.rs
src/test/codegen/debug-vtable.rs [new file with mode: 0644]
src/test/codegen/vtabletype.rs [deleted file]
src/test/rustdoc-gui/docblock-big-code-mobile.goml [new file with mode: 0644]
src/test/rustdoc-gui/src/test_docs/lib.rs
src/test/ui/error-codes/E0308-2.stderr
src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr [new file with mode: 0644]
src/test/ui/issues/issue-20831-debruijn.stderr
src/test/ui/issues/issue-65230.rs [new file with mode: 0644]
src/test/ui/issues/issue-65230.stderr [new file with mode: 0644]
src/test/ui/nll/issue-50716.stderr
src/test/ui/proc-macro/auxiliary/is-available.rs
src/test/ui/proc-macro/is-available.rs
src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs
src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr
src/test/ui/simd-intrinsic/issue-85855.rs [deleted file]
src/test/ui/simd-intrinsic/issue-85855.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs [deleted file]
src/test/ui/simd/array-trait.rs [new file with mode: 0644]
src/test/ui/simd/array-trait.stderr [new file with mode: 0644]
src/test/ui/simd/array-type.rs [new file with mode: 0644]
src/test/ui/simd/generics.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/float-math-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/float-minmax-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-arithmetic-2.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-arithmetic-2.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-bitmask-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-bitmask.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-bitmask.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-cast-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-cast.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-cast.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-comparison-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-comparison.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-comparison.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-elements-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-elements.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-elements.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-gather-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-reduction-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-reduction.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-reduction.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-select-pass.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-select.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-select.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-shuffle.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/generic-shuffle.stderr [new file with mode: 0644]
src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/inlining-issue67557.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/issue-85855.rs [new file with mode: 0644]
src/test/ui/simd/intrinsic/issue-85855.stderr [new file with mode: 0644]
src/test/ui/simd/shuffle-not-out-of-bounds.rs
src/test/ui/simd/shuffle-not-out-of-bounds.stderr
src/test/ui/simd/simd-array-trait.rs [deleted file]
src/test/ui/simd/simd-array-trait.stderr [deleted file]
src/test/ui/simd/simd-array-type.rs [deleted file]
src/test/ui/simd/simd-generics.rs [deleted file]
src/test/ui/simd/simd-intrinsic-float-math.rs [deleted file]
src/test/ui/simd/simd-intrinsic-float-minmax.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-bitmask.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-cast.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-comparison.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-elements.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-gather.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-reduction.rs [deleted file]
src/test/ui/simd/simd-intrinsic-generic-select.rs [deleted file]
src/test/ui/simd/simd-size-align.rs [deleted file]
src/test/ui/simd/simd-target-feature-mixup.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-empty.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-empty.stderr [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-extern-nonnull-ptr.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-oversized.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-oversized.stderr [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-power-of-two.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.stderr [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation.rs [deleted file]
src/test/ui/simd/simd-type-generic-monomorphisation.stderr [deleted file]
src/test/ui/simd/simd-type-wide-ptr.rs [deleted file]
src/test/ui/simd/simd-type-wide-ptr.stderr [deleted file]
src/test/ui/simd/simd-type.rs [deleted file]
src/test/ui/simd/simd-type.stderr [deleted file]
src/test/ui/simd/size-align.rs [new file with mode: 0644]
src/test/ui/simd/target-feature-mixup.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-empty.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-empty.stderr [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-non-primitive.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-non-primitive.stderr [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-oversized.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-oversized.stderr [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-power-of-two.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-wide-ptr.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation-wide-ptr.stderr [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation.rs [new file with mode: 0644]
src/test/ui/simd/type-generic-monomorphisation.stderr [new file with mode: 0644]
src/test/ui/simd/type-len.rs [new file with mode: 0644]
src/test/ui/simd/type-len.stderr [new file with mode: 0644]
src/test/ui/simd/type-wide-ptr.rs [new file with mode: 0644]
src/test/ui/simd/type-wide-ptr.stderr [new file with mode: 0644]
src/test/ui/variance/variance-contravariant-self-trait-match.stderr
src/test/ui/variance/variance-covariant-self-trait-match.stderr
src/test/ui/variance/variance-invariant-self-trait-match.stderr
src/test/ui/wasm/simd-to-array-80108.rs [new file with mode: 0644]
src/tools/compiletest/src/runtest.rs
src/tools/compiletest/src/runtest/debugger.rs [new file with mode: 0644]
src/tools/unicode-table-generator/src/case_mapping.rs
src/tools/unicode-table-generator/src/raw_emitter.rs

index 4d3b4f04badec86dd9149a9421036a3c81e52518..31959fa19c588b9265143b9e73b3a168fae07ad4 100644 (file)
@@ -2,7 +2,7 @@
 use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, VariableKind};
 use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods};
 use rustc_middle::mir;
-use rustc_middle::ty::{Instance, Ty};
+use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
 use rustc_span::{SourceFile, Span, Symbol};
 use rustc_target::abi::Size;
 use rustc_target::abi::call::FnAbi;
@@ -31,7 +31,7 @@ fn set_dbg_loc(&mut self, _dbg_loc: Self::DILocation) {
 }
 
 impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
-    fn create_vtable_metadata(&self, _ty: Ty<'tcx>, _vtable: Self::Value) {
+    fn create_vtable_metadata(&self, _ty: Ty<'tcx>, _trait_ref: Option<PolyExistentialTraitRef<'tcx>>, _vtable: Self::Value) {
         // TODO(antoyo)
     }
 
index 5d68d2b77d42ea0de6c529622840f7ae5afc2334..1bc924d3b90b0f5db6ba18c25375c728c9f2e2b3 100644 (file)
@@ -175,7 +175,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
             // should use dllimport for functions.
             if cx.use_dll_storage_attrs
                 && tcx.is_dllimport_foreign_item(instance_def_id)
-                && tcx.sess.target.env != "gnu"
+                && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc")
             {
                 llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
             }
index 8e6a66a61754640909b560a33575bd6a4b85535a..cd29f2af0165aa36041d7129778d3f3b3b469f4b 100644 (file)
@@ -2,7 +2,7 @@
 use self::RecursiveTypeDescription::*;
 
 use super::namespace::mangled_name_of_instance;
-use super::type_names::compute_debuginfo_type_name;
+use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name};
 use super::utils::{
     create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB,
 };
@@ -29,8 +29,9 @@
 use rustc_middle::mir::{self, GeneratorLayout};
 use rustc_middle::ty::layout::{self, IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::Instance;
-use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{
+    self, AdtKind, GeneratorSubsts, Instance, ParamEnv, Ty, TyCtxt, COMMON_VTABLE_ENTRIES,
+};
 use rustc_middle::{bug, span_bug};
 use rustc_query_system::ich::NodeIdHashingMode;
 use rustc_session::config::{self, DebugInfo};
@@ -2591,11 +2592,45 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
     }
 }
 
+/// Generates LLVM debuginfo for a vtable.
+fn vtable_type_metadata(
+    cx: &CodegenCx<'ll, 'tcx>,
+    ty: Ty<'tcx>,
+    poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+) -> &'ll DIType {
+    let tcx = cx.tcx;
+
+    let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
+        let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
+        let trait_ref = tcx.erase_regions(trait_ref);
+
+        tcx.vtable_entries(trait_ref)
+    } else {
+        COMMON_VTABLE_ENTRIES
+    };
+
+    // FIXME: We describe the vtable as an array of *const () pointers. The length of the array is
+    //        correct - but we could create a more accurate description, e.g. by describing it
+    //        as a struct where each field has a name that corresponds to the name of the method
+    //        it points to.
+    //        However, this is not entirely straightforward because there might be multiple
+    //        methods with the same name if the vtable is for multiple traits. So for now we keep
+    //        things simple instead of adding some ad-hoc disambiguation scheme.
+    let vtable_type = tcx.mk_array(tcx.mk_imm_ptr(tcx.types.unit), vtable_entries.len() as u64);
+
+    type_metadata(cx, vtable_type, rustc_span::DUMMY_SP)
+}
+
 /// Creates debug information for the given vtable, which is for the
 /// given type.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
-pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &'ll Value) {
+pub fn create_vtable_metadata(
+    cx: &CodegenCx<'ll, 'tcx>,
+    ty: Ty<'tcx>,
+    poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    vtable: &'ll Value,
+) {
     if cx.dbg_cx.is_none() {
         return;
     }
@@ -2605,42 +2640,16 @@ pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &
         return;
     }
 
-    let type_metadata = type_metadata(cx, ty, rustc_span::DUMMY_SP);
+    let vtable_name = compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref);
+    let vtable_type = vtable_type_metadata(cx, ty, poly_trait_ref);
 
     unsafe {
-        // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
-        // pointer will lead to hard to trace and debug LLVM assertions
-        // later on in `llvm/lib/IR/Value.cpp`.
-        let empty_array = create_DIArray(DIB(cx), &[]);
-        let name = "vtable";
-
-        // Create a new one each time. We don't want metadata caching
-        // here, because each vtable will refer to a unique containing
-        // type.
-        let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
-            DIB(cx),
-            NO_SCOPE_METADATA,
-            name.as_ptr().cast(),
-            name.len(),
-            unknown_file_metadata(cx),
-            UNKNOWN_LINE_NUMBER,
-            Size::ZERO.bits(),
-            cx.tcx.data_layout.pointer_align.abi.bits() as u32,
-            DIFlags::FlagArtificial,
-            None,
-            empty_array,
-            0,
-            Some(type_metadata),
-            name.as_ptr().cast(),
-            name.len(),
-        );
-
         let linkage_name = "";
         llvm::LLVMRustDIBuilderCreateStaticVariable(
             DIB(cx),
             NO_SCOPE_METADATA,
-            name.as_ptr().cast(),
-            name.len(),
+            vtable_name.as_ptr().cast(),
+            vtable_name.len(),
             linkage_name.as_ptr().cast(),
             linkage_name.len(),
             unknown_file_metadata(cx),
index 894320a79828504367af5018415371e9b8c785f6..1f1bd73c7d035d51ae736dae5bfde264980b1d0a 100644 (file)
@@ -550,8 +550,13 @@ fn dbg_loc(
         unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) }
     }
 
-    fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value) {
-        metadata::create_vtable_metadata(self, ty, vtable)
+    fn create_vtable_metadata(
+        &self,
+        ty: Ty<'tcx>,
+        trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+        vtable: Self::Value,
+    ) {
+        metadata::create_vtable_metadata(self, ty, trait_ref, vtable)
     }
 
     fn extend_scope_to_file(
index 6e7b2968597408fbe69978832484dc9ccf8833fb..609316ea69fe560487cfd397f28999bab9133512 100644 (file)
@@ -446,6 +446,62 @@ fn pop_auto_trait_separator(output: &mut String) {
     }
 }
 
+/// Computes a name for the global variable storing a vtable.
+///
+/// The name is of the form:
+///
+/// `<path::to::SomeType as path::to::SomeTrait>::{vtable}`
+///
+/// or, when generating C++-like names:
+///
+/// `impl$<path::to::SomeType, path::to::SomeTrait>::vtable$`
+pub fn compute_debuginfo_vtable_name<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    t: Ty<'tcx>,
+    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+) -> String {
+    let cpp_like_names = cpp_like_names(tcx);
+
+    let mut vtable_name = String::with_capacity(64);
+
+    if cpp_like_names {
+        vtable_name.push_str("impl$<");
+    } else {
+        vtable_name.push('<');
+    }
+
+    let mut visited = FxHashSet::default();
+    push_debuginfo_type_name(tcx, t, true, &mut vtable_name, &mut visited);
+
+    if cpp_like_names {
+        vtable_name.push_str(", ");
+    } else {
+        vtable_name.push_str(" as ");
+    }
+
+    if let Some(trait_ref) = trait_ref {
+        push_item_name(tcx, trait_ref.skip_binder().def_id, true, &mut vtable_name);
+        visited.clear();
+        push_generic_params_internal(
+            tcx,
+            trait_ref.skip_binder().substs,
+            &mut vtable_name,
+            &mut visited,
+        );
+    } else {
+        vtable_name.push_str("_");
+    }
+
+    push_close_angle_bracket(cpp_like_names, &mut vtable_name);
+
+    let suffix = if cpp_like_names { "::vtable$" } else { "::{vtable}" };
+
+    vtable_name.reserve_exact(suffix.len());
+    vtable_name.push_str(suffix);
+
+    vtable_name
+}
+
 pub fn push_item_name(tcx: TyCtxt<'tcx>, def_id: DefId, qualified: bool, output: &mut String) {
     let def_key = tcx.def_key(def_id);
     if qualified {
index 3267d3206f73f45bb55e5f4f8e87b5293091d3fb..6ab429669c881302c4779a34bfbfecd32af9d1ff 100644 (file)
@@ -78,7 +78,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
     let align = cx.data_layout().pointer_align.abi;
     let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
 
-    cx.create_vtable_metadata(ty, vtable);
+    cx.create_vtable_metadata(ty, trait_ref, vtable);
     cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
     vtable
 }
index 3e66d711d2ef59a79e1c7dc3b1597ac018f32ae3..e700afc448f28633716b42c3891906afe61a6898 100644 (file)
@@ -1,13 +1,18 @@
 use super::BackendTypes;
 use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
 use rustc_middle::mir;
-use rustc_middle::ty::{Instance, Ty};
+use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
 use rustc_span::{SourceFile, Span, Symbol};
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::Size;
 
 pub trait DebugInfoMethods<'tcx>: BackendTypes {
-    fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
+    fn create_vtable_metadata(
+        &self,
+        ty: Ty<'tcx>,
+        trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
+        vtable: Self::Value,
+    );
 
     /// Creates the function-specific debug context.
     ///
index ec2c703ad495d28e6e9c5bccfaa8bb399ae8e94c..a2fadb13a574179611cca2629ce783776860f3dc 100644 (file)
@@ -678,6 +678,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows `#[doc(cfg_hide(...))]`.
     (active, doc_cfg_hide, "1.57.0", Some(43781), None),
 
+    /// Allows using the `non_exhaustive_omitted_patterns` lint.
+    (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
index c44d4361f037a1007a6869d713ae3ee1b2ec3d6b..056709cd314d1a8f9c689411ee9d1299bf646b19 100644 (file)
@@ -2060,14 +2060,24 @@ fn values_str(
                     expected: exp_found.expected.print_only_trait_path(),
                     found: exp_found.found.print_only_trait_path(),
                 };
-                self.expected_found_str(pretty_exp_found)
+                match self.expected_found_str(pretty_exp_found) {
+                    Some((expected, found)) if expected == found => {
+                        self.expected_found_str(exp_found)
+                    }
+                    ret => ret,
+                }
             }
             infer::PolyTraitRefs(exp_found) => {
                 let pretty_exp_found = ty::error::ExpectedFound {
                     expected: exp_found.expected.print_only_trait_path(),
                     found: exp_found.found.print_only_trait_path(),
                 };
-                self.expected_found_str(pretty_exp_found)
+                match self.expected_found_str(pretty_exp_found) {
+                    Some((expected, found)) if expected == found => {
+                        self.expected_found_str(exp_found)
+                    }
+                    ret => ret,
+                }
             }
         }
     }
index 7a51e1e321a2a459d0d87bbde27cc369c0cde069..a93d18950dba9256364c077fcd85d32afe2504b1 100644 (file)
@@ -6,6 +6,7 @@
 
 use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason};
 use rustc_span::edition::Edition;
+use rustc_span::symbol::sym;
 
 declare_lint! {
     /// The `forbidden_lint_groups` lint detects violations of
     /// }
     ///
     /// // in crate B
+    /// #![feature(non_exhaustive_omitted_patterns_lint)]
+    ///
     /// match Bar::A {
     ///     Bar::A => {},
     ///     #[warn(non_exhaustive_omitted_patterns)]
     pub NON_EXHAUSTIVE_OMITTED_PATTERNS,
     Allow,
     "detect when patterns of types marked `non_exhaustive` are missed",
+    @feature_gate = sym::non_exhaustive_omitted_patterns_lint;
 }
 
 declare_lint! {
index 87495a2d5b3ec6cf66663d615c62707f214534e7..6720493cd3cb19ba77400f82970fc08df7449cca 100644 (file)
@@ -264,14 +264,14 @@ pub fn is_stack_dependent(self) -> bool {
 /// Indicates that trait evaluation caused overflow and in which pass.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
 pub enum OverflowError {
-    Cannonical,
+    Canonical,
     ErrorReporting,
 }
 
 impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
     fn from(overflow_error: OverflowError) -> SelectionError<'tcx> {
         match overflow_error {
-            OverflowError::Cannonical => SelectionError::Overflow,
+            OverflowError::Canonical => SelectionError::Overflow,
             OverflowError::ErrorReporting => SelectionError::ErrorReporting,
         }
     }
index 0bdf70b3ec4888fd6b9e92161a9a57f30fa9eb91..d0c7379c2d94d5aab856d8fb9ffbda0c6f795008 100644 (file)
@@ -3012,7 +3012,7 @@ fn fn_abi_new_uncached(
         };
 
         let target = &self.tcx.sess.target;
-        let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl");
+        let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
         let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
         let linux_s390x_gnu_like =
             target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
@@ -3110,7 +3110,7 @@ fn fn_abi_new_uncached(
             if arg.layout.is_zst() {
                 // For some forsaken reason, x86_64-pc-windows-gnu
                 // doesn't ignore zero-sized struct arguments.
-                // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl}.
+                // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}.
                 if is_return
                     || rust_abi
                     || (!win_x64_gnu
index 0e30e154ee57c7d5d0abbd0e53c56260f4dacb28..9551120ca5522450fdac428e999044c33493f69c 100644 (file)
         nomem,
         non_ascii_idents,
         non_exhaustive,
+        non_exhaustive_omitted_patterns_lint,
         non_modrs_mods,
         none_error,
         nontemporal_store,
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs
new file mode 100644 (file)
index 0000000..d230f77
--- /dev/null
@@ -0,0 +1,24 @@
+use crate::spec::{Target, TargetOptions};
+
+// This target is for uclibc Linux on ARMv7 without NEON or
+// thumb-mode. See the thumbv7neon variant for enabling both.
+
+pub fn target() -> Target {
+    let base = super::linux_uclibc_base::opts();
+    Target {
+        llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+
+        options: TargetOptions {
+            // Info about features at https://wiki.debian.org/ArmHardFloatPort
+            features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
+            cpu: "generic".to_string(),
+            max_atomic_width: Some(64),
+            mcount: "_mcount".to_string(),
+            abi: "eabihf".to_string(),
+            ..base
+        },
+    }
+}
index 5276da1ba5a1c7cf0a5626379c37dbea69482368..ff5dfa3f746254b0364c4faf37b17f81e941346b 100644 (file)
@@ -952,6 +952,8 @@ fn $module() {
     ("bpfel-unknown-none", bpfel_unknown_none),
 
     ("armv6k-nintendo-3ds", armv6k_nintendo_3ds),
+
+    ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),
 }
 
 /// Warnings encountered when parsing the target `json`.
index 31254a0534d76a720236495e69d893b7613a26b4..2fa6c0c02597b77ebef3d29585b04f825ab7c46f 100644 (file)
@@ -83,10 +83,10 @@ fn evaluate_obligation_no_overflow(
     ) -> EvaluationResult {
         match self.evaluate_obligation(obligation) {
             Ok(result) => result,
-            Err(OverflowError::Cannonical) => {
+            Err(OverflowError::Canonical) => {
                 let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
                 selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r {
-                    OverflowError::Cannonical => {
+                    OverflowError::Canonical => {
                         span_bug!(
                             obligation.cause.span,
                             "Overflow should be caught earlier in standard query mode: {:?}, {:?}",
index d68ae07907734e805d93916efc77c4a569e2a4ae..0f6e2e0be52b74a076a18019fe8d48272f7599e0 100644 (file)
@@ -161,7 +161,7 @@ fn candidate_from_obligation_no_cache<'o>(
                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
                 }
                 Ok(_) => Ok(None),
-                Err(OverflowError::Cannonical) => Err(Overflow),
+                Err(OverflowError::Canonical) => Err(Overflow),
                 Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
             })
             .flat_map(Result::transpose)
index 3818e75a1de04217874ddf7b6b2fcada3c4add85..85502a399dedac0bbc74781160255accebbba09d 100644 (file)
@@ -900,7 +900,7 @@ fn evaluate_stack<'o>(
         match self.candidate_from_obligation(stack) {
             Ok(Some(c)) => self.evaluate_candidate(stack, &c),
             Ok(None) => Ok(EvaluatedToAmbig),
-            Err(Overflow) => Err(OverflowError::Cannonical),
+            Err(Overflow) => Err(OverflowError::Canonical),
             Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
             Err(..) => Ok(EvaluatedToErr),
         }
@@ -1064,7 +1064,7 @@ fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
                     self.infcx.report_overflow_error(error_obligation, true);
                 }
                 TraitQueryMode::Canonical => {
-                    return Err(OverflowError::Cannonical);
+                    return Err(OverflowError::Canonical);
                 }
             }
         }
index 2b3a18a439fc92c56d2b6f530c73e85ce03db3c9..85f908a7f5c7b6cd49606661bf943a5d576695da 100644 (file)
@@ -1277,6 +1277,7 @@ impl<T> From<T> for Box<T> {
     /// from the stack into it.
     ///
     /// # Examples
+    ///
     /// ```rust
     /// let x = 5;
     /// let boxed = Box::new(5);
@@ -1330,6 +1331,12 @@ fn from(slice: &[T]) -> Box<[T]> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_cow", since = "1.45.0")]
 impl<T: Copy> From<Cow<'_, [T]>> for Box<[T]> {
+    /// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
+    ///
+    /// When `cow` is the `Cow::Borrowed` variant, this
+    /// conversion allocates on the heap and copies the
+    /// underlying slice. Otherwise, it will try to reuse the owned
+    /// `Vec`'s allocation.
     #[inline]
     fn from(cow: Cow<'_, [T]>) -> Box<[T]> {
         match cow {
@@ -1348,6 +1355,7 @@ impl From<&str> for Box<str> {
     /// and performs a copy of `s`.
     ///
     /// # Examples
+    ///
     /// ```rust
     /// let boxed: Box<str> = Box::from("hello");
     /// println!("{}", boxed);
@@ -1361,6 +1369,29 @@ fn from(s: &str) -> Box<str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_cow", since = "1.45.0")]
 impl From<Cow<'_, str>> for Box<str> {
+    /// Converts a `Cow<'_, str>` into a `Box<str>`
+    ///
+    /// When `cow` is the `Cow::Borrowed` variant, this
+    /// conversion allocates on the heap and copies the
+    /// underlying `str`. Otherwise, it will try to reuse the owned
+    /// `String`'s allocation.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::borrow::Cow;
+    ///
+    /// let unboxed = Cow::Borrowed("hello");
+    /// let boxed: Box<str> = Box::from(unboxed);
+    /// println!("{}", boxed);
+    /// ```
+    ///
+    /// ```rust
+    /// # use std::borrow::Cow;
+    /// let unboxed = Cow::Owned("hello".to_string());
+    /// let boxed: Box<str> = Box::from(unboxed);
+    /// println!("{}", boxed);
+    /// ```
     #[inline]
     fn from(cow: Cow<'_, str>) -> Box<str> {
         match cow {
@@ -1403,6 +1434,7 @@ fn from(s: Box<str, A>) -> Self {
     /// This conversion moves the array to newly heap-allocated memory.
     ///
     /// # Examples
+    ///
     /// ```rust
     /// let boxed: Box<[u8]> = Box::from([4, 2]);
     /// println!("{:?}", boxed);
@@ -1416,6 +1448,15 @@ fn from(s: Box<str, A>) -> Self {
 impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
     type Error = Box<[T]>;
 
+    /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
+    ///
+    /// The conversion occurs in-place and does not require a
+    /// new memory allocation.
+    ///
+    /// # Errors
+    ///
+    /// Returns the old `Box<[T]>` in the `Err` variant if
+    /// `boxed_slice.len()` does not equal `N`.
     fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
         if boxed_slice.len() == N {
             Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) })
index 4ed3702f7d22479d8ab1e77be4c49dc139f5b1ec..75720a970a31f780fcda4d458b2a8624a0a18a0c 100644 (file)
@@ -848,6 +848,7 @@ pub fn iter(&self) -> Iter<'_, T> {
     ///
     /// assert_eq!(heap.into_iter_sorted().take(2).collect::<Vec<_>>(), vec![5, 4]);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
     pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
         IntoIterSorted { inner: self }
@@ -1028,6 +1029,7 @@ pub fn as_slice(&self) -> &[T] {
     ///     println!("{}", x);
     /// }
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
     pub fn into_vec(self) -> Vec<T> {
         self.into()
index d6032372168f15c342cb55cf435860080aaea1ee..e9265262c8b8402448b6c71eb4b9348541c2c5f3 100644 (file)
@@ -1264,6 +1264,7 @@ pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V>
     /// assert_eq!(keys, [1, 2]);
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "map_into_keys_values", since = "1.54.0")]
     pub fn into_keys(self) -> IntoKeys<K, V> {
         IntoKeys { inner: self.into_iter() }
@@ -1286,6 +1287,7 @@ pub fn into_keys(self) -> IntoKeys<K, V> {
     /// assert_eq!(values, ["hello", "goodbye"]);
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "map_into_keys_values", since = "1.54.0")]
     pub fn into_values(self) -> IntoValues<K, V> {
         IntoValues { inner: self.into_iter() }
index 5fec8dc2d13343a6b45730474d1105b83cd1ce3f..3e9048b17688fb78f7d589c0dac2ba352a773415 100644 (file)
@@ -448,6 +448,7 @@ pub fn get_mut(&mut self) -> &mut V {
     /// }
     /// assert_eq!(map["poneyland"], 22);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_mut(self) -> &'a mut V {
         self.handle.into_val_mut()
index b8e11e109c831bb220fe350824975d573998f252..173960341f859b5acab3b8b8f094de9c6b1ee36e 100644 (file)
@@ -1755,20 +1755,20 @@ fn vacant_entry<T: Send + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Send +
 #[test]
 fn test_ord_absence() {
     fn map<K>(mut map: BTreeMap<K, ()>) {
-        map.is_empty();
-        map.len();
+        let _ = map.is_empty();
+        let _ = map.len();
         map.clear();
-        map.iter();
-        map.iter_mut();
-        map.keys();
-        map.values();
-        map.values_mut();
+        let _ = map.iter();
+        let _ = map.iter_mut();
+        let _ = map.keys();
+        let _ = map.values();
+        let _ = map.values_mut();
         if true {
-            map.into_values();
+            let _ = map.into_values();
         } else if true {
-            map.into_iter();
+            let _ = map.into_iter();
         } else {
-            map.into_keys();
+            let _ = map.into_keys();
         }
     }
 
index 16150ceeb62c116a3a6e701ef74f0338785fe259..f4c1010098256f7637ad860f841c6092b4cd9362 100644 (file)
@@ -534,6 +534,7 @@ pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
     /// b.insert(1);
     /// assert_eq!(a.is_disjoint(&b), false);
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_disjoint(&self, other: &BTreeSet<T>) -> bool
     where
@@ -559,6 +560,7 @@ pub fn is_disjoint(&self, other: &BTreeSet<T>) -> bool
     /// set.insert(4);
     /// assert_eq!(set.is_subset(&sup), false);
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_subset(&self, other: &BTreeSet<T>) -> bool
     where
@@ -638,6 +640,7 @@ pub fn is_subset(&self, other: &BTreeSet<T>) -> bool
     /// set.insert(2);
     /// assert_eq!(set.is_superset(&sub), true);
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_superset(&self, other: &BTreeSet<T>) -> bool
     where
index dd04f782f940a805c2a3e16d2b88e6130fbcb03c..89ab11fb97e1035d06030d256c08542b8ed40227 100644 (file)
@@ -73,6 +73,7 @@
         not(test),
         not(any(test, bootstrap)),
         any(not(feature = "miri-test-libstd"), test, doctest),
+        no_global_oom_handling,
         target_has_atomic = "ptr"
     ))
 )]
index 81e97805a72142a65408b0ebba48e6ad3214bc75..c6573597b1e8c6ecc8da3de52261fd7ca3169089 100644 (file)
@@ -2130,6 +2130,7 @@ pub fn as_ptr(&self) -> *const T {
     ///
     /// [`from_raw`]: Weak::from_raw
     /// [`as_ptr`]: Weak::as_ptr
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn into_raw(self) -> *const T {
         let result = self.as_ptr();
index d88b8e398985a94565a81bae1ec41cb4851212f2..d00792b9c3e71961b8fb1c53e159f590ade168df 100644 (file)
@@ -676,6 +676,7 @@ pub fn from_utf16_lossy(v: &[u16]) -> String {
     /// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
     /// assert_eq!(rebuilt, "hello");
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
     pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
         self.vec.into_raw_parts()
@@ -781,6 +782,7 @@ pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
     /// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         self.vec
@@ -1738,6 +1740,7 @@ pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "box_str", since = "1.4.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_boxed_str(self) -> Box<str> {
         let slice = self.vec.into_boxed_slice();
@@ -1783,6 +1786,7 @@ pub fn as_bytes(&self) -> &[u8] {
     ///
     /// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         self.bytes
index 6e8da849e64cd464baf02714dc9d9f95a9fbaf6f..7dd1bc51560390b419d900ee65fe203766178c73 100644 (file)
@@ -735,6 +735,7 @@ impl<T> Arc<mem::MaybeUninit<T>> {
     /// assert_eq!(*five, 5)
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub unsafe fn assume_init(self) -> Arc<T> {
         Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
@@ -776,6 +777,7 @@ impl<T> Arc<[mem::MaybeUninit<T>]> {
     /// assert_eq!(*values, [1, 2, 3])
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub unsafe fn assume_init(self) -> Arc<[T]> {
         unsafe { Arc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _) }
@@ -1759,6 +1761,7 @@ pub fn as_ptr(&self) -> *const T {
     ///
     /// [`from_raw`]: Weak::from_raw
     /// [`as_ptr`]: Weak::as_ptr
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn into_raw(self) -> *const T {
         let result = self.as_ptr();
index 09329247f949228a35fe2fc8e64eb21087b2f530..8d5c0510404fb2d7743b8c547895acc5b5b1e2cd 100644 (file)
 #[stable(feature = "array_value_iter", since = "1.51.0")]
 pub use iter::IntoIter;
 
+/// Creates an array `[T; N]` where each array element `T` is returned by the `cb` call.
+///
+/// # Arguments
+///
+/// * `cb`: Callback where the passed argument is the current array index.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(array_from_fn)]
+///
+/// let array = core::array::from_fn(|i| i);
+/// assert_eq!(array, [0, 1, 2, 3, 4]);
+/// ```
+#[inline]
+#[unstable(feature = "array_from_fn", issue = "89379")]
+pub fn from_fn<F, T, const N: usize>(mut cb: F) -> [T; N]
+where
+    F: FnMut(usize) -> T,
+{
+    let mut idx = 0;
+    [(); N].map(|_| {
+        let res = cb(idx);
+        idx += 1;
+        res
+    })
+}
+
+/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
+/// Unlike `core::array::from_fn`, where the element creation can't fail, this version will return an error
+/// if any element creation was unsuccessful.
+///
+/// # Arguments
+///
+/// * `cb`: Callback where the passed argument is the current array index.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(array_from_fn)]
+///
+/// #[derive(Debug, PartialEq)]
+/// enum SomeError {
+///     Foo,
+/// }
+///
+/// let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
+/// assert_eq!(array, Ok([0, 1, 2, 3, 4]));
+///
+/// let another_array = core::array::try_from_fn::<SomeError, _, (), 2>(|_| Err(SomeError::Foo));
+/// assert_eq!(another_array, Err(SomeError::Foo));
+/// ```
+#[inline]
+#[unstable(feature = "array_from_fn", issue = "89379")]
+pub fn try_from_fn<E, F, T, const N: usize>(cb: F) -> Result<[T; N], E>
+where
+    F: FnMut(usize) -> Result<T, E>,
+{
+    // SAFETY: we know for certain that this iterator will yield exactly `N`
+    // items.
+    unsafe { collect_into_array_rslt_unchecked(&mut (0..N).map(cb)) }
+}
+
 /// Converts a reference to `T` into a reference to an array of length 1 (without copying).
 #[stable(feature = "array_from_ref", since = "1.53.0")]
 pub fn from_ref<T>(s: &T) -> &[T; 1] {
@@ -448,13 +511,15 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
 ///
 /// It is up to the caller to guarantee that `iter` yields at least `N` items.
 /// Violating this condition causes undefined behavior.
-unsafe fn collect_into_array_unchecked<I, const N: usize>(iter: &mut I) -> [I::Item; N]
+unsafe fn collect_into_array_rslt_unchecked<E, I, T, const N: usize>(
+    iter: &mut I,
+) -> Result<[T; N], E>
 where
     // Note: `TrustedLen` here is somewhat of an experiment. This is just an
     // internal function, so feel free to remove if this bound turns out to be a
     // bad idea. In that case, remember to also remove the lower bound
     // `debug_assert!` below!
-    I: Iterator + TrustedLen,
+    I: Iterator<Item = Result<T, E>> + TrustedLen,
 {
     debug_assert!(N <= iter.size_hint().1.unwrap_or(usize::MAX));
     debug_assert!(N <= iter.size_hint().0);
@@ -463,6 +528,21 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
     unsafe { collect_into_array(iter).unwrap_unchecked() }
 }
 
+// Infallible version of `collect_into_array_rslt_unchecked`.
+unsafe fn collect_into_array_unchecked<I, const N: usize>(iter: &mut I) -> [I::Item; N]
+where
+    I: Iterator + TrustedLen,
+{
+    let mut map = iter.map(Ok::<_, Infallible>);
+
+    // SAFETY: The same safety considerations w.r.t. the iterator length
+    // apply for `collect_into_array_rslt_unchecked` as for
+    // `collect_into_array_unchecked`
+    match unsafe { collect_into_array_rslt_unchecked(&mut map) } {
+        Ok(array) => array,
+    }
+}
+
 /// Pulls `N` items from `iter` and returns them as an array. If the iterator
 /// yields fewer than `N` items, `None` is returned and all already yielded
 /// items are dropped.
@@ -473,43 +553,49 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
 ///
 /// If `iter.next()` panicks, all items already yielded by the iterator are
 /// dropped.
-fn collect_into_array<I, const N: usize>(iter: &mut I) -> Option<[I::Item; N]>
+fn collect_into_array<E, I, T, const N: usize>(iter: &mut I) -> Option<Result<[T; N], E>>
 where
-    I: Iterator,
+    I: Iterator<Item = Result<T, E>>,
 {
     if N == 0 {
         // SAFETY: An empty array is always inhabited and has no validity invariants.
-        return unsafe { Some(mem::zeroed()) };
+        return unsafe { Some(Ok(mem::zeroed())) };
     }
 
-    struct Guard<T, const N: usize> {
-        ptr: *mut T,
+    struct Guard<'a, T, const N: usize> {
+        array_mut: &'a mut [MaybeUninit<T>; N],
         initialized: usize,
     }
 
-    impl<T, const N: usize> Drop for Guard<T, N> {
+    impl<T, const N: usize> Drop for Guard<'_, T, N> {
         fn drop(&mut self) {
             debug_assert!(self.initialized <= N);
 
-            let initialized_part = crate::ptr::slice_from_raw_parts_mut(self.ptr, self.initialized);
-
-            // SAFETY: this raw slice will contain only initialized objects.
+            // SAFETY: this slice will contain only initialized objects.
             unsafe {
-                crate::ptr::drop_in_place(initialized_part);
+                crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
+                    &mut self.array_mut.get_unchecked_mut(..self.initialized),
+                ));
             }
         }
     }
 
     let mut array = MaybeUninit::uninit_array::<N>();
-    let mut guard: Guard<_, N> =
-        Guard { ptr: MaybeUninit::slice_as_mut_ptr(&mut array), initialized: 0 };
+    let mut guard = Guard { array_mut: &mut array, initialized: 0 };
+
+    while let Some(item_rslt) = iter.next() {
+        let item = match item_rslt {
+            Err(err) => {
+                return Some(Err(err));
+            }
+            Ok(elem) => elem,
+        };
 
-    while let Some(item) = iter.next() {
         // SAFETY: `guard.initialized` starts at 0, is increased by one in the
         // loop and the loop is aborted once it reaches N (which is
         // `array.len()`).
         unsafe {
-            array.get_unchecked_mut(guard.initialized).write(item);
+            guard.array_mut.get_unchecked_mut(guard.initialized).write(item);
         }
         guard.initialized += 1;
 
@@ -520,7 +606,7 @@ fn drop(&mut self) {
             // SAFETY: the condition above asserts that all elements are
             // initialized.
             let out = unsafe { MaybeUninit::array_assume_init(array) };
-            return Some(out);
+            return Some(Ok(out));
         }
     }
 
index 025ad54b539f5e72a133645eb53b54ab64cfcd1a..2ca077a98f8dc7500d4569274eb7143a80aee59c 100644 (file)
@@ -349,7 +349,7 @@ pub fn set(&self, val: T) {
         drop(old);
     }
 
-    /// Swaps the values of two Cells.
+    /// Swaps the values of two `Cell`s.
     /// Difference with `std::mem::swap` is that this function doesn't require `&mut` reference.
     ///
     /// # Examples
index b3af1f1ffb5928dd00556dfa884c6b98804b06a1..45f7540d314bec77e8e726a50ff6c11c210f5347 100644 (file)
@@ -377,6 +377,8 @@ pub fn to_digit(self, radix: u32) -> Option<u32> {
     /// ```
     /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
     /// ```
+    #[must_use = "this returns the escaped char as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn escape_unicode(self) -> EscapeUnicode {
@@ -453,6 +455,8 @@ pub(crate) fn escape_debug_ext(self, args: EscapeDebugExtArgs) -> EscapeDebug {
     /// ```
     /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
     /// ```
+    #[must_use = "this returns the escaped char as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "char_escape_debug", since = "1.20.0")]
     #[inline]
     pub fn escape_debug(self) -> EscapeDebug {
@@ -507,6 +511,8 @@ pub fn escape_debug(self) -> EscapeDebug {
     /// ```
     /// assert_eq!('"'.escape_default().to_string(), "\\\"");
     /// ```
+    #[must_use = "this returns the escaped char as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn escape_default(self) -> EscapeDefault {
@@ -692,6 +698,7 @@ pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
     /// // love is many things, but it is not alphabetic
     /// assert!(!c.is_alphabetic());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_alphabetic(self) -> bool {
@@ -724,6 +731,7 @@ pub fn is_alphabetic(self) -> bool {
     /// assert!(!'中'.is_lowercase());
     /// assert!(!' '.is_lowercase());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_lowercase(self) -> bool {
@@ -756,6 +764,7 @@ pub fn is_lowercase(self) -> bool {
     /// assert!(!'中'.is_uppercase());
     /// assert!(!' '.is_uppercase());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_uppercase(self) -> bool {
@@ -784,6 +793,7 @@ pub fn is_uppercase(self) -> bool {
     ///
     /// assert!(!'越'.is_whitespace());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_whitespace(self) -> bool {
@@ -812,6 +822,7 @@ pub fn is_whitespace(self) -> bool {
     /// assert!('و'.is_alphanumeric());
     /// assert!('藏'.is_alphanumeric());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_alphanumeric(self) -> bool {
@@ -837,6 +848,7 @@ pub fn is_alphanumeric(self) -> bool {
     /// assert!('\9c'.is_control());
     /// assert!(!'q'.is_control());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_control(self) -> bool {
@@ -852,6 +864,7 @@ pub fn is_control(self) -> bool {
     /// [uax29]: https://www.unicode.org/reports/tr29/
     /// [ucd]: https://www.unicode.org/reports/tr44/
     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
+    #[must_use]
     #[inline]
     pub(crate) fn is_grapheme_extended(self) -> bool {
         unicode::Grapheme_Extend(self)
@@ -881,6 +894,7 @@ pub(crate) fn is_grapheme_extended(self) -> bool {
     /// assert!(!'و'.is_numeric());
     /// assert!(!'藏'.is_numeric());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_numeric(self) -> bool {
@@ -1060,6 +1074,7 @@ pub fn to_uppercase(self) -> ToUppercase {
     /// assert!(ascii.is_ascii());
     /// assert!(!non_ascii.is_ascii());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")]
     #[inline]
@@ -1237,6 +1252,7 @@ pub fn make_ascii_lowercase(&mut self) {
     /// assert!(!lf.is_ascii_alphabetic());
     /// assert!(!esc.is_ascii_alphabetic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1270,6 +1286,7 @@ pub const fn is_ascii_alphabetic(&self) -> bool {
     /// assert!(!lf.is_ascii_uppercase());
     /// assert!(!esc.is_ascii_uppercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1303,6 +1320,7 @@ pub const fn is_ascii_uppercase(&self) -> bool {
     /// assert!(!lf.is_ascii_lowercase());
     /// assert!(!esc.is_ascii_lowercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1339,6 +1357,7 @@ pub const fn is_ascii_lowercase(&self) -> bool {
     /// assert!(!lf.is_ascii_alphanumeric());
     /// assert!(!esc.is_ascii_alphanumeric());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1372,6 +1391,7 @@ pub const fn is_ascii_alphanumeric(&self) -> bool {
     /// assert!(!lf.is_ascii_digit());
     /// assert!(!esc.is_ascii_digit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1408,6 +1428,7 @@ pub const fn is_ascii_digit(&self) -> bool {
     /// assert!(!lf.is_ascii_hexdigit());
     /// assert!(!esc.is_ascii_hexdigit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1445,6 +1466,7 @@ pub const fn is_ascii_hexdigit(&self) -> bool {
     /// assert!(!lf.is_ascii_punctuation());
     /// assert!(!esc.is_ascii_punctuation());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1478,6 +1500,7 @@ pub const fn is_ascii_punctuation(&self) -> bool {
     /// assert!(!lf.is_ascii_graphic());
     /// assert!(!esc.is_ascii_graphic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1528,6 +1551,7 @@ pub const fn is_ascii_graphic(&self) -> bool {
     /// assert!(lf.is_ascii_whitespace());
     /// assert!(!esc.is_ascii_whitespace());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1563,6 +1587,7 @@ pub const fn is_ascii_whitespace(&self) -> bool {
     /// assert!(lf.is_ascii_control());
     /// assert!(esc.is_ascii_control());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
index da3f20d18e5108f9b5cc1a6ce10e014df78a8f2b..540160bc4c2a4daadc4d040c58dc529b3d758fe4 100644 (file)
 /// Thankfully, you won't need to worry about upholding this property when
 /// deriving both [`Eq`] and `Hash` with `#[derive(PartialEq, Eq, Hash)]`.
 ///
+/// ## Prefix collisions
+///
+/// Implementations of `hash` should ensure that the data they
+/// pass to the `Hasher` are prefix-free. That is,
+/// unequal values should cause two different sequences of values to be written,
+/// and neither of the two sequences should be a prefix of the other.
+///
+/// For example, the standard implementation of [`Hash` for `&str`][impl] passes an extra
+/// `0xFF` byte to the `Hasher` so that the values `("ab", "c")` and `("a",
+/// "bc")` hash differently.
+///
 /// [`HashMap`]: ../../std/collections/struct.HashMap.html
 /// [`HashSet`]: ../../std/collections/struct.HashSet.html
 /// [`hash`]: Hash::hash
+/// [impl]: ../../std/primitive.str.html#impl-Hash
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Hash"]
 pub trait Hash {
index e10d01b58b017396c5630bff8db8abc00eb25b6f..7bc641c52767d6a19f3961f478f1adee6d98e30a 100644 (file)
@@ -65,6 +65,7 @@
     doc(cfg_hide(
         not(test),
         any(not(feature = "miri-test-libstd"), test, doctest),
+        no_fp_fmt_parse,
         target_pointer_width = "16",
         target_pointer_width = "32",
         target_pointer_width = "64",
index c47a2e8b05c4bed0b75c2ffca61ba342d8073feb..4073a38b3cd858577996796cae20c93c0747812c 100644 (file)
@@ -436,6 +436,7 @@ impl f32 {
     /// assert!(nan.is_nan());
     /// assert!(!f.is_nan());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -467,6 +468,7 @@ const fn abs_private(self) -> f32 {
     /// assert!(inf.is_infinite());
     /// assert!(neg_inf.is_infinite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -488,6 +490,7 @@ pub const fn is_infinite(self) -> bool {
     /// assert!(!inf.is_finite());
     /// assert!(!neg_inf.is_finite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -515,6 +518,7 @@ pub const fn is_finite(self) -> bool {
     /// assert!(lower_than_min.is_subnormal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "is_subnormal", since = "1.53.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -541,6 +545,7 @@ pub const fn is_subnormal(self) -> bool {
     /// assert!(!lower_than_min.is_normal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -587,6 +592,7 @@ pub const fn classify(self) -> FpCategory {
     /// assert!(f.is_sign_positive());
     /// assert!(!g.is_sign_positive());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -604,6 +610,7 @@ pub const fn is_sign_positive(self) -> bool {
     /// assert!(!f.is_sign_negative());
     /// assert!(g.is_sign_negative());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -636,6 +643,8 @@ pub fn recip(self) -> f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
     #[inline]
     pub fn to_degrees(self) -> f32 {
@@ -653,6 +662,8 @@ pub fn to_degrees(self) -> f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
     #[inline]
     pub fn to_radians(self) -> f32 {
@@ -712,6 +723,8 @@ pub fn min(self, other: f32) -> f32 {
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type `Int`, after truncating off its fractional part
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
     #[inline]
     pub unsafe fn to_int_unchecked<Int>(self) -> Int
@@ -740,6 +753,8 @@ pub unsafe fn to_int_unchecked<Int>(self) -> Int
     /// assert_eq!((12.5f32).to_bits(), 0x41480000);
     ///
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -802,6 +817,8 @@ pub const fn from_bits(v: u32) -> Self {
     /// let bytes = 12.5f32.to_be_bytes();
     /// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -818,6 +835,8 @@ pub const fn from_bits(v: u32) -> Self {
     /// let bytes = 12.5f32.to_le_bytes();
     /// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -847,6 +866,8 @@ pub const fn from_bits(v: u32) -> Self {
     ///     }
     /// );
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
index cfcc08b9addeb9b26fa07152161ec8549b744b11..c6ccff0398000c8ec8978b2052238d2bbf27b34b 100644 (file)
@@ -435,6 +435,7 @@ impl f64 {
     /// assert!(nan.is_nan());
     /// assert!(!f.is_nan());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -466,6 +467,7 @@ const fn abs_private(self) -> f64 {
     /// assert!(inf.is_infinite());
     /// assert!(neg_inf.is_infinite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -487,6 +489,7 @@ pub const fn is_infinite(self) -> bool {
     /// assert!(!inf.is_finite());
     /// assert!(!neg_inf.is_finite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -514,6 +517,7 @@ pub const fn is_finite(self) -> bool {
     /// assert!(lower_than_min.is_subnormal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "is_subnormal", since = "1.53.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -540,6 +544,7 @@ pub const fn is_subnormal(self) -> bool {
     /// assert!(!lower_than_min.is_normal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -586,6 +591,7 @@ pub const fn classify(self) -> FpCategory {
     /// assert!(f.is_sign_positive());
     /// assert!(!g.is_sign_positive());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -593,6 +599,7 @@ pub const fn is_sign_positive(self) -> bool {
         !self.is_sign_negative()
     }
 
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
     #[inline]
@@ -611,6 +618,7 @@ pub fn is_positive(self) -> bool {
     /// assert!(!f.is_sign_negative());
     /// assert!(g.is_sign_negative());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -618,6 +626,7 @@ pub const fn is_sign_negative(self) -> bool {
         self.to_bits() & 0x8000_0000_0000_0000 != 0
     }
 
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
     #[inline]
@@ -649,6 +658,8 @@ pub fn recip(self) -> f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_degrees(self) -> f64 {
@@ -667,6 +678,8 @@ pub fn to_degrees(self) -> f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_radians(self) -> f64 {
@@ -726,6 +739,8 @@ pub fn min(self, other: f64) -> f64 {
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type `Int`, after truncating off its fractional part
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
     #[inline]
     pub unsafe fn to_int_unchecked<Int>(self) -> Int
@@ -754,6 +769,8 @@ pub unsafe fn to_int_unchecked<Int>(self) -> Int
     /// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
     ///
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -816,6 +833,8 @@ pub const fn from_bits(v: u64) -> Self {
     /// let bytes = 12.5f64.to_be_bytes();
     /// assert_eq!(bytes, [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -832,6 +851,8 @@ pub const fn from_bits(v: u64) -> Self {
     /// let bytes = 12.5f64.to_le_bytes();
     /// assert_eq!(bytes, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -861,6 +882,8 @@ pub const fn from_bits(v: u64) -> Self {
     ///     }
     /// );
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
index 12dda61400f2a62ccd816e9c9b2bb9abba0ce7fe..c90e301a9dd509a18d566487bd3ef3e164a25044 100644 (file)
@@ -81,6 +81,8 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[doc(alias = "popcount")]
         #[doc(alias = "popcnt")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
 
@@ -95,6 +97,8 @@ pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_zeros(self) -> u32 {
             (!self).count_ones()
@@ -113,6 +117,8 @@ pub const fn count_zeros(self) -> u32 {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_zeros(self) -> u32 {
             (self as $UnsignedT).leading_zeros()
@@ -131,6 +137,8 @@ pub const fn leading_zeros(self) -> u32 {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_zeros(self) -> u32 {
             (self as $UnsignedT).trailing_zeros()
@@ -149,6 +157,8 @@ pub const fn trailing_zeros(self) -> u32 {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_ones(self) -> u32 {
             (self as $UnsignedT).leading_ones()
@@ -167,6 +177,8 @@ pub const fn leading_ones(self) -> u32 {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_ones(self) -> u32 {
             (self as $UnsignedT).trailing_ones()
@@ -236,6 +248,8 @@ pub const fn rotate_right(self, n: u32) -> Self {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn swap_bytes(self) -> Self {
             (self as $UnsignedT).swap_bytes() as Self
@@ -257,8 +271,9 @@ pub const fn swap_bytes(self) -> Self {
         /// ```
         #[stable(feature = "reverse_bits", since = "1.37.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.37.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
-        #[must_use]
         pub const fn reverse_bits(self) -> Self {
             (self as $UnsignedT).reverse_bits() as Self
         }
@@ -344,6 +359,8 @@ pub const fn from_le(x: Self) -> Self {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_be(self) -> Self { // or not to be?
             #[cfg(target_endian = "big")]
@@ -375,6 +392,8 @@ pub const fn to_be(self) -> Self { // or not to be?
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_le(self) -> Self {
             #[cfg(target_endian = "little")]
@@ -689,6 +708,8 @@ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn checked_neg(self) -> Option<Self> {
             let (a, b) = self.overflowing_neg();
@@ -801,6 +822,8 @@ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
         /// ```
         #[stable(feature = "no_panic_abs", since = "1.13.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn checked_abs(self) -> Option<Self> {
             if self.is_negative() {
@@ -959,6 +982,8 @@ pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
 
         #[stable(feature = "saturating_neg", since = "1.45.0")]
         #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn saturating_neg(self) -> Self {
             intrinsics::saturating_sub(0, self)
@@ -980,6 +1005,8 @@ pub const fn saturating_neg(self) -> Self {
 
         #[stable(feature = "saturating_neg", since = "1.45.0")]
         #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn saturating_abs(self) -> Self {
             if self.is_negative() {
@@ -1308,6 +1335,8 @@ pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
             (0 as $SelfT).wrapping_sub(self)
@@ -1390,6 +1419,8 @@ pub const fn wrapping_shr(self, rhs: u32) -> Self {
         /// ```
         #[stable(feature = "no_panic_abs", since = "1.13.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[allow(unused_attributes)]
         #[inline]
         pub const fn wrapping_abs(self) -> Self {
@@ -1415,6 +1446,8 @@ pub const fn wrapping_abs(self) -> Self {
         /// ```
         #[stable(feature = "unsigned_abs", since = "1.51.0")]
         #[rustc_const_stable(feature = "unsigned_abs", since = "1.51.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn unsigned_abs(self) -> $UnsignedT {
              self.wrapping_abs() as $UnsignedT
@@ -1781,6 +1814,8 @@ pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[allow(unused_attributes)]
         pub const fn overflowing_neg(self) -> (Self, bool) {
             if unlikely!(self == Self::MIN) {
@@ -1855,6 +1890,8 @@ pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
         /// ```
         #[stable(feature = "no_panic_abs", since = "1.13.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn overflowing_abs(self) -> (Self, bool) {
             (self.wrapping_abs(), self == Self::MIN)
@@ -2199,7 +2236,8 @@ pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// This method might not be optimized owing to implementation details;
         /// `log2` can produce results more efficiently for base 2, and `log10`
@@ -2208,8 +2246,8 @@ pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
         /// # Panics
         ///
         /// When the number is zero, or if the base is not at least 2; it
-        /// panics in debug mode and the return value is wrapped to 0 in release
-        /// mode (the only situation in which the method can return 0).
+        /// panics in debug mode and the return value is 0 in release
+        /// mode.
         ///
         /// # Examples
         ///
@@ -2219,7 +2257,7 @@ pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -2237,13 +2275,12 @@ pub const fn log(self, base: Self) -> u32 {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is zero it panics in debug mode and the return value
-        /// is wrapped to 0 in release mode (the only situation in which the
-        /// method can return 0).
+        /// is 0 in release mode.
         ///
         /// # Examples
         ///
@@ -2253,7 +2290,7 @@ pub const fn log(self, base: Self) -> u32 {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -2271,13 +2308,12 @@ pub const fn log2(self) -> u32 {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is zero it panics in debug mode and the return value
-        /// is wrapped to 0 in release mode (the only situation in which the
-        /// method can return 0).
+        /// is 0 in release mode.
         ///
         /// # Example
         ///
@@ -2287,7 +2323,7 @@ pub const fn log2(self) -> u32 {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -2305,7 +2341,8 @@ pub const fn log10(self) -> u32 {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// Returns `None` if the number is negative or zero, or if the base is not at least 2.
         ///
@@ -2321,7 +2358,7 @@ pub const fn log10(self) -> u32 {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log(self, base: Self) -> Option<u32> {
             if self <= 0 || base <= 1 {
@@ -2345,7 +2382,7 @@ pub const fn checked_log(self, base: Self) -> Option<u32> {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is negative or zero.
         ///
@@ -2357,7 +2394,7 @@ pub const fn checked_log(self, base: Self) -> Option<u32> {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log2(self) -> Option<u32> {
             if self <= 0 {
@@ -2369,7 +2406,7 @@ pub const fn checked_log2(self) -> Option<u32> {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is negative or zero.
         ///
@@ -2381,7 +2418,7 @@ pub const fn checked_log2(self) -> Option<u32> {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log10(self) -> Option<u32> {
             int_log10::$ActualT(self as $ActualT)
@@ -2412,6 +2449,8 @@ pub const fn checked_log10(self) -> Option<u32> {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[allow(unused_attributes)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn abs(self) -> Self {
@@ -2443,6 +2482,8 @@ pub const fn abs(self) -> Self {
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.abs_diff(", stringify!($SelfT), "::MAX), ", stringify!($UnsignedT), "::MAX);")]
         /// ```
         #[unstable(feature = "int_abs_diff", issue = "89492")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn abs_diff(self, other: Self) -> $UnsignedT {
             if self < other {
@@ -2482,6 +2523,8 @@ pub const fn abs_diff(self, other: Self) -> $UnsignedT {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_sign", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn signum(self) -> Self {
             match self {
@@ -2502,6 +2545,7 @@ pub const fn signum(self) -> Self {
         #[doc = concat!("assert!(10", stringify!($SelfT), ".is_positive());")]
         #[doc = concat!("assert!(!(-10", stringify!($SelfT), ").is_positive());")]
         /// ```
+        #[must_use]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[inline(always)]
@@ -2518,6 +2562,7 @@ pub const fn is_positive(self) -> bool { self > 0 }
         #[doc = concat!("assert!((-10", stringify!($SelfT), ").is_negative());")]
         #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_negative());")]
         /// ```
+        #[must_use]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[inline(always)]
@@ -2536,6 +2581,8 @@ pub const fn is_negative(self) -> bool { self < 0 }
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_be().to_ne_bytes()
@@ -2554,6 +2601,8 @@ pub const fn is_negative(self) -> bool { self < 0 }
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_le().to_ne_bytes()
@@ -2588,6 +2637,8 @@ pub const fn is_negative(self) -> bool { self < 0 }
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute them to arrays of bytes
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
             // SAFETY: integers are plain old datatypes so we can always transmute them to
index 44918a711d47046e7955b7e9bc9c4c2c5a3ac826..18ebf1cbb1063e51fe3a9970612054d075f2f390 100644 (file)
@@ -259,6 +259,7 @@ impl u8 {
     /// assert!(ascii.is_ascii());
     /// assert!(!non_ascii.is_ascii());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")]
     #[inline]
@@ -419,6 +420,7 @@ pub fn make_ascii_lowercase(&mut self) {
     /// assert!(!lf.is_ascii_alphabetic());
     /// assert!(!esc.is_ascii_alphabetic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -452,6 +454,7 @@ pub const fn is_ascii_alphabetic(&self) -> bool {
     /// assert!(!lf.is_ascii_uppercase());
     /// assert!(!esc.is_ascii_uppercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -485,6 +488,7 @@ pub const fn is_ascii_uppercase(&self) -> bool {
     /// assert!(!lf.is_ascii_lowercase());
     /// assert!(!esc.is_ascii_lowercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -521,6 +525,7 @@ pub const fn is_ascii_lowercase(&self) -> bool {
     /// assert!(!lf.is_ascii_alphanumeric());
     /// assert!(!esc.is_ascii_alphanumeric());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -554,6 +559,7 @@ pub const fn is_ascii_alphanumeric(&self) -> bool {
     /// assert!(!lf.is_ascii_digit());
     /// assert!(!esc.is_ascii_digit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -590,6 +596,7 @@ pub const fn is_ascii_digit(&self) -> bool {
     /// assert!(!lf.is_ascii_hexdigit());
     /// assert!(!esc.is_ascii_hexdigit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -627,6 +634,7 @@ pub const fn is_ascii_hexdigit(&self) -> bool {
     /// assert!(!lf.is_ascii_punctuation());
     /// assert!(!esc.is_ascii_punctuation());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -660,6 +668,7 @@ pub const fn is_ascii_punctuation(&self) -> bool {
     /// assert!(!lf.is_ascii_graphic());
     /// assert!(!esc.is_ascii_graphic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -710,6 +719,7 @@ pub const fn is_ascii_graphic(&self) -> bool {
     /// assert!(lf.is_ascii_whitespace());
     /// assert!(!esc.is_ascii_whitespace());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -745,6 +755,7 @@ pub const fn is_ascii_whitespace(&self) -> bool {
     /// assert!(lf.is_ascii_control());
     /// assert!(esc.is_ascii_control());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
index e44597279baf232b930e9b9844a4324dc750337b..4bb659db3a011137eb9e590ed4435d404c4d84f5 100644 (file)
@@ -198,6 +198,8 @@ impl $Ty {
                 /// ```
                 #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                 #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn leading_zeros(self) -> u32 {
                     // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
@@ -220,6 +222,8 @@ pub const fn leading_zeros(self) -> u32 {
                 /// ```
                 #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                 #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn trailing_zeros(self) -> u32 {
                     // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
@@ -315,6 +319,8 @@ impl $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_add(other) {
@@ -348,6 +354,8 @@ pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_add(self, other: $Int) -> $Ty {
                     // SAFETY: $Int::saturating_add returns $Int::MAX on overflow
@@ -378,6 +386,8 @@ pub const fn saturating_add(self, other: $Int) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty {
                     // SAFETY: The caller ensures there is no overflow.
@@ -410,6 +420,8 @@ pub const fn saturating_add(self, other: $Int) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
                     if let Some(nz) = self.get().checked_next_power_of_two() {
@@ -460,6 +472,8 @@ impl $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn abs(self) -> $Ty {
                     // SAFETY: This cannot overflow to zero.
@@ -490,6 +504,8 @@ pub const fn abs(self) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_abs(self) -> Option<$Ty> {
                     if let Some(nz) = self.get().checked_abs() {
@@ -524,6 +540,8 @@ pub const fn checked_abs(self) -> Option<$Ty> {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn overflowing_abs(self) -> ($Ty, bool) {
                     let (nz, flag) = self.get().overflowing_abs();
@@ -562,6 +580,8 @@ pub const fn overflowing_abs(self) -> ($Ty, bool) {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_abs(self) -> $Ty {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
@@ -595,6 +615,8 @@ pub const fn saturating_abs(self) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn wrapping_abs(self) -> $Ty {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
@@ -628,6 +650,8 @@ pub const fn wrapping_abs(self) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn unsigned_abs(self) -> $Uty {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
@@ -675,6 +699,8 @@ impl $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_mul(other.get()) {
@@ -709,6 +735,8 @@ pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_mul(self, other: $Ty) -> $Ty {
                     // SAFETY: saturating_mul returns u*::MAX on overflow
@@ -749,6 +777,8 @@ pub const fn saturating_mul(self, other: $Ty) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
                     // SAFETY: The caller ensures there is no overflow.
@@ -778,6 +808,8 @@ pub const fn saturating_mul(self, other: $Ty) -> $Ty {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_pow(other) {
@@ -820,6 +852,8 @@ pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_pow(self, other: u32) -> $Ty {
                     // SAFETY: saturating_pow returns u*::MAX on overflow
@@ -878,6 +912,7 @@ impl $Ty {
                 #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
                 /// assert!(!ten.is_power_of_two());
                 /// ```
+                #[must_use]
                 #[unstable(feature = "nonzero_is_power_of_two", issue = "81106")]
                 #[inline]
                 pub const fn is_power_of_two(self) -> bool {
index f6dd3603c491431cc9b31931d7fdf0a51f73fe0f..eeaaf38e61dfb7480f7199d1d3b92e0fbf294ffa 100644 (file)
@@ -474,6 +474,8 @@ impl Saturating<$t> {
             #[inline]
             #[doc(alias = "popcount")]
             #[doc(alias = "popcnt")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn count_ones(self) -> u32 {
                 self.0.count_ones()
@@ -492,6 +494,8 @@ pub const fn count_ones(self) -> u32 {
             #[doc = concat!("assert_eq!(Saturating(!0", stringify!($t), ").count_zeros(), 0);")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn count_zeros(self) -> u32 {
                 self.0.count_zeros()
@@ -512,6 +516,8 @@ pub const fn count_zeros(self) -> u32 {
             /// assert_eq!(n.trailing_zeros(), 3);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn trailing_zeros(self) -> u32 {
                 self.0.trailing_zeros()
@@ -538,6 +544,8 @@ pub const fn trailing_zeros(self) -> u32 {
             /// assert_eq!(n.rotate_left(32), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn rotate_left(self, n: u32) -> Self {
                 Saturating(self.0.rotate_left(n))
@@ -564,6 +572,8 @@ pub const fn rotate_left(self, n: u32) -> Self {
             /// assert_eq!(n.rotate_right(4), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn rotate_right(self, n: u32) -> Self {
                 Saturating(self.0.rotate_right(n))
@@ -588,6 +598,8 @@ pub const fn rotate_right(self, n: u32) -> Self {
             /// assert_eq!(m, Saturating(21760));
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn swap_bytes(self) -> Self {
                 Saturating(self.0.swap_bytes())
@@ -614,10 +626,11 @@ pub const fn swap_bytes(self) -> Self {
             /// assert_eq!(m.0 as u16, 0b10101010_00000000);
             /// assert_eq!(m, Saturating(-22016));
             /// ```
+            #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
-            #[inline]
-            #[must_use]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn reverse_bits(self) -> Self {
                 Saturating(self.0.reverse_bits())
             }
@@ -699,6 +712,8 @@ pub const fn from_le(x: Self) -> Self {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn to_be(self) -> Self {
                 Saturating(self.0.to_be())
             }
@@ -726,6 +741,8 @@ pub const fn to_be(self) -> Self {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn to_le(self) -> Self {
                 Saturating(self.0.to_le())
             }
@@ -754,6 +771,8 @@ pub const fn to_le(self) -> Self {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub fn pow(self, exp: u32) -> Self {
                 Saturating(self.0.saturating_pow(exp))
             }
@@ -782,6 +801,8 @@ impl Saturating<$t> {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
             }
@@ -805,6 +826,8 @@ pub const fn leading_zeros(self) -> u32 {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub fn abs(self) -> Saturating<$t> {
                 Saturating(self.0.saturating_abs())
             }
@@ -829,6 +852,8 @@ pub fn abs(self) -> Saturating<$t> {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub fn signum(self) -> Saturating<$t> {
                 Saturating(self.0.signum())
             }
@@ -847,6 +872,7 @@ pub fn signum(self) -> Saturating<$t> {
             #[doc = concat!("assert!(Saturating(10", stringify!($t), ").is_positive());")]
             #[doc = concat!("assert!(!Saturating(-10", stringify!($t), ").is_positive());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn is_positive(self) -> bool {
@@ -867,6 +893,7 @@ pub const fn is_positive(self) -> bool {
             #[doc = concat!("assert!(Saturating(-10", stringify!($t), ").is_negative());")]
             #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_negative());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn is_negative(self) -> bool {
@@ -908,6 +935,8 @@ impl Saturating<$t> {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
             }
@@ -925,6 +954,7 @@ pub const fn leading_zeros(self) -> u32 {
             #[doc = concat!("assert!(Saturating(16", stringify!($t), ").is_power_of_two());")]
             #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_power_of_two());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub fn is_power_of_two(self) -> bool {
index 25cd582bb67d7a3fd98087fa3f2cd417080b2f9e..2a3663f2c0fdeeb02ae17c77e773b10fe3fd89e9 100644 (file)
@@ -80,6 +80,8 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
         #[doc(alias = "popcount")]
         #[doc(alias = "popcnt")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_ones(self) -> u32 {
             intrinsics::ctpop(self as $ActualT) as u32
@@ -96,6 +98,8 @@ pub const fn count_ones(self) -> u32 {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_zeros(self) -> u32 {
             (!self).count_ones()
@@ -114,6 +118,8 @@ pub const fn count_zeros(self) -> u32 {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_zeros(self) -> u32 {
             intrinsics::ctlz(self as $ActualT) as u32
@@ -133,6 +139,8 @@ pub const fn leading_zeros(self) -> u32 {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_zeros(self) -> u32 {
             intrinsics::cttz(self) as u32
@@ -151,6 +159,8 @@ pub const fn trailing_zeros(self) -> u32 {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_ones(self) -> u32 {
             (!self).leading_zeros()
@@ -170,6 +180,8 @@ pub const fn leading_ones(self) -> u32 {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_ones(self) -> u32 {
             (!self).trailing_zeros()
@@ -238,6 +250,8 @@ pub const fn rotate_right(self, n: u32) -> Self {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn swap_bytes(self) -> Self {
             intrinsics::bswap(self as $ActualT) as Self
@@ -259,8 +273,9 @@ pub const fn swap_bytes(self) -> Self {
         /// ```
         #[stable(feature = "reverse_bits", since = "1.37.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.37.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
-        #[must_use]
         pub const fn reverse_bits(self) -> Self {
             intrinsics::bitreverse(self as $ActualT) as Self
         }
@@ -349,6 +364,8 @@ pub const fn from_le(x: Self) -> Self {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn to_be(self) -> Self { // or not to be?
             #[cfg(target_endian = "big")]
@@ -381,6 +398,8 @@ pub const fn to_be(self) -> Self { // or not to be?
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn to_le(self) -> Self {
             #[cfg(target_endian = "little")]
@@ -658,7 +677,8 @@ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// This method might not be optimized owing to implementation details;
         /// `log2` can produce results more efficiently for base 2, and `log10`
@@ -667,8 +687,7 @@ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
         /// # Panics
         ///
         /// When the number is negative, zero, or if the base is not at least 2;
-        /// it panics in debug mode and the return value is wrapped to 0 in
-        /// release mode (the only situation in which the method can return 0).
+        /// it panics in debug mode and the return value is 0 in release mode.
         ///
         /// # Examples
         ///
@@ -678,7 +697,7 @@ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -696,13 +715,12 @@ pub const fn log(self, base: Self) -> u32 {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is negative or zero it panics in debug mode and
-        /// the return value is wrapped to 0 in release mode (the only situation in
-        /// which the method can return 0).
+        /// the return value is 0 in release mode.
         ///
         /// # Examples
         ///
@@ -712,7 +730,7 @@ pub const fn log(self, base: Self) -> u32 {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -730,13 +748,12 @@ pub const fn log2(self) -> u32 {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is negative or zero it panics in debug mode and the
-        /// return value is wrapped to 0 in release mode (the only situation in
-        /// which the method can return 0).
+        /// return value is 0 in release mode.
         ///
         /// # Example
         ///
@@ -746,7 +763,7 @@ pub const fn log2(self) -> u32 {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -764,7 +781,8 @@ pub const fn log10(self) -> u32 {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// Returns `None` if the number is zero, or if the base is not at least 2.
         ///
@@ -780,7 +798,7 @@ pub const fn log10(self) -> u32 {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log(self, base: Self) -> Option<u32> {
             if self <= 0 || base <= 1 {
@@ -804,7 +822,7 @@ pub const fn checked_log(self, base: Self) -> Option<u32> {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is zero.
         ///
@@ -816,7 +834,7 @@ pub const fn checked_log(self, base: Self) -> Option<u32> {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log2(self) -> Option<u32> {
             if self <= 0 {
@@ -828,7 +846,7 @@ pub const fn checked_log2(self) -> Option<u32> {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is zero.
         ///
@@ -840,7 +858,7 @@ pub const fn checked_log2(self) -> Option<u32> {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log10(self) -> Option<u32> {
             int_log10::$ActualT(self as $ActualT)
@@ -861,6 +879,8 @@ pub const fn checked_log10(self) -> Option<u32> {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn checked_neg(self) -> Option<Self> {
             let (a, b) = self.overflowing_neg();
@@ -1222,7 +1242,7 @@ pub const fn wrapping_sub(self, rhs: Self) -> Self {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
         #[must_use = "this returns the result of the operation, \
-                          without modifying the original"]
+                      without modifying the original"]
         #[inline(always)]
         pub const fn wrapping_mul(self, rhs: Self) -> Self {
             intrinsics::wrapping_mul(self, rhs)
@@ -1347,6 +1367,8 @@ pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
             (0 as $SelfT).wrapping_sub(self)
@@ -1602,6 +1624,8 @@ pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($SelfT), ");")]
         /// ```
         #[unstable(feature = "int_abs_diff", issue = "89492")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn abs_diff(self, other: Self) -> Self {
             if mem::size_of::<Self>() == 1 {
@@ -1776,6 +1800,8 @@ pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
         #[inline(always)]
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         pub const fn overflowing_neg(self) -> (Self, bool) {
             ((!self).wrapping_add(1), self != 0)
         }
@@ -1892,7 +1918,7 @@ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
         #[must_use = "this returns the result of the operation, \
-                          without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn pow(self, mut exp: u32) -> Self {
@@ -1989,6 +2015,8 @@ pub const fn rem_euclid(self, rhs: Self) -> Self {
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_floor(4), 1);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         #[rustc_inherit_overflow_checks]
         pub const fn unstable_div_floor(self, rhs: Self) -> Self {
@@ -2010,6 +2038,8 @@ pub const fn unstable_div_floor(self, rhs: Self) -> Self {
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_ceil(4), 2);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn unstable_div_ceil(self, rhs: Self) -> Self {
@@ -2087,6 +2117,7 @@ pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
         #[doc = concat!("assert!(16", stringify!($SelfT), ".is_power_of_two());")]
         #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_power_of_two());")]
         /// ```
+        #[must_use]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0")]
         #[inline(always)]
@@ -2120,7 +2151,7 @@ const fn one_less_than_next_power_of_two(self) -> Self {
         /// Returns the smallest power of two greater than or equal to `self`.
         ///
         /// When return value overflows (i.e., `self > (1 << (N-1))` for type
-        /// `uN`), it panics in debug mode and return value is wrapped to 0 in
+        /// `uN`), it panics in debug mode and the return value is wrapped to 0 in
         /// release mode (the only situation in which method can return 0).
         ///
         /// # Examples
@@ -2133,6 +2164,8 @@ const fn one_less_than_next_power_of_two(self) -> Self {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn next_power_of_two(self) -> Self {
@@ -2155,6 +2188,8 @@ pub const fn next_power_of_two(self) -> Self {
         #[inline]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         pub const fn checked_next_power_of_two(self) -> Option<Self> {
             self.one_less_than_next_power_of_two().checked_add(1)
         }
@@ -2177,6 +2212,8 @@ pub const fn checked_next_power_of_two(self) -> Option<Self> {
         #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
                    reason = "needs decision on wrapping behaviour")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         pub const fn wrapping_next_power_of_two(self) -> Self {
             self.one_less_than_next_power_of_two().wrapping_add(1)
         }
@@ -2194,6 +2231,8 @@ pub const fn wrapping_next_power_of_two(self) -> Self {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_be().to_ne_bytes()
@@ -2212,6 +2251,8 @@ pub const fn wrapping_next_power_of_two(self) -> Self {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_le().to_ne_bytes()
@@ -2244,6 +2285,8 @@ pub const fn wrapping_next_power_of_two(self) -> Self {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute them to arrays of bytes
         #[inline]
index b078cdf5479d7ba536cfdefff4584cc369f4e44d..66620fc8fd14d5ce335012caa1b8954875298d7c 100644 (file)
@@ -469,6 +469,8 @@ impl Wrapping<$t> {
             #[inline]
             #[doc(alias = "popcount")]
             #[doc(alias = "popcnt")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn count_ones(self) -> u32 {
                 self.0.count_ones()
@@ -487,6 +489,8 @@ pub const fn count_ones(self) -> u32 {
             #[doc = concat!("assert_eq!(Wrapping(!0", stringify!($t), ").count_zeros(), 0);")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn count_zeros(self) -> u32 {
                 self.0.count_zeros()
@@ -507,6 +511,8 @@ pub const fn count_zeros(self) -> u32 {
             /// assert_eq!(n.trailing_zeros(), 3);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn trailing_zeros(self) -> u32 {
                 self.0.trailing_zeros()
@@ -533,6 +539,8 @@ pub const fn trailing_zeros(self) -> u32 {
             /// assert_eq!(n.rotate_left(32), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn rotate_left(self, n: u32) -> Self {
                 Wrapping(self.0.rotate_left(n))
@@ -559,6 +567,8 @@ pub const fn rotate_left(self, n: u32) -> Self {
             /// assert_eq!(n.rotate_right(4), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn rotate_right(self, n: u32) -> Self {
                 Wrapping(self.0.rotate_right(n))
@@ -583,6 +593,8 @@ pub const fn rotate_right(self, n: u32) -> Self {
             /// assert_eq!(m, Wrapping(21760));
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn swap_bytes(self) -> Self {
                 Wrapping(self.0.swap_bytes())
@@ -610,8 +622,9 @@ pub const fn swap_bytes(self) -> Self {
             /// ```
             #[stable(feature = "reverse_bits", since = "1.37.0")]
             #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[inline]
-            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 Wrapping(self.0.reverse_bits())
             }
@@ -692,6 +705,8 @@ pub const fn from_le(x: Self) -> Self {
             /// }
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn to_be(self) -> Self {
                 Wrapping(self.0.to_be())
@@ -719,6 +734,8 @@ pub const fn to_be(self) -> Self {
             /// }
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn to_le(self) -> Self {
                 Wrapping(self.0.to_le())
@@ -747,6 +764,8 @@ pub const fn to_le(self) -> Self {
             /// assert_eq!(Wrapping(3i8).pow(6), Wrapping(-39));
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn pow(self, exp: u32) -> Self {
                 Wrapping(self.0.wrapping_pow(exp))
@@ -775,6 +794,8 @@ impl Wrapping<$t> {
             /// assert_eq!(n.leading_zeros(), 3);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
@@ -801,6 +822,8 @@ pub const fn leading_zeros(self) -> u32 {
             /// assert_eq!(Wrapping(-128i8).abs().0 as u8, 128u8);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn abs(self) -> Wrapping<$t> {
                 Wrapping(self.0.wrapping_abs())
@@ -825,6 +848,8 @@ pub fn abs(self) -> Wrapping<$t> {
             #[doc = concat!("assert_eq!(Wrapping(-10", stringify!($t), ").signum(), Wrapping(-1));")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn signum(self) -> Wrapping<$t> {
                 Wrapping(self.0.signum())
@@ -844,6 +869,7 @@ pub fn signum(self) -> Wrapping<$t> {
             #[doc = concat!("assert!(Wrapping(10", stringify!($t), ").is_positive());")]
             #[doc = concat!("assert!(!Wrapping(-10", stringify!($t), ").is_positive());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn is_positive(self) -> bool {
@@ -864,6 +890,7 @@ pub const fn is_positive(self) -> bool {
             #[doc = concat!("assert!(Wrapping(-10", stringify!($t), ").is_negative());")]
             #[doc = concat!("assert!(!Wrapping(10", stringify!($t), ").is_negative());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn is_negative(self) -> bool {
@@ -893,6 +920,8 @@ impl Wrapping<$t> {
             /// assert_eq!(n.leading_zeros(), 2);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
@@ -911,6 +940,7 @@ pub const fn leading_zeros(self) -> u32 {
             #[doc = concat!("assert!(Wrapping(16", stringify!($t), ").is_power_of_two());")]
             #[doc = concat!("assert!(!Wrapping(10", stringify!($t), ").is_power_of_two());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn is_power_of_two(self) -> bool {
@@ -935,6 +965,8 @@ pub fn is_power_of_two(self) -> bool {
             #[doc = concat!("assert_eq!(Wrapping(200_u8).next_power_of_two(), Wrapping(0));")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
                        reason = "needs decision on wrapping behaviour")]
             pub fn next_power_of_two(self) -> Self {
index 3259e142a0c2ac0e5075b4755c1a2ff278804449..df8af22a317bcbe7ce1eeb58b7a3d7e2452d555f 100644 (file)
@@ -1473,6 +1473,7 @@ impl<T: Copy> Option<&mut T> {
     /// let copied = opt_x.copied();
     /// assert_eq!(copied, Some(12));
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "copied", since = "1.35.0")]
     pub fn copied(self) -> Option<T> {
         self.map(|&mut t| t)
@@ -1492,6 +1493,7 @@ impl<T: Clone> Option<&T> {
     /// let cloned = opt_x.cloned();
     /// assert_eq!(cloned, Some(12));
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn cloned(self) -> Option<T> {
         self.map(|t| t.clone())
index 8b645792169155aba160c46382db7721b776265c..34fc874ada09b7171017fcf43f9ec3b01462ab31 100644 (file)
@@ -715,6 +715,7 @@ pub const fn get_ref(self) -> &'a T {
 impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
     #[inline(always)]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin", since = "1.33.0")]
     pub const fn into_ref(self) -> Pin<&'a T> {
@@ -731,6 +732,7 @@ pub const fn into_ref(self) -> Pin<&'a T> {
     /// the `Pin` itself. This method allows turning the `Pin` into a reference
     /// with the same lifetime as the original `Pin`.
     #[inline(always)]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "pin", since = "1.33.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const fn get_mut(self) -> &'a mut T
@@ -751,6 +753,7 @@ pub const fn get_mut(self) -> &'a mut T
     /// If the underlying data is `Unpin`, `Pin::get_mut` should be used
     /// instead.
     #[inline(always)]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "pin", since = "1.33.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const unsafe fn get_unchecked_mut(self) -> &'a mut T {
@@ -772,6 +775,7 @@ pub const fn get_mut(self) -> &'a mut T
     /// not move out of the argument you receive to the interior function.
     ///
     /// [`pin` module]: self#projections-and-structural-pinning
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "pin", since = "1.33.0")]
     pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
     where
@@ -811,6 +815,7 @@ impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
     /// implementations of `P::DerefMut` are likewise ruled out by the contract of
     /// `Pin::new_unchecked`.
     #[unstable(feature = "pin_deref_mut", issue = "86918")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline(always)]
     pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> {
         // SAFETY: What we're asserting here is that going from
index cd6afdccc29d7a5f2ad5fe2c1899203694d9545e..b3deddca18efea9801175a809bf3d5cc4d2db05e 100644 (file)
@@ -101,6 +101,7 @@ pub fn new(ptr: *mut T) -> Option<Self> {
     }
 
     /// Acquires the underlying `*mut` pointer.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub const fn as_ptr(self) -> *mut T {
         self.pointer as *mut T
@@ -131,6 +132,7 @@ pub unsafe fn as_mut(&mut self) -> &mut T {
     }
 
     /// Casts to a pointer of another type.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub const fn cast<U>(self) -> Unique<U> {
         // SAFETY: Unique::new_unchecked() creates a new unique and needs
index c0dfba490eca7dd7b12f5204ad052b34d206f85d..70e59cda63f26dd071900a0a1150ce251418d685 100644 (file)
@@ -267,6 +267,7 @@ pub(super) fn new(slice: &'a mut [T]) -> Self {
     /// // Now slice is "[2, 2, 3]":
     /// println!("{:?}", slice);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
     pub fn into_slice(self) -> &'a mut [T] {
         // SAFETY: the iterator was created from a mutable slice with pointer
@@ -1869,6 +1870,7 @@ pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     pub fn into_remainder(self) -> &'a mut [T] {
         self.rem
@@ -2264,6 +2266,7 @@ pub(super) fn new(slice: &'a mut [T]) -> Self {
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `N-1`
     /// elements.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "array_chunks", issue = "74985")]
     pub fn into_remainder(self) -> &'a mut [T] {
         self.rem
@@ -2875,6 +2878,7 @@ pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rchunks", since = "1.31.0")]
     pub fn into_remainder(self) -> &'a mut [T] {
         self.rem
index f25ab52cfa0d010c315b5f125604ca9cca614964..14ce94c178c5bdb8785bafd9f98f9b7df6295567 100644 (file)
@@ -188,6 +188,7 @@ pub const fn is_empty(&self) -> bool {
     /// // third byte of `老`
     /// assert!(!s.is_char_boundary(8));
     /// ```
+    #[must_use]
     #[stable(feature = "is_char_boundary", since = "1.9.0")]
     #[inline]
     pub fn is_char_boundary(&self, index: usize) -> bool {
@@ -1536,7 +1537,8 @@ pub fn rsplitn<'a, P>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
     #[inline]
     pub fn split_once<'a, P: Pattern<'a>>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)> {
         let (start, end) = delimiter.into_searcher(self).next_match()?;
-        Some((&self[..start], &self[end..]))
+        // SAFETY: `Searcher` is known to return valid indices.
+        unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
     }
 
     /// Splits the string on the last occurrence of the specified delimiter and
@@ -1556,7 +1558,8 @@ pub fn rsplit_once<'a, P>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)>
         P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         let (start, end) = delimiter.into_searcher(self).next_match_back()?;
-        Some((&self[..start], &self[end..]))
+        // SAFETY: `Searcher` is known to return valid indices.
+        unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
     }
 
     /// An iterator over the disjoint matches of a pattern within the given string
index d1533b8d67a6bf97e1f3360dc3661bd7fcfd96c0..e1408c7cc2ecc56d89c34583b1d008654f4750d8 100644 (file)
@@ -291,6 +291,7 @@ pub const fn from_nanos(nanos: u64) -> Duration {
     /// assert!(!Duration::from_nanos(1).is_zero());
     /// assert!(!Duration::from_secs(1).is_zero());
     /// ```
+    #[must_use]
     #[stable(feature = "duration_zero", since = "1.53.0")]
     #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")]
     #[inline]
@@ -464,6 +465,8 @@ pub const fn as_nanos(&self) -> u128 {
     /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
@@ -497,6 +500,8 @@ pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
     /// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
     /// ```
     #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn saturating_add(self, rhs: Duration) -> Duration {
@@ -520,6 +525,8 @@ pub const fn saturating_add(self, rhs: Duration) -> Duration {
     /// assert_eq!(Duration::new(0, 0).checked_sub(Duration::new(0, 1)), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
@@ -551,6 +558,8 @@ pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
     /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO);
     /// ```
     #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn saturating_sub(self, rhs: Duration) -> Duration {
@@ -574,6 +583,8 @@ pub const fn saturating_sub(self, rhs: Duration) -> Duration {
     /// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
@@ -603,6 +614,8 @@ pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
     /// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
     /// ```
     #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn saturating_mul(self, rhs: u32) -> Duration {
@@ -627,6 +640,8 @@ pub const fn saturating_mul(self, rhs: u32) -> Duration {
     /// assert_eq!(Duration::new(2, 0).checked_div(0), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
@@ -814,6 +829,8 @@ pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, FromSecsError> {
     /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn mul_f64(self, rhs: f64) -> Duration {
@@ -836,6 +853,8 @@ pub const fn mul_f64(self, rhs: f64) -> Duration {
     /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn mul_f32(self, rhs: f32) -> Duration {
@@ -857,6 +876,8 @@ pub const fn mul_f32(self, rhs: f32) -> Duration {
     /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_f64(self, rhs: f64) -> Duration {
@@ -880,6 +901,8 @@ pub const fn div_f64(self, rhs: f64) -> Duration {
     /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_f32(self, rhs: f32) -> Duration {
@@ -898,6 +921,8 @@ pub const fn div_f32(self, rhs: f32) -> Duration {
     /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
     /// ```
     #[unstable(feature = "div_duration", issue = "63139")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
@@ -916,6 +941,8 @@ pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
     /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
     /// ```
     #[unstable(feature = "div_duration", issue = "63139")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
index 9680aa14d3b54568c0816b33469a5df9bcda6c79..1502b3160bc22b104a3552ebc6646f0b9966a3ba 100644 (file)
@@ -44,10 +44,10 @@ pub(crate) fn is_printable(x: char) -> bool {
     } else if x < 0x20000 {
         check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
     } else {
-        if 0x2a6de <= x && x < 0x2a700 {
+        if 0x2a6e0 <= x && x < 0x2a700 {
             return false;
         }
-        if 0x2b735 <= x && x < 0x2b740 {
+        if 0x2b739 <= x && x < 0x2b740 {
             return false;
         }
         if 0x2b81e <= x && x < 0x2b820 {
@@ -77,13 +77,13 @@ pub(crate) fn is_printable(x: char) -> bool {
     (0x00, 1),
     (0x03, 5),
     (0x05, 6),
-    (0x06, 3),
+    (0x06, 2),
     (0x07, 6),
-    (0x08, 8),
+    (0x08, 7),
     (0x09, 17),
     (0x0a, 28),
     (0x0b, 25),
-    (0x0c, 20),
+    (0x0c, 26),
     (0x0d, 16),
     (0x0e, 13),
     (0x0f, 4),
@@ -91,16 +91,15 @@ pub(crate) fn is_printable(x: char) -> bool {
     (0x12, 18),
     (0x13, 9),
     (0x16, 1),
-    (0x17, 5),
-    (0x18, 2),
+    (0x17, 4),
+    (0x18, 1),
     (0x19, 3),
     (0x1a, 7),
+    (0x1b, 1),
     (0x1c, 2),
-    (0x1d, 1),
     (0x1f, 22),
     (0x20, 3),
     (0x2b, 3),
-    (0x2c, 2),
     (0x2d, 11),
     (0x2e, 1),
     (0x30, 3),
@@ -112,49 +111,48 @@ pub(crate) fn is_printable(x: char) -> bool {
     (0xab, 8),
     (0xfa, 2),
     (0xfb, 5),
-    (0xfd, 4),
+    (0xfd, 2),
     (0xfe, 3),
     (0xff, 9),
 ];
 #[rustfmt::skip]
 const SINGLETONS0L: &[u8] = &[
     0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
-    0x58, 0x8b, 0x8c, 0x90, 0x1c, 0x1d, 0xdd, 0x0e,
-    0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
-    0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e,
-    0x91, 0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6,
-    0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
-    0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b,
-    0x3d, 0x49, 0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9,
-    0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
-    0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12,
-    0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
-    0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
-    0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49,
-    0x57, 0x64, 0x65, 0x8d, 0x91, 0xa9, 0xb4, 0xba,
-    0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,
-    0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2,
-    0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0, 0xf1, 0x83,
-    0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,
-    0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd,
-    0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f, 0x57, 0x59,
-    0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,
-    0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17,
-    0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff, 0x80, 0x0d,
-    0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,
-    0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf,
-    0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1e, 0x1f, 0x46,
-    0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,
-    0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1,
-    0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96, 0x2f,
-    0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
+    0x58, 0x8b, 0x8c, 0x90, 0x1c, 0xdd, 0x0e, 0x0f,
+    0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, 0x5c,
+    0x5d, 0x5f, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92,
+    0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca,
+    0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, 0x11, 0x12,
+    0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49,
+    0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4,
+    0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5,
+    0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31,
+    0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e,
+    0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce,
+    0xcf, 0x0d, 0x11, 0x29, 0x3a, 0x3b, 0x45, 0x49,
+    0x57, 0x5b, 0x5c, 0x5e, 0x5f, 0x64, 0x65, 0x8d,
+    0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf,
+    0xe4, 0xe5, 0xf0, 0x0d, 0x11, 0x45, 0x49, 0x64,
+    0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
+    0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6,
+    0xbe, 0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb,
+    0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,
+    0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e,
+    0x8f, 0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7,
+    0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,
+    0xfe, 0xff, 0x80, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
+    0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e,
+    0xae, 0xaf, 0x7f, 0xbb, 0xbc, 0x16, 0x17, 0x1e,
+    0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c,
+    0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc,
+    0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75,
+    0x96, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
     0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98,
-    0x30, 0x8f, 0x1f, 0xc0, 0xc1, 0xce, 0xff, 0x4e,
+    0x30, 0x8f, 0x1f, 0xd2, 0xd4, 0xce, 0xff, 0x4e,
     0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,
     0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f,
-    0x42, 0x45, 0x90, 0x91, 0xfe, 0xff, 0x53, 0x67,
-    0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
-    0xfe, 0xff,
+    0x42, 0x45, 0x90, 0x91, 0x53, 0x67, 0x75, 0xc8,
+    0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
 #[rustfmt::skip]
 const SINGLETONS1U: &[(u8, u8)] = &[
@@ -162,6 +160,8 @@ pub(crate) fn is_printable(x: char) -> bool {
     (0x01, 1),
     (0x03, 1),
     (0x04, 2),
+    (0x05, 7),
+    (0x07, 2),
     (0x08, 8),
     (0x09, 2),
     (0x0a, 5),
@@ -178,9 +178,11 @@ pub(crate) fn is_printable(x: char) -> bool {
     (0x1c, 5),
     (0x1d, 8),
     (0x24, 1),
-    (0x6a, 3),
+    (0x6a, 4),
     (0x6b, 2),
+    (0xaf, 3),
     (0xbc, 2),
+    (0xcf, 2),
     (0xd1, 2),
     (0xd4, 12),
     (0xd5, 9),
@@ -189,38 +191,40 @@ pub(crate) fn is_printable(x: char) -> bool {
     (0xda, 1),
     (0xe0, 5),
     (0xe1, 2),
+    (0xe7, 4),
     (0xe8, 2),
     (0xee, 32),
     (0xf0, 4),
     (0xf8, 2),
-    (0xf9, 2),
     (0xfa, 2),
     (0xfb, 1),
 ];
 #[rustfmt::skip]
 const SINGLETONS1L: &[u8] = &[
     0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
-    0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
-    0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
-    0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd,
-    0x35, 0xe0, 0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04,
-    0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
-    0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65,
-    0x5c, 0xb6, 0xb7, 0x1b, 0x1c, 0x07, 0x08, 0x0a,
-    0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,
-    0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07,
-    0x0a, 0x3b, 0x3e, 0x66, 0x69, 0x8f, 0x92, 0x6f,
-    0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,
-    0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7,
-    0xa8, 0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c,
-    0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,
-    0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25,
-    0x3e, 0x3f, 0xc5, 0xc6, 0x04, 0x20, 0x23, 0x25,
-    0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,
-    0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
-    0x60, 0x63, 0x65, 0x66, 0x6b, 0x73, 0x78, 0x7d,
-    0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,
-    0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,
+    0x9e, 0x9f, 0x7b, 0x8b, 0x93, 0x96, 0xa2, 0xb2,
+    0xba, 0x86, 0xb1, 0x06, 0x07, 0x09, 0x36, 0x3d,
+    0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18,
+    0x36, 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf,
+    0xbd, 0x35, 0xe0, 0x12, 0x87, 0x89, 0x8e, 0x9e,
+    0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34,
+    0x3a, 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64,
+    0x65, 0x5c, 0xb6, 0xb7, 0x1b, 0x1c, 0x07, 0x08,
+    0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8,
+    0xa9, 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8,
+    0x07, 0x0a, 0x3b, 0x3e, 0x66, 0x69, 0x8f, 0x92,
+    0x6f, 0x5f, 0xbf, 0xee, 0xef, 0x5a, 0x62, 0xf4,
+    0xfc, 0xff, 0x9a, 0x9b, 0x2e, 0x2f, 0x27, 0x28,
+    0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
+    0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
+    0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
+    0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e,
+    0x3f, 0xe7, 0xec, 0xef, 0xff, 0xc5, 0xc6, 0x04,
+    0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a,
+    0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58,
+    0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b,
+    0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf,
+    0xb0, 0xc0, 0xd0, 0xae, 0xaf, 0x6e, 0x6f, 0x93,
 ];
 #[rustfmt::skip]
 const NORMAL0: &[u8] = &[
@@ -231,9 +235,9 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x1b, 0x04,
     0x06, 0x11,
     0x81, 0xac, 0x0e,
-    0x80, 0xab, 0x35,
-    0x28, 0x0b,
-    0x80, 0xe0, 0x03,
+    0x80, 0xab, 0x05,
+    0x1f, 0x09,
+    0x81, 0x1b, 0x03,
     0x19, 0x08,
     0x01, 0x04,
     0x2f, 0x04,
@@ -257,13 +261,11 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x0b, 0x06,
     0x01, 0x0e,
     0x15, 0x05,
-    0x3a, 0x03,
-    0x11, 0x07,
-    0x06, 0x05,
-    0x10, 0x07,
+    0x4e, 0x07,
+    0x1b, 0x07,
     0x57, 0x07,
-    0x02, 0x07,
-    0x15, 0x0d,
+    0x02, 0x06,
+    0x16, 0x0d,
     0x50, 0x04,
     0x43, 0x03,
     0x2d, 0x03,
@@ -280,8 +282,8 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x1a, 0x06,
     0x82, 0xfd, 0x03,
     0x59, 0x07,
-    0x15, 0x0b,
-    0x17, 0x09,
+    0x16, 0x09,
+    0x18, 0x09,
     0x14, 0x0c,
     0x14, 0x0c,
     0x6a, 0x06,
@@ -299,10 +301,9 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x0b, 0x03,
     0x80, 0xac, 0x06,
     0x0a, 0x06,
-    0x21, 0x3f,
-    0x4c, 0x04,
-    0x2d, 0x03,
-    0x74, 0x08,
+    0x2f, 0x31,
+    0x4d, 0x03,
+    0x80, 0xa4, 0x08,
     0x3c, 0x03,
     0x0f, 0x03,
     0x3c, 0x07,
@@ -312,7 +313,7 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x18, 0x08,
     0x2f, 0x11,
     0x2d, 0x03,
-    0x20, 0x10,
+    0x21, 0x0f,
     0x21, 0x0f,
     0x80, 0x8c, 0x04,
     0x82, 0x97, 0x19,
@@ -322,19 +323,19 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x3b, 0x07,
     0x02, 0x0e,
     0x18, 0x09,
-    0x80, 0xb3, 0x2d,
+    0x80, 0xbe, 0x22,
     0x74, 0x0c,
     0x80, 0xd6, 0x1a,
     0x0c, 0x05,
     0x80, 0xff, 0x05,
     0x80, 0xdf, 0x0c,
-    0xee, 0x0d, 0x03,
-    0x84, 0x8d, 0x03,
+    0xf2, 0x9d, 0x03,
     0x37, 0x09,
     0x81, 0x5c, 0x14,
     0x80, 0xb8, 0x08,
-    0x80, 0xcb, 0x2a,
-    0x38, 0x03,
+    0x80, 0xcb, 0x05,
+    0x0a, 0x18,
+    0x3b, 0x03,
     0x0a, 0x06,
     0x38, 0x08,
     0x46, 0x08,
@@ -354,9 +355,9 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x81, 0xda, 0x26,
     0x07, 0x0c,
     0x05, 0x05,
-    0x80, 0xa5, 0x11,
-    0x81, 0x6d, 0x10,
-    0x78, 0x28,
+    0x80, 0xa6, 0x10,
+    0x81, 0xf5, 0x07,
+    0x01, 0x20,
     0x2a, 0x06,
     0x4c, 0x04,
     0x80, 0x8d, 0x04,
@@ -386,10 +387,11 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x24, 0x04,
     0x28, 0x08,
     0x34, 0x0b,
-    0x01, 0x80, 0x90,
+    0x4e, 0x43,
     0x81, 0x37, 0x09,
     0x16, 0x0a,
-    0x08, 0x80, 0x98,
+    0x08, 0x18,
+    0x3b, 0x45,
     0x39, 0x03,
     0x63, 0x08,
     0x09, 0x30,
@@ -417,12 +419,13 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x0a, 0x81, 0x26,
     0x52, 0x4e,
     0x28, 0x08,
-    0x2a, 0x56,
+    0x2a, 0x16,
+    0x1a, 0x26,
     0x1c, 0x14,
     0x17, 0x09,
     0x4e, 0x04,
-    0x1e, 0x0f,
-    0x43, 0x0e,
+    0x24, 0x09,
+    0x44, 0x0d,
     0x19, 0x07,
     0x0a, 0x06,
     0x48, 0x08,
@@ -443,18 +446,18 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x45, 0x0b,
     0x0a, 0x06,
     0x0d, 0x13,
-    0x39, 0x07,
+    0x3a, 0x06,
     0x0a, 0x36,
     0x2c, 0x04,
-    0x10, 0x80, 0xc0,
+    0x17, 0x80, 0xb9,
     0x3c, 0x64,
     0x53, 0x0c,
     0x48, 0x09,
     0x0a, 0x46,
     0x45, 0x1b,
     0x48, 0x08,
-    0x53, 0x1d,
-    0x39, 0x81, 0x07,
+    0x53, 0x0d,
+    0x49, 0x81, 0x07,
     0x46, 0x0a,
     0x1d, 0x03,
     0x47, 0x49,
@@ -468,12 +471,13 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x32, 0x0d,
     0x83, 0x9b, 0x66,
     0x75, 0x0b,
-    0x80, 0xc4, 0x8a, 0xbc,
+    0x80, 0xc4, 0x8a, 0x4c,
+    0x63, 0x0d,
     0x84, 0x2f, 0x8f, 0xd1,
     0x82, 0x47, 0xa1, 0xb9,
     0x82, 0x39, 0x07,
     0x2a, 0x04,
-    0x02, 0x60,
+    0x5c, 0x06,
     0x26, 0x0a,
     0x46, 0x0a,
     0x28, 0x05,
@@ -486,32 +490,36 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x02, 0x0e,
     0x97, 0xf8, 0x08,
     0x84, 0xd6, 0x2a,
-    0x09, 0xa2, 0xf7,
-    0x81, 0x1f, 0x31,
+    0x09, 0xa2, 0xe7,
+    0x81, 0x33, 0x2d,
     0x03, 0x11,
     0x04, 0x08,
     0x81, 0x8c, 0x89, 0x04,
     0x6b, 0x05,
     0x0d, 0x03,
     0x09, 0x07,
-    0x10, 0x93, 0x60,
+    0x10, 0x92, 0x60,
+    0x47, 0x09,
+    0x74, 0x3c,
     0x80, 0xf6, 0x0a,
     0x73, 0x08,
-    0x6e, 0x17,
+    0x70, 0x15,
     0x46, 0x80, 0x9a,
     0x14, 0x0c,
     0x57, 0x09,
     0x19, 0x80, 0x87,
     0x81, 0x47, 0x03,
     0x85, 0x42, 0x0f,
-    0x15, 0x85, 0x50,
+    0x15, 0x84, 0x50,
+    0x1f, 0x80, 0xe1,
     0x2b, 0x80, 0xd5,
     0x2d, 0x03,
     0x1a, 0x04,
-    0x02, 0x81, 0x70,
+    0x02, 0x81, 0x40,
+    0x1f, 0x11,
     0x3a, 0x05,
-    0x01, 0x85, 0x00,
-    0x80, 0xd7, 0x29,
+    0x01, 0x84, 0xe0,
+    0x80, 0xf7, 0x29,
     0x4c, 0x04,
     0x0a, 0x04,
     0x02, 0x83, 0x11,
@@ -531,12 +539,13 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x09, 0x07,
     0x02, 0x0e,
     0x06, 0x80, 0x9a,
-    0x83, 0xd8, 0x08,
-    0x0d, 0x03,
+    0x83, 0xd8, 0x05,
+    0x10, 0x03,
     0x0d, 0x03,
     0x74, 0x0c,
     0x59, 0x07,
-    0x0c, 0x14,
+    0x0c, 0x04,
+    0x01, 0x0f,
     0x0c, 0x04,
     0x38, 0x08,
     0x0a, 0x06,
@@ -544,12 +553,14 @@ pub(crate) fn is_printable(x: char) -> bool {
     0x22, 0x4e,
     0x81, 0x54, 0x0c,
     0x15, 0x03,
-    0x03, 0x05,
+    0x05, 0x03,
     0x07, 0x09,
-    0x19, 0x07,
+    0x1d, 0x03,
+    0x0b, 0x05,
+    0x06, 0x0a,
+    0x0a, 0x06,
+    0x08, 0x08,
     0x07, 0x09,
-    0x03, 0x0d,
-    0x07, 0x29,
     0x80, 0xcb, 0x25,
     0x0a, 0x84, 0x06,
 ];
index 16803bf2e83b9b59db5a8012984af14b58dac77a..d2073f86c010fee04a51915f06c01a3e781c441b 100644 (file)
@@ -94,72 +94,74 @@ fn skip_search<const SOR: usize, const OFFSETS: usize>(
     offset_idx % 2 == 1
 }
 
-pub const UNICODE_VERSION: (u8, u8, u8) = (13, 0, 0);
+pub const UNICODE_VERSION: (u8, u8, u8) = (14, 0, 0);
 
 #[rustfmt::skip]
 pub mod alphabetic {
-    static SHORT_OFFSET_RUNS: [u32; 52] = [
-        706, 33559113, 868226669, 947920662, 1157637302, 1306536960, 1310732293, 1398813696,
-        1449151936, 1451270141, 1455465613, 1459660301, 1468061604, 1648425216, 1658911342,
-        1661009214, 1707147904, 1793132343, 1853951616, 1994464256, 2330009312, 2418090906,
-        2428579840, 2439066671, 2441167872, 2443265607, 2445371392, 2447469113, 2449567296,
-        2476836856, 2508295382, 2512498688, 2518790431, 2520888060, 2533473280, 2535576576,
-        2556548774, 2634145792, 2682380992, 2715936768, 2720132608, 2736910640, 2875326464,
-        2887952094, 2890053429, 2894253730, 2902649825, 2906847232, 2908944926, 2911043584,
-        2913145675, 2916356939,
+    static SHORT_OFFSET_RUNS: [u32; 51] = [
+        706, 33559113, 876615277, 956309270, 1166025910, 1314925568, 1319120901, 1398813696,
+        1449151936, 1451271309, 1455465997, 1463867300, 1652619520, 1663105646, 1665203518,
+        1711342208, 1797326647, 1891700352, 2044795904, 2397118176, 2485199770, 2495688592,
+        2506175535, 2512471040, 2514568775, 2516674560, 2518772281, 2520870464, 2552334328,
+        2583792854, 2587996144, 2594287907, 2608968444, 2621553664, 2623656960, 2644629158,
+        2722225920, 2770461328, 2808211424, 2816601600, 2850156848, 2988572672, 3001198304,
+        3003299641, 3007499938, 3015896033, 3020093440, 3022191134, 3024289792, 3026391883,
+        3029603147,
     ];
-    static OFFSETS: [u8; 1391] = [
+    static OFFSETS: [u8; 1445] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 42,
         5, 1, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, 39,
         14, 1, 1, 1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10,
-        3, 2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 53, 21, 1, 18,
-        12, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3, 8,
-        2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2,
-        1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1, 5,
-        3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2,
-        2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3, 12,
-        4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 4, 1, 8, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3,
-        5, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 7, 1, 1, 4, 13, 2, 13,
-        13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24, 1, 9, 1, 1,
-        2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1, 1, 1, 19, 1,
-        3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 17, 6, 16, 1, 36, 67, 55, 1, 1, 2, 5,
-        16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33,
-        1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2, 17, 1, 26,
-        5, 75, 3, 11, 7, 13, 1, 6, 12, 20, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4, 1,
-        67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2,
-        20, 50, 1, 23, 2, 63, 52, 1, 15, 1, 7, 52, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3, 10, 36,
-        2, 9, 7, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 39, 14, 11, 0, 2, 6, 2, 38, 2, 6, 2, 8,
-        1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116,
-        1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2, 4, 5,
-        5, 4, 1, 17, 41, 0, 52, 0, 47, 1, 47, 1, 133, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1,
-        16, 23, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2,
-        5, 4, 86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 3, 0, 67, 46, 2, 0,
-        3, 16, 10, 2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 53, 2, 9, 42, 17, 1, 33, 24, 52, 12,
+        3, 2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 6, 17,
+        42, 10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3,
+        8, 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1,
+        2, 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1,
+        5, 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2,
+        2, 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3,
+        12, 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 4, 1, 8, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2,
+        1, 3, 2, 1, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 6, 2, 1, 4,
+        13, 2, 13, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24,
+        1, 9, 1, 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1,
+        1, 1, 19, 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 17, 6, 16, 1, 36, 67, 55,
+        1, 1, 2, 5, 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1,
+        4, 2, 33, 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2,
+        17, 1, 26, 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4,
+        1, 67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2,
+        20, 50, 1, 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3,
+        10, 36, 2, 9, 7, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 39, 14, 11, 0, 2, 6, 2, 38, 2,
+        6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1,
+        7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2,
+        4, 5, 5, 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23,
+        9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4,
+        86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10,
+        2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 64, 5, 2, 1, 1, 1, 5, 24, 20, 1, 33, 24, 52, 12,
         68, 1, 1, 44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1,
         55, 9, 14, 18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1,
         43, 1, 14, 6, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1,
         1, 1, 2, 1, 2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89,
         3, 6, 2, 6, 2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3,
         49, 47, 32, 13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52,
-        156, 0, 9, 22, 10, 8, 152, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2,
-        10, 22, 10, 26, 70, 56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28,
-        27, 54, 10, 22, 10, 19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 0, 42, 1, 2, 3, 2, 78, 29,
-        10, 1, 8, 22, 106, 21, 27, 23, 9, 70, 60, 55, 23, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64, 1,
-        4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 1, 65, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57, 23,
-        4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 156, 66, 1, 3,
-        1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71,
-        27, 2, 14, 213, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8, 2, 46,
-        2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 34, 57, 0, 9, 1, 45, 1, 7, 1, 1, 49, 30, 2,
-        22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, 1, 2, 1, 37, 1, 2, 1, 4,
-        1, 1, 0, 23, 185, 1, 79, 0, 102, 111, 17, 196, 0, 0, 0, 0, 0, 0, 7, 31, 113, 30, 18, 48, 16,
-        4, 31, 21, 5, 19, 0, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 2, 14, 0, 8, 0, 42, 9, 0,
-        0, 49, 3, 17, 4, 8, 0, 0, 107, 5, 13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2,
-        4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25,
-        1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 7, 1, 17, 2, 7, 1,
-        2, 1, 5, 213, 45, 10, 7, 16, 1, 0, 44, 0, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1,
-        2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0,
-        26, 6, 26, 6, 26, 0, 0, 34, 0, 11, 222, 2, 0, 14, 0, 0, 0, 0, 0, 0,
+        12, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 67, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1,
+        9, 69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 70,
+        56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10,
+        19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 0, 42, 1, 2, 3, 2, 78, 29, 10, 1, 8, 22, 42,
+        18, 46, 21, 27, 23, 9, 70, 43, 5, 12, 55, 9, 1, 13, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64,
+        1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 1, 65, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57,
+        23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 156, 66, 1,
+        3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1,
+        71, 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4,
+        93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 0, 9, 1, 45, 1, 7, 1,
+        1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, 1, 2, 1,
+        37, 1, 2, 1, 4, 1, 1, 0, 23, 185, 1, 79, 0, 102, 111, 17, 196, 0, 97, 15, 0, 0, 0, 0, 0, 7,
+        31, 17, 79, 17, 30, 18, 48, 16, 4, 31, 21, 5, 19, 0, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1,
+        12, 2, 14, 0, 8, 0, 42, 9, 0, 4, 1, 7, 1, 2, 1, 0, 45, 3, 17, 4, 8, 0, 0, 107, 5, 13, 3, 9,
+        7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1,
+        7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1,
+        25, 1, 31, 1, 25, 1, 8, 0, 31, 225, 7, 1, 17, 2, 7, 1, 2, 1, 5, 213, 45, 10, 7, 16, 1, 0,
+        30, 18, 44, 0, 7, 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2,
+        1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26,
+        6, 26, 6, 26, 0, 0, 32, 0, 7, 222, 2, 0, 14, 0, 0, 0, 0, 0, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -172,44 +174,45 @@ pub fn lookup(c: char) -> bool {
 
 #[rustfmt::skip]
 pub mod case_ignorable {
-    static SHORT_OFFSET_RUNS: [u32; 32] = [
-        688, 44045149, 555751186, 559947709, 794831996, 866136069, 891330581, 916497656, 920692236,
-        924908318, 1122041344, 1130430973, 1193347585, 1205931300, 1231097515, 1235294255,
-        1445009723, 1453399088, 1512120051, 1575040048, 1579248368, 1583443791, 1596046493,
-        1612829031, 1621219840, 1642192896, 1667359024, 1688330988, 1692526800, 1696723963,
-        1705902081, 1711210992,
+    static SHORT_OFFSET_RUNS: [u32; 35] = [
+        688, 44045149, 572528402, 576724925, 807414908, 878718981, 903913493, 929080568, 933275148,
+        937491230, 1138818560, 1147208189, 1210124160, 1222707713, 1235291428, 1260457643,
+        1264654383, 1491147067, 1499536432, 1558257395, 1621177392, 1625385712, 1629581135,
+        1642180592, 1658961053, 1671548672, 1679937895, 1688328704, 1709301760, 1734467888,
+        1755439790, 1759635664, 1768027131, 1777205249, 1782514160,
     ];
-    static OFFSETS: [u8; 821] = [
+    static OFFSETS: [u8; 855] = [
         39, 1, 6, 1, 11, 1, 35, 1, 1, 1, 71, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2,
         1, 1, 251, 7, 207, 1, 5, 1, 49, 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35,
         1, 10, 21, 16, 1, 101, 8, 1, 10, 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24,
-        24, 43, 3, 119, 48, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1,
-        20, 2, 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4,
-        1, 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3,
-        1, 57, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4,
-        4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 6, 74,
-        2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25,
-        2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 3, 29, 2, 30, 2, 64, 2, 1,
-        7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 4, 52, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2,
-        1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 17, 63, 4, 48, 1, 1, 5, 1, 1, 5, 1,
-        40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13,
-        1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 95, 1, 5, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2,
-        12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3,
-        125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98,
-        4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 109, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1,
-        151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2,
-        2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1,
-        100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 16, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1,
-        7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 3, 1,
-        2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2, 153, 11, 176, 1, 54, 15, 56, 3, 49, 4, 2, 2, 2, 1,
-        15, 1, 50, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 160,
-        1, 3, 8, 21, 2, 57, 2, 3, 1, 37, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1,
-        2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1,
-        5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3,
-        46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1,
-        72, 2, 3, 1, 1, 1, 0, 2, 0, 9, 0, 5, 59, 7, 9, 4, 0, 1, 63, 17, 64, 2, 1, 2, 0, 2, 1, 4, 0,
-        3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7,
-        1, 2, 1, 5, 0, 14, 0, 4, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
+        24, 43, 3, 44, 1, 7, 2, 6, 8, 41, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1,
+        58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2,
+        57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1,
+        61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1,
+        5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9,
+        98, 1, 2, 9, 9, 1, 1, 6, 74, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
+        102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3,
+        29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118,
+        3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 31,
+        49, 4, 48, 1, 1, 5, 1, 1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3,
+        58, 8, 2, 2, 64, 6, 82, 3, 1, 13, 1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1,
+        3, 11, 3, 13, 3, 13, 3, 13, 2, 12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1,
+        16, 13, 51, 33, 0, 2, 113, 3, 125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6,
+        93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 103, 3, 3,
+        2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4,
+        2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2,
+        1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3,
+        1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3,
+        0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2,
+        153, 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3,
+        36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 160, 1, 3, 8, 21, 2,
+        57, 2, 3, 1, 37, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1, 2, 238, 4, 6, 2,
+        1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1, 5, 0, 9, 1, 2, 0,
+        2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0,
+        7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1,
+        0, 2, 0, 9, 0, 5, 59, 7, 9, 4, 0, 1, 63, 17, 64, 2, 1, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0,
+        46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7,
+        1, 17, 2, 7, 1, 2, 1, 5, 0, 14, 0, 1, 61, 4, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -222,23 +225,24 @@ pub fn lookup(c: char) -> bool {
 
 #[rustfmt::skip]
 pub mod cased {
-    static SHORT_OFFSET_RUNS: [u32; 19] = [
-        4256, 115348384, 136322176, 144711446, 163587254, 320875520, 325101120, 358656816,
-        392231680, 404815649, 413205504, 421596288, 434182304, 442592832, 446813184, 451008166,
-        528607488, 576844080, 582152586,
+    static SHORT_OFFSET_RUNS: [u32; 21] = [
+        4256, 115348384, 136322176, 144711446, 163587254, 320875520, 325101120, 350268208,
+        392231680, 404815649, 413205504, 421595008, 467733632, 484513952, 492924480, 497144832,
+        501339814, 578936576, 627173632, 635564336, 640872842,
     ];
-    static OFFSETS: [u8; 283] = [
+    static OFFSETS: [u8; 311] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5,
         96, 1, 42, 4, 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9,
         41, 0, 38, 1, 1, 5, 1, 2, 43, 2, 3, 0, 86, 2, 6, 0, 9, 7, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2,
         38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13,
         5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4,
-        1, 6, 4, 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 47, 1, 47, 1, 133, 6, 4, 3, 2, 12, 38,
-        1, 1, 5, 1, 0, 46, 18, 30, 132, 102, 3, 4, 1, 48, 2, 9, 42, 2, 1, 3, 0, 43, 1, 13, 7, 80, 0,
-        7, 12, 5, 0, 26, 6, 26, 0, 80, 96, 36, 4, 36, 0, 51, 13, 51, 0, 64, 0, 64, 0, 85, 1, 71, 1,
-        2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3,
-        7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 68,
-        0, 26, 6, 26, 6, 26, 0,
+        1, 6, 4, 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1,
+        0, 46, 18, 30, 132, 102, 3, 4, 1, 59, 5, 2, 1, 1, 1, 5, 27, 2, 1, 3, 0, 43, 1, 13, 7, 80, 0,
+        7, 12, 5, 0, 26, 6, 26, 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1,
+        7, 1, 2, 0, 1, 2, 3, 1, 42, 1, 9, 0, 51, 13, 51, 0, 64, 0, 64, 0, 85, 1, 71, 1, 2, 2, 1, 2,
+        2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2,
+        25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, 1, 20, 0,
+        68, 0, 26, 6, 26, 6, 26, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -268,38 +272,40 @@ pub fn lookup(c: char) -> bool {
 
 #[rustfmt::skip]
 pub mod grapheme_extend {
-    static SHORT_OFFSET_RUNS: [u32; 31] = [
-        768, 2098307, 6292881, 10490717, 513808146, 518004748, 723528943, 731918378, 744531567,
-        752920578, 769719070, 899743232, 903937950, 912327165, 916523521, 929107236, 954273451,
-        958470191, 1180769328, 1252073203, 1315007216, 1319202639, 1327611037, 1340199269,
-        1344395776, 1373757440, 1398923568, 1419895532, 1424091344, 1429078048, 1438581232,
+    static SHORT_OFFSET_RUNS: [u32; 32] = [
+        768, 2098307, 6292881, 10490717, 522196754, 526393356, 731917551, 740306986, 752920175,
+        761309186, 778107678, 908131840, 912326558, 920715773, 924912129, 937495844, 962662059,
+        966858799, 1205935152, 1277239027, 1340173040, 1344368463, 1352776861, 1365364480,
+        1369559397, 1377950208, 1407311872, 1432478000, 1453449902, 1457645776, 1466826784,
+        1476329968,
     ];
-    static OFFSETS: [u8; 689] = [
+    static OFFSETS: [u8; 707] = [
         0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 1, 72, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1,
-        4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 119, 15, 1, 32, 55,
-        1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2, 2,
-        57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, 1,
-        1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1, 57,
-        3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 2, 1, 3, 1, 5, 2, 7, 2, 11, 2, 28, 2, 57, 2,
-        1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7, 12, 8, 98,
-        1, 2, 9, 11, 6, 74, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1,
-        6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 3, 29, 3, 29, 2, 30,
-        2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 119, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2,
-        2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 17, 63, 4, 48, 7, 1, 1, 5, 1, 40, 9,
-        12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 152, 3, 1, 13, 1, 7, 4, 1,
-        6, 1, 3, 2, 198, 58, 1, 5, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1, 10,
-        32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3,
-        48, 1, 2, 4, 2, 2, 39, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1,
-        1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, 149, 5, 0, 3,
-        1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2, 153, 11, 176, 1, 54, 15, 56, 3, 49, 4, 2, 2,
-        69, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 160, 1, 3, 8,
-        21, 2, 57, 2, 1, 1, 1, 1, 22, 1, 14, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 81, 1, 2, 6, 1, 1,
-        2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1,
-        1, 101, 3, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10,
-        40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2,
-        122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 0,
-        2, 0, 1, 1, 3, 4, 5, 8, 8, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0,
-        7, 1, 17, 2, 7, 1, 2, 1, 5, 0, 7, 0, 4, 0, 7, 109, 7, 0, 96, 128, 240, 0,
+        4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 60, 8, 42, 24, 1, 32,
+        55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2,
+        2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6,
+        1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1,
+        55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 2, 1, 3, 1, 5, 2, 7, 2, 11, 2, 28,
+        2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7,
+        12, 8, 98, 1, 2, 9, 11, 6, 74, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
+        102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 3, 29, 2,
+        30, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, 4, 2, 9,
+        1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 31, 49, 4, 48, 7, 1,
+        1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 152, 3, 1,
+        13, 1, 7, 4, 1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0,
+        4, 1, 10, 32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11,
+        46, 3, 48, 1, 2, 4, 2, 2, 39, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, 2, 2,
+        5, 2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, 149,
+        5, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2, 153, 11, 49, 4, 123, 1, 54, 15, 41, 1,
+        2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3,
+        2, 1, 1, 2, 6, 1, 160, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 22, 1, 14, 7, 3, 5, 195, 8, 2, 3,
+        1, 1, 23, 1, 81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2,
+        1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 2, 1, 1, 4,
+        1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1,
+        1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 0, 5,
+        59, 7, 0, 1, 63, 4, 81, 1, 0, 2, 0, 46, 2, 23, 0, 1, 1, 3, 4, 5, 8, 8, 2, 7, 30, 4, 148, 3,
+        0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 0, 7, 0, 1, 61, 4,
+        0, 7, 109, 7, 0, 96, 128, 240, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -313,33 +319,34 @@ pub fn lookup(c: char) -> bool {
 #[rustfmt::skip]
 pub mod lowercase {
     static BITSET_CHUNKS_MAP: [u8; 123] = [
-        13, 16, 0, 0, 8, 0, 0, 11, 12, 9, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 3, 1, 0, 14, 0, 7, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0,
-        0, 0, 6,
+        14, 17, 0, 0, 9, 0, 0, 12, 13, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0,
+        3, 0, 0, 7,
     ];
-    static BITSET_INDEX_CHUNKS: [[u8; 16]; 18] = [
+    static BITSET_INDEX_CHUNKS: [[u8; 16]; 19] = [
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 52, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 55, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 39, 0, 47, 43, 45, 30],
-        [0, 0, 0, 0, 10, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 42, 0, 50, 46, 48, 32],
+        [0, 0, 0, 0, 10, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26],
-        [0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 54, 0, 52, 52, 52, 0, 21, 21, 64, 21, 33, 24, 23, 34],
-        [0, 5, 71, 0, 28, 15, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 61, 31, 17, 22, 48, 49, 44, 42, 8, 32, 38, 0, 27, 13, 29],
-        [11, 55, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [16, 25, 21, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [16, 46, 2, 20, 63, 9, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [60, 37, 51, 12, 70, 58, 18, 1, 6, 59, 68, 19, 65, 66, 3, 41],
+        [0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26],
+        [0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 57, 0, 55, 55, 55, 0, 21, 21, 67, 21, 35, 24, 23, 36],
+        [0, 5, 74, 0, 28, 15, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 64, 33, 17, 22, 51, 52, 47, 45, 8, 34, 40, 0, 27, 13, 30],
+        [11, 58, 0, 4, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 31, 0],
+        [16, 25, 21, 37, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [16, 49, 2, 20, 66, 9, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [63, 39, 54, 12, 73, 61, 18, 1, 6, 62, 71, 19, 68, 69, 3, 44],
     ];
-    static BITSET_CANONICAL: [u64; 52] = [
+    static BITSET_CANONICAL: [u64; 55] = [
         0b0000000000000000000000000000000000000000000000000000000000000000,
         0b1111111111111111110000000000000000000000000011111111111111111111,
         0b1010101010101010101010101010101010101010101010101010100000000010,
@@ -365,12 +372,14 @@ pub mod lowercase {
         0b0101010110101010101010101010101010101010101010101010101010101010,
         0b0100000011011111000000001111111100000000111111110000000011111111,
         0b0011111111111111000000001111111100000000111111110000000000111111,
-        0b0011111111011010000101010110001001111111111111111111111111111111,
+        0b0011111111011010000101010110001011111111111111111111111111111111,
         0b0011111100000000000000000000000000000000000000000000000000000000,
         0b0011110010001010000000000000000000000000000000000000000000100000,
         0b0011001000010000100000000000000000000000000010001100010000000000,
+        0b0001101111111011111111111111101111111111100000000000000000000000,
         0b0001100100101111101010101010101010101010111000110111111111111111,
-        0b0000011101000000000000000000000000000000000000000000010100001000,
+        0b0000011111111101111111111111111111111111111111111111111110111001,
+        0b0000011101000000000000000000000000000010101010100000010100001010,
         0b0000010000100000000001000000000000000000000000000000000000000000,
         0b0000000111111111111111111111111111111111111011111111111111111111,
         0b0000000011111111000000001111111100000000001111110000000011111111,
@@ -379,6 +388,7 @@ pub mod lowercase {
         0b0000000000000000001000001011111111111111111111111111111111111111,
         0b0000000000000000000000001111111111111111110111111100000000000000,
         0b0000000000000000000000000001111100000000000000000000000000000011,
+        0b0000000000000000000000000000000001111111111111111111101111111111,
         0b0000000000000000000000000000000000111010101010101010101010101010,
         0b0000000000000000000000000000000000000000111110000000000001111111,
         0b0000000000000000000000000000000000000000000000000000101111110111,
@@ -416,10 +426,10 @@ pub mod n {
         1632, 18876774, 31461440, 102765417, 111154926, 115349830, 132128880, 165684320, 186656630,
         195046653, 199241735, 203436434, 216049184, 241215536, 249605104, 274792208, 278987015,
         283181793, 295766104, 320933114, 383848032, 392238160, 434181712, 442570976, 455154768,
-        463544256, 476128256, 480340576, 484535936, 497144544, 501340110, 509731136, 513925872,
-        518121671, 522316913, 530706688, 551681008, 556989434,
+        463544256, 476128256, 480340576, 484535936, 501338848, 505534414, 513925440, 518120176,
+        522315975, 526511217, 534900992, 555875312, 561183738,
     ];
-    static OFFSETS: [u8; 267] = [
+    static OFFSETS: [u8; 269] = [
         48, 10, 120, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118,
         10, 118, 10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10,
         70, 20, 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10,
@@ -429,8 +439,9 @@ pub mod n {
         29, 1, 8, 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9,
         52, 2, 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134,
         30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 102, 12, 0,
-        19, 93, 10, 0, 29, 227, 10, 70, 10, 0, 21, 0, 111, 0, 10, 230, 10, 1, 7, 0, 23, 0, 20, 108,
-        25, 0, 50, 0, 10, 0, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0,
+        19, 93, 10, 0, 29, 227, 10, 70, 10, 0, 21, 0, 111, 0, 10, 86, 10, 134, 10, 1, 7, 0, 23, 0,
+        20, 108, 25, 0, 50, 0, 10, 0, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0,
+        10, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -444,37 +455,37 @@ pub fn lookup(c: char) -> bool {
 #[rustfmt::skip]
 pub mod uppercase {
     static BITSET_CHUNKS_MAP: [u8; 125] = [
-        12, 15, 5, 5, 0, 5, 5, 2, 4, 11, 5, 14, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 5, 5, 6, 5, 13, 5, 10, 5, 5, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 16, 5, 5,
-        5, 5, 9, 5, 3,
+        12, 15, 6, 6, 0, 6, 6, 2, 4, 11, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 5, 6, 14, 6, 10, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 6, 6,
+        6, 6, 9, 6, 3,
     ];
     static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [
-        [41, 41, 5, 33, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 5, 0],
-        [41, 41, 5, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 38, 41, 41, 41, 41, 41, 17, 17, 61, 17, 40, 29, 24, 23],
-        [41, 41, 41, 41, 9, 8, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 35, 28, 65, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 56, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 60, 59, 41, 20, 14, 16, 4],
-        [41, 41, 41, 41, 47, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 51, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 52, 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 53, 41, 31, 34, 21, 22, 15, 13, 32, 41, 41, 41, 11, 30, 37],
-        [48, 41, 9, 44, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [49, 36, 17, 27, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [50, 19, 2, 18, 10, 45, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [57, 1, 26, 54, 12, 7, 25, 55, 39, 58, 6, 3, 64, 63, 62, 66],
+        [43, 43, 5, 34, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 5, 1],
+        [43, 43, 5, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 39, 43, 43, 43, 43, 43, 17, 17, 62, 17, 42, 29, 24, 23],
+        [43, 43, 43, 43, 9, 8, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 36, 28, 66, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 54, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 43, 20, 14, 16, 4],
+        [43, 43, 43, 43, 55, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 58, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 59, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 48, 43, 31, 35, 21, 22, 15, 13, 33, 43, 43, 43, 11, 30, 38],
+        [51, 53, 26, 49, 12, 7, 25, 50, 40, 52, 6, 3, 65, 64, 63, 67],
+        [56, 43, 9, 46, 43, 41, 32, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [57, 19, 2, 18, 10, 47, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [57, 37, 17, 27, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
     ];
-    static BITSET_CANONICAL: [u64; 41] = [
+    static BITSET_CANONICAL: [u64; 43] = [
+        0b0000011111111111111111111111111000000000000000000000000000000000,
         0b0000000000111111111111111111111111111111111111111111111111111111,
-        0b1111111111111111111111110000000000000000000000000011111111111111,
         0b0101010101010101010101010101010101010101010101010101010000000001,
         0b0000011111111111111111111111110000000000000000000000000000000001,
-        0b0000000000100000000000000000000000000000000000000000001011110100,
+        0b0000000000100000000000000000000000000001010000010000001011110101,
         0b1111111111111111111111111111111100000000000000000000000000000000,
         0b1111111111111111111111110000000000000000000000000000001111111111,
         0b1111111111111111111100000000000000000000000000011111110001011111,
@@ -502,6 +513,7 @@ pub mod uppercase {
         0b0000000000000000111111110000000010101010000000000011111100000000,
         0b0000000000000000000011111111101111111111111111101101011101000000,
         0b0000000000000000000000000000000001111111011111111111111111111111,
+        0b0000000000000000000000000000000000000000001101111111011111111111,
         0b0000000000000000000000000000000000000000000000000101010101111010,
         0b0000000000000000000000000000000000000000000000000010000010111111,
         0b1010101001010101010101010101010101010101010101010101010101010101,
@@ -510,11 +522,12 @@ pub mod uppercase {
         0b1110011010010000010101010101010101010101000111001000000000000000,
         0b1110011111111111111111111111111111111111111111110000000000000000,
         0b1111000000000000000000000000001111111111111111111111111100000000,
+        0b1111011111111111000000000000000000000000000000000000000000000000,
         0b1111111100000000111111110000000000111111000000001111111100000000,
     ];
-    static BITSET_MAPPING: [(u8, u8); 26] = [
-        (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 135),
-        (0, 134), (0, 131), (0, 64), (1, 115), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 164),
+    static BITSET_MAPPING: [(u8, u8); 25] = [
+        (0, 187), (0, 177), (0, 171), (0, 167), (0, 164), (0, 32), (0, 47), (0, 51), (0, 121),
+        (0, 117), (0, 109), (1, 150), (1, 148), (1, 142), (1, 134), (1, 131), (1, 64), (2, 164),
         (2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171),
     ];
 
@@ -1051,113 +1064,116 @@ pub mod conversions {
         ('\u{2c28}', ['\u{2c58}', '\u{0}', '\u{0}']), ('\u{2c29}', ['\u{2c59}', '\u{0}', '\u{0}']),
         ('\u{2c2a}', ['\u{2c5a}', '\u{0}', '\u{0}']), ('\u{2c2b}', ['\u{2c5b}', '\u{0}', '\u{0}']),
         ('\u{2c2c}', ['\u{2c5c}', '\u{0}', '\u{0}']), ('\u{2c2d}', ['\u{2c5d}', '\u{0}', '\u{0}']),
-        ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']),
-        ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']), ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']),
-        ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']), ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']),
-        ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']), ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']),
-        ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']), ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']),
-        ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']), ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']),
-        ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']), ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']),
-        ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']), ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']),
-        ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']), ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']),
-        ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']), ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']),
-        ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']), ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']),
-        ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']), ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']),
-        ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']), ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']),
-        ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']), ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']),
-        ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']), ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']),
-        ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']), ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']),
-        ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']), ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']),
-        ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']), ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']),
-        ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']), ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']),
-        ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']), ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']),
-        ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']), ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']),
-        ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']), ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']),
-        ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']), ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']),
-        ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']), ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']),
-        ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']), ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']),
-        ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']), ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']),
-        ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']), ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']),
-        ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']), ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']),
-        ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']), ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']),
-        ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']), ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']),
-        ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']), ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']),
-        ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']), ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']),
-        ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']), ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']),
-        ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']), ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']),
-        ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']), ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']),
-        ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']), ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']),
-        ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']), ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']),
-        ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']), ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']),
-        ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']), ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']),
-        ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']), ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']),
-        ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']), ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']),
-        ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']), ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']),
-        ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']), ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']),
-        ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']), ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']),
-        ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']), ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']),
-        ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']), ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']),
-        ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']), ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']),
-        ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']), ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']),
-        ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']), ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']),
-        ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']), ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']),
-        ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']), ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']),
-        ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']), ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']),
-        ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']), ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']),
-        ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']), ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']),
-        ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']), ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']),
-        ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']), ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']),
-        ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']), ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']),
-        ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']), ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']),
-        ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']), ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']),
-        ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']), ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']),
-        ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']), ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']),
-        ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']), ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']),
-        ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']), ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']),
-        ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']), ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']),
-        ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']), ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']),
-        ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']), ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']),
-        ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']), ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']),
-        ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']), ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']),
-        ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']), ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']),
-        ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']), ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']),
-        ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']), ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']),
-        ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']), ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']),
-        ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']), ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']),
-        ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']), ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']),
-        ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']), ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']),
-        ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']), ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']),
-        ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']), ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']),
-        ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']), ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']),
-        ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']), ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']),
-        ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']), ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']),
-        ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']), ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']),
-        ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']), ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']),
-        ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']), ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']),
-        ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']), ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']),
-        ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']), ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']),
-        ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']), ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']),
-        ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']), ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']),
-        ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']), ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']),
-        ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']), ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']),
-        ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']), ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']),
-        ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']), ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']),
+        ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), ('\u{2c2f}', ['\u{2c5f}', '\u{0}', '\u{0}']),
+        ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']), ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']),
+        ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']), ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']),
+        ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']), ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']),
+        ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']), ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']),
+        ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']), ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']),
+        ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']), ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']),
+        ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']), ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']),
+        ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']), ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']),
+        ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']), ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']),
+        ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']), ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']),
+        ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']), ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']),
+        ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']), ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']),
+        ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']), ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']),
+        ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']), ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']),
+        ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']), ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']),
+        ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']), ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']),
+        ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']), ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']),
+        ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']), ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']),
+        ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']), ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']),
+        ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']), ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']),
+        ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']), ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']),
+        ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']), ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']),
+        ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']), ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']),
+        ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']), ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']),
+        ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']), ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']),
+        ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']), ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']),
+        ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']), ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']),
+        ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']), ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']),
+        ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']), ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']),
+        ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']), ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']),
+        ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']), ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']),
+        ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']), ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']),
+        ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']), ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']),
+        ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']), ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']),
+        ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']), ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']),
+        ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']), ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']),
+        ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']), ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']),
+        ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']), ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']),
+        ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']), ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']),
+        ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']), ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']),
+        ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']), ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']),
+        ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']), ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']),
+        ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']), ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']),
+        ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']), ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']),
+        ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']), ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']),
+        ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']), ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']),
+        ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']), ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']),
+        ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']), ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']),
+        ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']), ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']),
+        ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']), ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']),
+        ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']), ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']),
+        ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']), ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']),
+        ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']), ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']),
+        ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']), ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']),
+        ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']), ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']),
+        ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']), ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']),
+        ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']), ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']),
+        ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']), ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']),
+        ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']), ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']),
+        ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']), ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']),
+        ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']), ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']),
+        ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']), ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']),
+        ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']), ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']),
+        ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']), ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']),
+        ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']), ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']),
+        ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']), ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']),
+        ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']), ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']),
+        ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']), ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']),
+        ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']), ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']),
+        ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']), ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']),
+        ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']), ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']),
+        ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']), ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']),
+        ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']), ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']),
+        ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']), ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']),
+        ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']), ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']),
+        ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']), ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']),
+        ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']), ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']),
+        ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']), ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']),
+        ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']), ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']),
+        ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']), ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']),
+        ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']), ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']),
+        ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']), ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']),
+        ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']), ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']),
+        ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']), ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']),
+        ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']), ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']),
+        ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']), ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']),
+        ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']), ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']),
+        ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']), ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']),
+        ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']), ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']),
+        ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']), ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']),
+        ('\u{a7c0}', ['\u{a7c1}', '\u{0}', '\u{0}']), ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']),
         ('\u{a7c4}', ['\u{a794}', '\u{0}', '\u{0}']), ('\u{a7c5}', ['\u{282}', '\u{0}', '\u{0}']),
         ('\u{a7c6}', ['\u{1d8e}', '\u{0}', '\u{0}']), ('\u{a7c7}', ['\u{a7c8}', '\u{0}', '\u{0}']),
-        ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), ('\u{a7f5}', ['\u{a7f6}', '\u{0}', '\u{0}']),
-        ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']), ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']),
-        ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']), ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']),
-        ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']), ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']),
-        ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']), ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']),
-        ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']), ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']),
-        ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']), ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']),
-        ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']), ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']),
-        ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']), ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']),
-        ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']), ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']),
-        ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']), ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']),
-        ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']), ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']),
-        ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']), ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']),
-        ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']), ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']),
+        ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), ('\u{a7d0}', ['\u{a7d1}', '\u{0}', '\u{0}']),
+        ('\u{a7d6}', ['\u{a7d7}', '\u{0}', '\u{0}']), ('\u{a7d8}', ['\u{a7d9}', '\u{0}', '\u{0}']),
+        ('\u{a7f5}', ['\u{a7f6}', '\u{0}', '\u{0}']), ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']),
+        ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']), ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']),
+        ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']), ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']),
+        ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']), ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']),
+        ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']), ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']),
+        ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']), ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']),
+        ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']), ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']),
+        ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']), ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']),
+        ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']), ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']),
+        ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']), ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']),
+        ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']), ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']),
+        ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']), ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']),
+        ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']), ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']),
+        ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']),
         ('\u{10400}', ['\u{10428}', '\u{0}', '\u{0}']),
         ('\u{10401}', ['\u{10429}', '\u{0}', '\u{0}']),
         ('\u{10402}', ['\u{1042a}', '\u{0}', '\u{0}']),
@@ -1234,6 +1250,41 @@ pub mod conversions {
         ('\u{104d1}', ['\u{104f9}', '\u{0}', '\u{0}']),
         ('\u{104d2}', ['\u{104fa}', '\u{0}', '\u{0}']),
         ('\u{104d3}', ['\u{104fb}', '\u{0}', '\u{0}']),
+        ('\u{10570}', ['\u{10597}', '\u{0}', '\u{0}']),
+        ('\u{10571}', ['\u{10598}', '\u{0}', '\u{0}']),
+        ('\u{10572}', ['\u{10599}', '\u{0}', '\u{0}']),
+        ('\u{10573}', ['\u{1059a}', '\u{0}', '\u{0}']),
+        ('\u{10574}', ['\u{1059b}', '\u{0}', '\u{0}']),
+        ('\u{10575}', ['\u{1059c}', '\u{0}', '\u{0}']),
+        ('\u{10576}', ['\u{1059d}', '\u{0}', '\u{0}']),
+        ('\u{10577}', ['\u{1059e}', '\u{0}', '\u{0}']),
+        ('\u{10578}', ['\u{1059f}', '\u{0}', '\u{0}']),
+        ('\u{10579}', ['\u{105a0}', '\u{0}', '\u{0}']),
+        ('\u{1057a}', ['\u{105a1}', '\u{0}', '\u{0}']),
+        ('\u{1057c}', ['\u{105a3}', '\u{0}', '\u{0}']),
+        ('\u{1057d}', ['\u{105a4}', '\u{0}', '\u{0}']),
+        ('\u{1057e}', ['\u{105a5}', '\u{0}', '\u{0}']),
+        ('\u{1057f}', ['\u{105a6}', '\u{0}', '\u{0}']),
+        ('\u{10580}', ['\u{105a7}', '\u{0}', '\u{0}']),
+        ('\u{10581}', ['\u{105a8}', '\u{0}', '\u{0}']),
+        ('\u{10582}', ['\u{105a9}', '\u{0}', '\u{0}']),
+        ('\u{10583}', ['\u{105aa}', '\u{0}', '\u{0}']),
+        ('\u{10584}', ['\u{105ab}', '\u{0}', '\u{0}']),
+        ('\u{10585}', ['\u{105ac}', '\u{0}', '\u{0}']),
+        ('\u{10586}', ['\u{105ad}', '\u{0}', '\u{0}']),
+        ('\u{10587}', ['\u{105ae}', '\u{0}', '\u{0}']),
+        ('\u{10588}', ['\u{105af}', '\u{0}', '\u{0}']),
+        ('\u{10589}', ['\u{105b0}', '\u{0}', '\u{0}']),
+        ('\u{1058a}', ['\u{105b1}', '\u{0}', '\u{0}']),
+        ('\u{1058c}', ['\u{105b3}', '\u{0}', '\u{0}']),
+        ('\u{1058d}', ['\u{105b4}', '\u{0}', '\u{0}']),
+        ('\u{1058e}', ['\u{105b5}', '\u{0}', '\u{0}']),
+        ('\u{1058f}', ['\u{105b6}', '\u{0}', '\u{0}']),
+        ('\u{10590}', ['\u{105b7}', '\u{0}', '\u{0}']),
+        ('\u{10591}', ['\u{105b8}', '\u{0}', '\u{0}']),
+        ('\u{10592}', ['\u{105b9}', '\u{0}', '\u{0}']),
+        ('\u{10594}', ['\u{105bb}', '\u{0}', '\u{0}']),
+        ('\u{10595}', ['\u{105bc}', '\u{0}', '\u{0}']),
         ('\u{10c80}', ['\u{10cc0}', '\u{0}', '\u{0}']),
         ('\u{10c81}', ['\u{10cc1}', '\u{0}', '\u{0}']),
         ('\u{10c82}', ['\u{10cc2}', '\u{0}', '\u{0}']),
@@ -1892,154 +1943,157 @@ pub mod conversions {
         ('\u{2c59}', ['\u{2c29}', '\u{0}', '\u{0}']), ('\u{2c5a}', ['\u{2c2a}', '\u{0}', '\u{0}']),
         ('\u{2c5b}', ['\u{2c2b}', '\u{0}', '\u{0}']), ('\u{2c5c}', ['\u{2c2c}', '\u{0}', '\u{0}']),
         ('\u{2c5d}', ['\u{2c2d}', '\u{0}', '\u{0}']), ('\u{2c5e}', ['\u{2c2e}', '\u{0}', '\u{0}']),
-        ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']), ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']),
-        ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']), ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']),
-        ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']), ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']),
-        ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']), ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']),
-        ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']), ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']),
-        ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']), ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']),
-        ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']), ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']),
-        ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']), ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']),
-        ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']), ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']),
-        ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']), ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']),
-        ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']), ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']),
-        ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']), ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']),
-        ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']), ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']),
-        ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']), ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']),
-        ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']), ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']),
-        ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']), ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']),
-        ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']), ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']),
-        ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']), ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']),
-        ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']), ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']),
-        ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']), ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']),
-        ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']), ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']),
-        ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']), ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']),
-        ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']), ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']),
-        ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']), ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']),
-        ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']), ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']),
-        ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']), ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']),
-        ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']), ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']),
-        ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']), ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']),
-        ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']), ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']),
-        ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']), ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']),
-        ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']), ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']),
-        ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']), ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']),
-        ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']), ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']),
-        ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']), ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']),
-        ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']), ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']),
-        ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']), ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']),
-        ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']), ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']),
-        ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']), ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']),
-        ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']), ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']),
-        ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']), ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']),
-        ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']), ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']),
-        ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']), ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']),
-        ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']), ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']),
-        ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']), ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']),
-        ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']), ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']),
-        ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']), ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']),
-        ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']), ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']),
-        ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']), ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']),
-        ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']), ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']),
-        ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']), ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']),
-        ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']), ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']),
-        ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']), ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']),
-        ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']), ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']),
-        ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']), ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']),
-        ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']), ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']),
-        ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']), ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']),
-        ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']), ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']),
-        ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']), ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']),
-        ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']), ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']),
-        ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']), ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']),
-        ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']), ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']),
-        ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']), ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']),
-        ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']), ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']),
-        ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']), ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']),
-        ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']), ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']),
-        ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']), ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']),
-        ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']), ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']),
-        ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']), ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']),
-        ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']), ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']),
-        ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']), ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']),
-        ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']), ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']),
-        ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']), ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']),
-        ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']), ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']),
-        ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']), ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']),
-        ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']), ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']),
-        ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']), ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']),
-        ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']), ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']),
-        ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']), ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']),
-        ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']), ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']),
-        ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']), ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']),
-        ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']), ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']),
-        ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']), ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']),
-        ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']), ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']),
-        ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']), ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']),
-        ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']), ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']),
-        ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']), ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']),
-        ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']), ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']),
-        ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']), ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']),
-        ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']), ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']),
-        ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']), ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']),
-        ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']), ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']),
-        ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']), ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']),
-        ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']), ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']),
-        ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']), ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']),
-        ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']), ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']),
-        ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']), ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']),
-        ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']), ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']),
-        ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']), ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']),
-        ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']), ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']),
-        ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']), ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']),
-        ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']), ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']),
-        ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']),
+        ('\u{2c5f}', ['\u{2c2f}', '\u{0}', '\u{0}']), ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']),
+        ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']), ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']),
+        ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']), ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']),
+        ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']), ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']),
+        ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']), ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']),
+        ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']), ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']),
+        ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']), ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']),
+        ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']), ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']),
+        ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']), ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']),
+        ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']), ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']),
+        ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']), ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']),
+        ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']), ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']),
+        ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']), ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']),
+        ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']), ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']),
+        ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']), ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']),
+        ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']), ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']),
+        ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']), ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']),
+        ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']), ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']),
+        ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']), ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']),
+        ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']), ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']),
+        ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']), ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']),
+        ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']), ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']),
+        ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']), ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']),
+        ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']), ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']),
+        ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']), ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']),
+        ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']), ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']),
+        ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']), ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']),
+        ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']), ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']),
+        ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']), ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']),
+        ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']), ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']),
+        ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']), ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']),
+        ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']), ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']),
+        ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']), ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']),
+        ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']), ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']),
+        ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']), ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']),
+        ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']), ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']),
+        ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']), ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']),
+        ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']), ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']),
+        ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']), ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']),
+        ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']), ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']),
+        ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']), ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']),
+        ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']), ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']),
+        ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']), ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']),
+        ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']), ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']),
+        ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']), ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']),
+        ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']), ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']),
+        ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']), ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']),
+        ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']), ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']),
+        ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']), ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']),
+        ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']), ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']),
+        ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']), ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']),
+        ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']), ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']),
+        ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']), ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']),
+        ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']), ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']),
+        ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']), ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']),
+        ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']), ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']),
+        ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']), ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']),
+        ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']), ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']),
+        ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']), ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']),
+        ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']), ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']),
+        ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']), ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']),
+        ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']), ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']),
+        ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']), ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']),
+        ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']), ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']),
+        ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']), ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']),
+        ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']), ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']),
+        ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']), ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']),
+        ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']), ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']),
+        ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']), ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']),
+        ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']), ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']),
+        ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']), ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']),
+        ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']), ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']),
+        ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']), ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']),
+        ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']), ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']),
+        ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']), ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']),
+        ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']), ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']),
+        ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']), ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']),
+        ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']), ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']),
+        ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']), ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']),
+        ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']), ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']),
+        ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']), ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']),
+        ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']), ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']),
+        ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']), ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']),
+        ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']), ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']),
+        ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']), ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']),
+        ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']), ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']),
+        ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']), ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']),
+        ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']), ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']),
+        ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']), ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']),
+        ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']), ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']),
+        ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']), ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']),
+        ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']), ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']),
+        ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']), ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']),
+        ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']), ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']),
+        ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']), ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']),
+        ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']), ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']),
+        ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']), ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']),
+        ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']), ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']),
+        ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']), ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']),
+        ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']), ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']),
+        ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']), ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']),
+        ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']), ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']),
+        ('\u{a7c1}', ['\u{a7c0}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']),
         ('\u{a7c8}', ['\u{a7c7}', '\u{0}', '\u{0}']), ('\u{a7ca}', ['\u{a7c9}', '\u{0}', '\u{0}']),
-        ('\u{a7f6}', ['\u{a7f5}', '\u{0}', '\u{0}']), ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']),
-        ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']), ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']),
-        ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']), ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']),
-        ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']), ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']),
-        ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']), ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']),
-        ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']), ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']),
-        ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']), ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']),
-        ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']), ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']),
-        ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']), ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']),
-        ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']), ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']),
-        ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']), ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']),
-        ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']), ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']),
-        ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']), ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']),
-        ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']), ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']),
-        ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']), ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']),
-        ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']), ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']),
-        ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']), ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']),
-        ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']), ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']),
-        ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']), ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']),
-        ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']), ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']),
-        ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']), ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']),
-        ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']), ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']),
-        ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']), ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']),
-        ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']), ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']),
-        ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']), ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']),
-        ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']), ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']),
-        ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']), ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']),
-        ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']), ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']),
-        ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']), ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']),
-        ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']), ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']),
-        ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']), ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']),
-        ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']), ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']),
-        ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']), ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']),
-        ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']), ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']),
-        ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']), ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']),
-        ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']), ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']),
-        ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']), ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']),
-        ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']), ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']),
-        ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']), ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']),
-        ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']), ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']),
-        ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']), ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']),
-        ('\u{fb00}', ['F', 'F', '\u{0}']), ('\u{fb01}', ['F', 'I', '\u{0}']),
-        ('\u{fb02}', ['F', 'L', '\u{0}']), ('\u{fb03}', ['F', 'F', 'I']),
-        ('\u{fb04}', ['F', 'F', 'L']), ('\u{fb05}', ['S', 'T', '\u{0}']),
-        ('\u{fb06}', ['S', 'T', '\u{0}']), ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']),
+        ('\u{a7d1}', ['\u{a7d0}', '\u{0}', '\u{0}']), ('\u{a7d7}', ['\u{a7d6}', '\u{0}', '\u{0}']),
+        ('\u{a7d9}', ['\u{a7d8}', '\u{0}', '\u{0}']), ('\u{a7f6}', ['\u{a7f5}', '\u{0}', '\u{0}']),
+        ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']), ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']),
+        ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']), ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']),
+        ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']), ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']),
+        ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']), ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']),
+        ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']), ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']),
+        ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']), ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']),
+        ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']), ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']),
+        ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']), ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']),
+        ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']), ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']),
+        ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']), ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']),
+        ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']), ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']),
+        ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']), ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']),
+        ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']), ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']),
+        ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']), ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']),
+        ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']), ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']),
+        ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']), ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']),
+        ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']), ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']),
+        ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']), ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']),
+        ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']), ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']),
+        ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']), ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']),
+        ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']), ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']),
+        ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']), ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']),
+        ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']), ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']),
+        ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']), ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']),
+        ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']), ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']),
+        ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']), ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']),
+        ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']), ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']),
+        ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']), ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']),
+        ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']), ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']),
+        ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']), ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']),
+        ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']), ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']),
+        ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']), ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']),
+        ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']), ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']),
+        ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']), ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']),
+        ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']), ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']),
+        ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']), ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']),
+        ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']), ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']),
+        ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']), ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']),
+        ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']), ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']),
+        ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']), ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']),
+        ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']), ('\u{fb00}', ['F', 'F', '\u{0}']),
+        ('\u{fb01}', ['F', 'I', '\u{0}']), ('\u{fb02}', ['F', 'L', '\u{0}']),
+        ('\u{fb03}', ['F', 'F', 'I']), ('\u{fb04}', ['F', 'F', 'L']),
+        ('\u{fb05}', ['S', 'T', '\u{0}']), ('\u{fb06}', ['S', 'T', '\u{0}']),
+        ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']),
         ('\u{fb14}', ['\u{544}', '\u{535}', '\u{0}']),
         ('\u{fb15}', ['\u{544}', '\u{53b}', '\u{0}']),
         ('\u{fb16}', ['\u{54e}', '\u{546}', '\u{0}']),
@@ -2133,6 +2187,41 @@ pub mod conversions {
         ('\u{104f9}', ['\u{104d1}', '\u{0}', '\u{0}']),
         ('\u{104fa}', ['\u{104d2}', '\u{0}', '\u{0}']),
         ('\u{104fb}', ['\u{104d3}', '\u{0}', '\u{0}']),
+        ('\u{10597}', ['\u{10570}', '\u{0}', '\u{0}']),
+        ('\u{10598}', ['\u{10571}', '\u{0}', '\u{0}']),
+        ('\u{10599}', ['\u{10572}', '\u{0}', '\u{0}']),
+        ('\u{1059a}', ['\u{10573}', '\u{0}', '\u{0}']),
+        ('\u{1059b}', ['\u{10574}', '\u{0}', '\u{0}']),
+        ('\u{1059c}', ['\u{10575}', '\u{0}', '\u{0}']),
+        ('\u{1059d}', ['\u{10576}', '\u{0}', '\u{0}']),
+        ('\u{1059e}', ['\u{10577}', '\u{0}', '\u{0}']),
+        ('\u{1059f}', ['\u{10578}', '\u{0}', '\u{0}']),
+        ('\u{105a0}', ['\u{10579}', '\u{0}', '\u{0}']),
+        ('\u{105a1}', ['\u{1057a}', '\u{0}', '\u{0}']),
+        ('\u{105a3}', ['\u{1057c}', '\u{0}', '\u{0}']),
+        ('\u{105a4}', ['\u{1057d}', '\u{0}', '\u{0}']),
+        ('\u{105a5}', ['\u{1057e}', '\u{0}', '\u{0}']),
+        ('\u{105a6}', ['\u{1057f}', '\u{0}', '\u{0}']),
+        ('\u{105a7}', ['\u{10580}', '\u{0}', '\u{0}']),
+        ('\u{105a8}', ['\u{10581}', '\u{0}', '\u{0}']),
+        ('\u{105a9}', ['\u{10582}', '\u{0}', '\u{0}']),
+        ('\u{105aa}', ['\u{10583}', '\u{0}', '\u{0}']),
+        ('\u{105ab}', ['\u{10584}', '\u{0}', '\u{0}']),
+        ('\u{105ac}', ['\u{10585}', '\u{0}', '\u{0}']),
+        ('\u{105ad}', ['\u{10586}', '\u{0}', '\u{0}']),
+        ('\u{105ae}', ['\u{10587}', '\u{0}', '\u{0}']),
+        ('\u{105af}', ['\u{10588}', '\u{0}', '\u{0}']),
+        ('\u{105b0}', ['\u{10589}', '\u{0}', '\u{0}']),
+        ('\u{105b1}', ['\u{1058a}', '\u{0}', '\u{0}']),
+        ('\u{105b3}', ['\u{1058c}', '\u{0}', '\u{0}']),
+        ('\u{105b4}', ['\u{1058d}', '\u{0}', '\u{0}']),
+        ('\u{105b5}', ['\u{1058e}', '\u{0}', '\u{0}']),
+        ('\u{105b6}', ['\u{1058f}', '\u{0}', '\u{0}']),
+        ('\u{105b7}', ['\u{10590}', '\u{0}', '\u{0}']),
+        ('\u{105b8}', ['\u{10591}', '\u{0}', '\u{0}']),
+        ('\u{105b9}', ['\u{10592}', '\u{0}', '\u{0}']),
+        ('\u{105bb}', ['\u{10594}', '\u{0}', '\u{0}']),
+        ('\u{105bc}', ['\u{10595}', '\u{0}', '\u{0}']),
         ('\u{10cc0}', ['\u{10c80}', '\u{0}', '\u{0}']),
         ('\u{10cc1}', ['\u{10c81}', '\u{0}', '\u{0}']),
         ('\u{10cc2}', ['\u{10c82}', '\u{0}', '\u{0}']),
index 0ae625bdb68c6244f20b7a65c5e6154d6594afd4..b3af1328c90d45869d0efb236f97e77e6a53df53 100644 (file)
@@ -1,5 +1,6 @@
 use core::array;
 use core::convert::TryFrom;
+use core::sync::atomic::{AtomicUsize, Ordering};
 
 #[test]
 fn array_from_ref() {
@@ -303,8 +304,6 @@ fn array_map() {
 #[test]
 #[should_panic(expected = "test succeeded")]
 fn array_map_drop_safety() {
-    use core::sync::atomic::AtomicUsize;
-    use core::sync::atomic::Ordering;
     static DROPPED: AtomicUsize = AtomicUsize::new(0);
     struct DropCounter;
     impl Drop for DropCounter {
@@ -356,3 +355,84 @@ fn new() -> B<'a> {
     b3.a[0].set(Some(&b1));
     b3.a[1].set(Some(&b2));
 }
+
+#[test]
+fn array_from_fn() {
+    let array = core::array::from_fn(|idx| idx);
+    assert_eq!(array, [0, 1, 2, 3, 4]);
+}
+
+#[test]
+fn array_try_from_fn() {
+    #[derive(Debug, PartialEq)]
+    enum SomeError {
+        Foo,
+    }
+
+    let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
+    assert_eq!(array, Ok([0, 1, 2, 3, 4]));
+
+    let another_array = core::array::try_from_fn::<SomeError, _, (), 2>(|_| Err(SomeError::Foo));
+    assert_eq!(another_array, Err(SomeError::Foo));
+}
+
+#[cfg(not(panic = "abort"))]
+#[test]
+fn array_try_from_fn_drops_inserted_elements_on_err() {
+    static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+    struct CountDrop;
+    impl Drop for CountDrop {
+        fn drop(&mut self) {
+            DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    let _ = catch_unwind_silent(move || {
+        let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
+            if idx == 2 {
+                return Err(());
+            }
+            Ok(CountDrop)
+        });
+    });
+
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
+}
+
+#[cfg(not(panic = "abort"))]
+#[test]
+fn array_try_from_fn_drops_inserted_elements_on_panic() {
+    static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+    struct CountDrop;
+    impl Drop for CountDrop {
+        fn drop(&mut self) {
+            DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    let _ = catch_unwind_silent(move || {
+        let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
+            if idx == 2 {
+                panic!("peek a boo");
+            }
+            Ok(CountDrop)
+        });
+    });
+
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
+}
+
+#[cfg(not(panic = "abort"))]
+// https://stackoverflow.com/a/59211505
+fn catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R>
+where
+    F: FnOnce() -> R + core::panic::UnwindSafe,
+{
+    let prev_hook = std::panic::take_hook();
+    std::panic::set_hook(Box::new(|_| {}));
+    let result = std::panic::catch_unwind(f);
+    std::panic::set_hook(prev_hook);
+    result
+}
index 0673564dd5c4af6781fedd74b55dd64ea423a75b..3608853dce4e05e41679195add2e47c8772ef9c4 100644 (file)
@@ -26,6 +26,7 @@
 #![feature(extern_types)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
+#![feature(array_from_fn)]
 #![feature(hashmap_internals)]
 #![feature(try_find)]
 #![feature(is_sorted)]
index e21a1507a62e200689e9a2d182d2673461baaa0f..3a06cd04ab146345e3d3198a9521d60b7bcc3a98 100644 (file)
@@ -61,7 +61,7 @@
 /// non-panicking way to detect whether the infrastructure required to use the
 /// API of proc_macro is presently available. Returns true if invoked from
 /// inside of a procedural macro, false if invoked from any other binary.
-#[unstable(feature = "proc_macro_is_available", issue = "71436")]
+#[stable(feature = "proc_macro_is_available", since = "1.57.0")]
 pub fn is_available() -> bool {
     bridge::Bridge::is_available()
 }
index 528bb1bf6e9f9feb22f73a6af644ad12bd49bcd6..f0bd09091d7b53f8a60767e8ddf7acf46aa8767d 100644 (file)
@@ -1720,6 +1720,7 @@ pub fn key_mut(&mut self) -> &mut K {
     /// Converts the entry into a mutable reference to the key in the entry
     /// with a lifetime bound to the map itself.
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn into_key(self) -> &'a mut K {
         self.base.into_key()
@@ -1735,6 +1736,7 @@ pub fn get(&self) -> &V {
     /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
     /// with a lifetime bound to the map itself.
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn into_mut(self) -> &'a mut V {
         self.base.into_mut()
@@ -1764,6 +1766,7 @@ pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
     /// Converts the `OccupiedEntry` into a mutable reference to the key and value in the entry
     /// with a lifetime bound to the map itself.
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
         self.base.into_key_value()
index fe1f28f00c4031aa8291120b6afc9ba5b842ffef..6b488e49ed74b4dc9b0c07e4c6a0667592219355 100644 (file)
@@ -322,6 +322,7 @@ pub fn as_bytes(&self) -> &[u8] {
     ///
     /// assert_eq!(bytes, value.unwrap_err().into_bytes());
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     pub fn into_bytes(self) -> Vec<u8> {
         self.bytes
     }
@@ -524,6 +525,7 @@ pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
     /// }
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub fn into_raw(self) -> *mut c_char {
         Box::into_raw(self.into_inner()) as *mut c_char
@@ -547,7 +549,6 @@ pub fn into_raw(self) -> *mut c_char {
     /// let err = cstring.into_string().err().expect("into_string().err() failed");
     /// assert_eq!(err.utf8_error().valid_up_to(), 1);
     /// ```
-
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_string(self) -> Result<String, IntoStringError> {
         String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError {
@@ -571,6 +572,7 @@ pub fn into_string(self) -> Result<String, IntoStringError> {
     /// let bytes = c_string.into_bytes();
     /// assert_eq!(bytes, vec![b'f', b'o', b'o']);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         let mut vec = self.into_inner().into_vec();
@@ -591,6 +593,7 @@ pub fn into_bytes(self) -> Vec<u8> {
     /// let bytes = c_string.into_bytes_with_nul();
     /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes_with_nul(self) -> Vec<u8> {
         self.into_inner().into_vec()
@@ -667,6 +670,7 @@ pub fn as_c_str(&self) -> &CStr {
     /// assert_eq!(&*boxed,
     ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "into_boxed_c_str", since = "1.20.0")]
     pub fn into_boxed_c_str(self) -> Box<CStr> {
         unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) }
@@ -1018,6 +1022,7 @@ pub fn nul_position(&self) -> usize {
     /// let nul_error = CString::new("foo\0bar").unwrap_err();
     /// assert_eq!(nul_error.into_vec(), b"foo\0bar");
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_vec(self) -> Vec<u8> {
         self.1
@@ -1092,6 +1097,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 impl IntoStringError {
     /// Consumes this error, returning original [`CString`] which generated the
     /// error.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_cstring(self) -> CString {
         self.inner
index c305519dd4461ad549a98d7a65778b7278e301d1..f5cef60e1267ac88bca50cc27ae627c4294d4622 100644 (file)
@@ -346,6 +346,7 @@ pub fn shrink_to(&mut self, min_capacity: usize) {
     ///
     /// let b: Box<OsStr> = s.into_boxed_os_str();
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
     pub fn into_boxed_os_str(self) -> Box<OsStr> {
         let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
index 243207a6065449cd4467f6f4fe88f674096c7745..2864e94f60f2c82ca542ac8fa890701bc340a0a9 100644 (file)
@@ -242,14 +242,13 @@ pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
                 self.pos = new_pos as usize;
                 return Ok(());
             }
-        } else {
-            if let Some(new_pos) = pos.checked_add(offset as u64) {
-                if new_pos <= self.cap as u64 {
-                    self.pos = new_pos as usize;
-                    return Ok(());
-                }
+        } else if let Some(new_pos) = pos.checked_add(offset as u64) {
+            if new_pos <= self.cap as u64 {
+                self.pos = new_pos as usize;
+                return Ok(());
             }
         }
+
         self.seek(SeekFrom::Current(offset)).map(drop)
     }
 }
index ebbda7c1bf2a0b6fa8a45e563fa0db4f373bc4d2..c7423e4d92a896c359743285a3e76f2d47ab3ed6 100644 (file)
@@ -476,6 +476,7 @@ pub struct WriterPanicked {
 impl WriterPanicked {
     /// Returns the perhaps-unwritten data.  Some of this data may have been written by the
     /// panicking call(s) to the underlying writer, so simply writing it again is not a good idea.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
     pub fn into_inner(self) -> Vec<u8> {
         self.buf
index 51666c0a3c7f1bf534c653b48916c51c7314bc6c..6101260e149a0838b7497d239c4a101390272515 100644 (file)
@@ -657,6 +657,7 @@ pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'stat
     /// }
     /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
         match self.repr {
index 1ac3bbc95c66dea8d405ddd7fb76e58704803b2d..9389501e0129e63b8a6d4d5a042b06a79e7a27a5 100644 (file)
@@ -464,6 +464,7 @@ pub fn into_locked(self) -> StdinLock<'static> {
     ///     println!("got a line: {}", line.unwrap());
     /// }
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "stdin_forwarders", issue = "87096")]
     pub fn lines(self) -> Lines<StdinLock<'static>> {
         self.into_locked().lines()
index 223726d45d72a4ffe7ee2ad5897c7e97575cbbda..2c6e3930059905bd94f42b56c2305db7b4a72b2b 100644 (file)
@@ -883,6 +883,7 @@ pub fn incoming(&self) -> Incoming<'_> {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
     pub fn into_incoming(self) -> IntoIncoming {
         IntoIncoming { listener: self }
index a45ecf6ea8c63ed05ee1ff29482d6546b5fc98dd..6bfc7b0a5c1dfb89b42a3f79840495da3fa12825 100644 (file)
@@ -532,6 +532,7 @@ impl<'a> Component<'a> {
     /// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
     /// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_os_str(self) -> &'a OsStr {
         match self {
@@ -1428,6 +1429,7 @@ fn _set_extension(&mut self, extension: &OsStr) -> bool {
     /// let os_str = p.into_os_string();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_os_string(self) -> OsString {
         self.inner
@@ -1435,6 +1437,7 @@ pub fn into_os_string(self) -> OsString {
 
     /// Converts this `PathBuf` into a [boxed](Box) [`Path`].
     #[stable(feature = "into_boxed_path", since = "1.20.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_boxed_path(self) -> Box<Path> {
         let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path;
index 5c68400114d49744de3e73b1663db7555664b021..4bd06475e2761510fe681acd80de672683f0e094 100644 (file)
 use crate::str;
 use crate::sys::pipe::{read2, AnonPipe};
 use crate::sys::process as imp;
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 pub use crate::sys_common::process::CommandEnvs;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
@@ -943,13 +943,12 @@ pub fn status(&mut self) -> io::Result<ExitStatus> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::process::Command;
     ///
     /// let cmd = Command::new("echo");
     /// assert_eq!(cmd.get_program(), "echo");
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_program(&self) -> &OsStr {
         self.inner.get_program()
     }
@@ -963,7 +962,6 @@ pub fn get_program(&self) -> &OsStr {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::ffi::OsStr;
     /// use std::process::Command;
     ///
@@ -972,7 +970,7 @@ pub fn get_program(&self) -> &OsStr {
     /// let args: Vec<&OsStr> = cmd.get_args().collect();
     /// assert_eq!(args, &["first", "second"]);
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_args(&self) -> CommandArgs<'_> {
         CommandArgs { inner: self.inner.get_args() }
     }
@@ -992,7 +990,6 @@ pub fn get_args(&self) -> CommandArgs<'_> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::ffi::OsStr;
     /// use std::process::Command;
     ///
@@ -1004,7 +1001,7 @@ pub fn get_args(&self) -> CommandArgs<'_> {
     ///     (OsStr::new("TZ"), None)
     /// ]);
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_envs(&self) -> CommandEnvs<'_> {
         self.inner.get_envs()
     }
@@ -1016,7 +1013,6 @@ pub fn get_envs(&self) -> CommandEnvs<'_> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::path::Path;
     /// use std::process::Command;
     ///
@@ -1025,7 +1021,7 @@ pub fn get_envs(&self) -> CommandEnvs<'_> {
     /// cmd.current_dir("/bin");
     /// assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin")));
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_current_dir(&self) -> Option<&Path> {
         self.inner.get_current_dir()
     }
@@ -1057,13 +1053,13 @@ fn as_inner_mut(&mut self) -> &mut imp::Command {
 ///
 /// This struct is created by [`Command::get_args`]. See its documentation for
 /// more.
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 #[derive(Debug)]
 pub struct CommandArgs<'a> {
     inner: imp::CommandArgs<'a>,
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> Iterator for CommandArgs<'a> {
     type Item = &'a OsStr;
     fn next(&mut self) -> Option<&'a OsStr> {
@@ -1074,7 +1070,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> ExactSizeIterator for CommandArgs<'a> {
     fn len(&self) -> usize {
         self.inner.len()
index 1c37f4ee4981e51f07cc2d30df4ab60fed59823b..2ba6c8d830ede552890c37898353615bf2a69dc8 100644 (file)
@@ -307,6 +307,9 @@ pub fn abort_internal() -> ! {
         #[link(name = "zircon")]
         #[link(name = "fdio")]
         extern "C" {}
+    } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] {
+        #[link(name = "dl")]
+        extern "C" {}
     }
 }
 
index e8747e39bcbf4f1cf81f108c3eaf0e4827dd1435..db1a2a26a8903c21797fce7449b14749c400aec6 100644 (file)
@@ -143,14 +143,15 @@ pub unsafe fn cleanup() {
     }
 
     unsafe fn get_stackp() -> *mut libc::c_void {
-        let stackp = mmap(
-            ptr::null_mut(),
-            SIGSTKSZ + page_size(),
-            PROT_READ | PROT_WRITE,
-            MAP_PRIVATE | MAP_ANON,
-            -1,
-            0,
-        );
+        // OpenBSD requires this flag for stack mapping
+        // otherwise the said mapping will fail as a no-op on most systems
+        // and has a different meaning on FreeBSD
+        #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",))]
+        let flags = MAP_PRIVATE | MAP_ANON | libc::MAP_STACK;
+        #[cfg(not(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",)))]
+        let flags = MAP_PRIVATE | MAP_ANON;
+        let stackp =
+            mmap(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0);
         if stackp == MAP_FAILED {
             panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error());
         }
index 891f3413e9138fd4f93ae6a38bf8e392380e8625..6f4863057aba431b0635eb11a4671e335e573913 100644 (file)
@@ -594,7 +594,8 @@ pub unsafe fn current() -> Option<Guard> {
                 Some(stackaddr - guardsize..stackaddr)
             } else if cfg!(all(target_os = "linux", target_env = "musl")) {
                 Some(stackaddr - guardsize..stackaddr)
-            } else if cfg!(all(target_os = "linux", target_env = "gnu")) {
+            } else if cfg!(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))
+            {
                 // glibc used to include the guard area within the stack, as noted in the BUGS
                 // section of `man pthread_attr_getguardsize`.  This has been corrected starting
                 // with glibc 2.27, and in some distro backports, so the guard is now placed at the
index cc137771bb8d41bf79c4dd6efa7717e330901b1d..ad550a823ae90e2596c26614d19c2911bbd953ad 100644 (file)
@@ -558,7 +558,7 @@ fn into_inner(self) -> Handle {
 
 impl FromInner<Handle> for File {
     fn from_inner(handle: Handle) -> File {
-        File { handle: handle }
+        File { handle }
     }
 }
 
@@ -672,7 +672,7 @@ pub fn set_readonly(&mut self, readonly: bool) {
 
 impl FileType {
     fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType {
-        FileType { attributes: attrs, reparse_tag: reparse_tag }
+        FileType { attributes: attrs, reparse_tag }
     }
     pub fn is_dir(&self) -> bool {
         !self.is_symlink() && self.is_directory()
index 755dc0a6c8b47045a5ce45149d0f1762a454a3bc..18a2a36ad2548e25c0bab340235d2fd41ac81646 100644 (file)
@@ -9,10 +9,10 @@ impl Handler {
     pub unsafe fn new() -> Handler {
         // This API isn't available on XP, so don't panic in that case and just
         // pray it works out ok.
-        if c::SetThreadStackGuarantee(&mut 0x5000) == 0 {
-            if c::GetLastError() as u32 != c::ERROR_CALL_NOT_IMPLEMENTED as u32 {
-                panic!("failed to reserve stack space for exception handling");
-            }
+        if c::SetThreadStackGuarantee(&mut 0x5000) == 0
+            && c::GetLastError() as u32 != c::ERROR_CALL_NOT_IMPLEMENTED as u32
+        {
+            panic!("failed to reserve stack space for exception handling");
         }
         Handler
     }
index e6a099f0e81a0ad141b1f2950e34ed78c8987db4..d5e8f12414ff2d688007a157925030225d107518 100644 (file)
@@ -93,10 +93,8 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
         if stop {
             return false;
         }
-        if !hit {
-            if start {
-                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
-            }
+        if !hit && start {
+            res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
         }
 
         idx += 1;
index 38007d5c414ecd42bd97456334005c4231756bd9..3d71219756a207bfaba82d9a6a980ef102e6e338 100644 (file)
@@ -106,13 +106,13 @@ pub fn iter(&self) -> CommandEnvs<'_> {
 /// This struct is created by
 /// [`Command::get_envs`][crate::process::Command::get_envs]. See its
 /// documentation for more.
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 #[derive(Debug)]
 pub struct CommandEnvs<'a> {
     iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> Iterator for CommandEnvs<'a> {
     type Item = (&'a OsStr, Option<&'a OsStr>);
     fn next(&mut self) -> Option<Self::Item> {
@@ -123,7 +123,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> ExactSizeIterator for CommandEnvs<'a> {
     fn len(&self) -> usize {
         self.iter.len()
index 25be9e7cc6c0cd217769d902ac6c89b7de8fd09a..e263780bf38796dbdae16e73b90bb8774edf39eb 100644 (file)
@@ -63,7 +63,7 @@
 // don't want to duplicate it here.
 #[cfg(all(
     target_os = "linux",
-    target_env = "gnu",
+    any(target_env = "gnu", target_env = "uclibc"),
     not(feature = "llvm-libunwind"),
     not(feature = "system-llvm-libunwind")
 ))]
@@ -72,7 +72,7 @@
 
 #[cfg(all(
     target_os = "linux",
-    target_env = "gnu",
+    any(target_env = "gnu", target_env = "uclibc"),
     not(feature = "llvm-libunwind"),
     feature = "system-llvm-libunwind"
 ))]
index 272b7153111370a1a341474b84f971857fc096e4..8594fa42266b41306d242f59c65b27fc5ca732d0 100644 (file)
@@ -653,7 +653,7 @@ fn run(self, builder: &Builder<'_>) {
         let host = self.host;
         let compiler = builder.compiler(stage, host);
 
-        let clippy = builder
+        builder
             .ensure(tool::Clippy { compiler, target: self.host, extra_features: Vec::new() })
             .expect("in-tree tool");
         let mut cargo = tool::prepare_tool_cargo(
@@ -672,14 +672,7 @@ fn run(self, builder: &Builder<'_>) {
         cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
         cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
         let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
-        let target_libs = builder
-            .stage_out(compiler, Mode::ToolRustc)
-            .join(&self.host.triple)
-            .join(builder.cargo_dir());
         cargo.env("HOST_LIBS", host_libs);
-        cargo.env("TARGET_LIBS", target_libs);
-        // clippy tests need to find the driver
-        cargo.env("CLIPPY_DRIVER_PATH", clippy);
 
         cargo.arg("--").args(builder.config.cmd.test_args());
 
@@ -905,7 +898,7 @@ fn run(self, builder: &Builder<'_>) {
         let out_dir = builder.test_out(self.target).join("rustdoc-gui");
 
         // We remove existing folder to be sure there won't be artifacts remaining.
-        let _ = fs::remove_dir_all(&out_dir);
+        builder.clear_if_dirty(&out_dir, &builder.rustdoc(self.compiler));
 
         let src_path = builder.build.src.join("src/test/rustdoc-gui/src");
         // We generate docs for the libraries present in the rustdoc-gui's src folder.
index 3d30ee49022d8f9318abc0fa52d71cd8310799d1..416fa50374fe412c89b9b3c5cdff7f890c332c58 100644 (file)
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
index b358dce3cdfe855d41203fa02517c461df7d58af..814e1fa16f87d87333501796d7f3f7febc7469a5 100644 (file)
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
index aa13119d50c19f346b521037f2f490a5e82de246..83439bb81e23d084dcf1c2b17cc1c2a59b270096 100644 (file)
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
index c9c141afad131d1883466c44a7847e0108bf90a5..2e995b2c0bdfd327cd53cafa125555f9e3b849fc 100644 (file)
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
index 26fef88946251e1ede97342b3543e7892fee137c..bbeab598f2292870baca8e070388fd632881b592 100644 (file)
@@ -220,6 +220,7 @@ target | std | host | notes
 `armv6-unknown-netbsd-eabihf` | ? |  |
 `armv6k-nintendo-3ds` | * |  | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
 `armv7-apple-ios` | ✓ |  | ARMv7 iOS, Cortex-a8
+`armv7-unknown-linux-uclibceabihf` | ✓ | ? | ARMv7 Linux uClibc
 `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
 `armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
 `armv7-wrs-vxworks-eabihf` | ? |  |
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
new file mode 100644 (file)
index 0000000..b3a4275
--- /dev/null
@@ -0,0 +1,66 @@
+# armv7-unknown-linux-uclibceabihf
+
+**Tier: 3**
+
+This tier supports the ARMv7 processor running a Linux kernel and uClibc-ng standard library.  It provides full support for rust and the rust standard library.
+
+## Designated Developers
+
+* [@skrap](https://github.com/skrap)
+
+## Requirements
+
+This target is cross compiled, and requires a cross toolchain.  You can find suitable pre-built toolchains at [bootlin](https://toolchains.bootlin.com/) or build one yourself via [buildroot](https://buildroot.org).
+
+## Building
+
+### Get a C toolchain
+
+Compiling rust for this target has been tested on `x86_64` linux hosts.  Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.
+
+If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2020.08-1.tar.bz2), and unpack it into a directory.
+
+### Configure rust
+
+The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`:
+
+```toml
+[build]
+target = ["armv7-unknown-linux-uclibceabihf"]
+stage = 2
+
+[target.armv7-unknown-linux-uclibceabihf]
+# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
+cc = "/TOOLCHAIN_PATH/bin/arm-buildroot-linux-uclibcgnueabihf-gcc"
+```
+
+### Build
+
+```sh
+# in rust dir
+./x.py build --stage 2
+```
+
+## Building and Running Rust Programs
+
+To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-arm` [userspace emulation](https://qemu-project.gitlab.io/qemu/user/main.html) program.  This avoids having a full emulated ARM system by doing dynamic binary translation and dynamic system call translation.  It lets you run ARM programs directly on your `x86_64` kernel.  It's very convenient!
+
+To use:
+
+* Install `qemu-arm` according to your distro.
+* Link your built toolchain via:
+  * `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2`
+* Create a test program
+
+```sh
+cargo new hello_world
+cd hello_world
+```
+
+* Build and run
+
+```sh
+CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_RUNNER="qemu-arm -L ${TOOLCHAIN}/arm-buildroot-linux-uclibcgnueabihf/sysroot/" \
+CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_LINKER=${TOOLCHAIN}/bin/arm-buildroot-linux-uclibcgnueabihf-gcc \
+cargo +stage2 run --target armv7-unknown-linux-uclibceabihf
+```
index a2afa88028fea4c8b0ae77796555950f587f8b7b..5a2cef24870be49daaff686d45f225e39cfdffd4 100644 (file)
@@ -456,7 +456,7 @@ operand := reg_operand / "const" const_expr / "sym" path
 clobber_abi := "clobber_abi(" <abi> ")"
 option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
 options := "options(" option *["," option] [","] ")"
-asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," clobber_abi]  ["," options] [","] ")"
+asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," clobber_abi] *("," options) [","] ")"
 ```
 
 Inline assembly is currently supported on the following architectures:
index 1436e51f31820b27c11003960e1fae161f9a4bc3..f9d1666977134f70fda11a90096bbd3fd25d7473 100644 (file)
@@ -118,7 +118,7 @@ fn generate_for_trait(
                 span: Span::dummy(),
                 unsafety: hir::Unsafety::Normal,
                 generics: new_generics,
-                trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
+                trait_: Some(trait_ref.clean(self.cx)),
                 for_: ty.clean(self.cx),
                 items: Vec::new(),
                 negative_polarity,
@@ -166,16 +166,16 @@ fn get_lifetime(region: Region<'_>, names_map: &FxHashMap<Symbol, Lifetime>) ->
             .clone()
     }
 
-    // This method calculates two things: Lifetime constraints of the form 'a: 'b,
-    // and region constraints of the form ReVar: 'a
-    //
-    // This is essentially a simplified version of lexical_region_resolve. However,
-    // handle_lifetimes determines what *needs be* true in order for an impl to hold.
-    // lexical_region_resolve, along with much of the rest of the compiler, is concerned
-    // with determining if a given set up constraints/predicates *are* met, given some
-    // starting conditions (e.g., user-provided code). For this reason, it's easier
-    // to perform the calculations we need on our own, rather than trying to make
-    // existing inference/solver code do what we want.
+    /// This method calculates two things: Lifetime constraints of the form `'a: 'b`,
+    /// and region constraints of the form `RegionVid: 'a`
+    ///
+    /// This is essentially a simplified version of lexical_region_resolve. However,
+    /// handle_lifetimes determines what *needs be* true in order for an impl to hold.
+    /// lexical_region_resolve, along with much of the rest of the compiler, is concerned
+    /// with determining if a given set up constraints/predicates *are* met, given some
+    /// starting conditions (e.g., user-provided code). For this reason, it's easier
+    /// to perform the calculations we need on our own, rather than trying to make
+    /// existing inference/solver code do what we want.
     fn handle_lifetimes<'cx>(
         regions: &RegionConstraintData<'cx>,
         names_map: &FxHashMap<Symbol, Lifetime>,
@@ -353,48 +353,35 @@ fn make_final_bounds(
                 if let Some(data) = ty_to_fn.get(&ty) {
                     let (poly_trait, output) =
                         (data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new));
-                    let new_ty = match poly_trait.trait_ {
-                        Type::ResolvedPath { ref path, ref did } => {
-                            let mut new_path = path.clone();
-                            let last_segment =
-                                new_path.segments.pop().expect("segments were empty");
-
-                            let (old_input, old_output) = match last_segment.args {
-                                GenericArgs::AngleBracketed { args, .. } => {
-                                    let types = args
-                                        .iter()
-                                        .filter_map(|arg| match arg {
-                                            GenericArg::Type(ty) => Some(ty.clone()),
-                                            _ => None,
-                                        })
-                                        .collect();
-                                    (types, None)
-                                }
-                                GenericArgs::Parenthesized { inputs, output, .. } => {
-                                    (inputs, output)
-                                }
-                            };
+                    let mut new_path = poly_trait.trait_.clone();
+                    let last_segment = new_path.segments.pop().expect("segments were empty");
+
+                    let (old_input, old_output) = match last_segment.args {
+                        GenericArgs::AngleBracketed { args, .. } => {
+                            let types = args
+                                .iter()
+                                .filter_map(|arg| match arg {
+                                    GenericArg::Type(ty) => Some(ty.clone()),
+                                    _ => None,
+                                })
+                                .collect();
+                            (types, None)
+                        }
+                        GenericArgs::Parenthesized { inputs, output } => (inputs, output),
+                    };
 
-                            if old_output.is_some() && old_output != output {
-                                panic!(
-                                    "Output mismatch for {:?} {:?} {:?}",
-                                    ty, old_output, data.1
-                                );
-                            }
+                    if old_output.is_some() && old_output != output {
+                        panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, data.1);
+                    }
 
-                            let new_params =
-                                GenericArgs::Parenthesized { inputs: old_input, output };
+                    let new_params = GenericArgs::Parenthesized { inputs: old_input, output };
 
-                            new_path
-                                .segments
-                                .push(PathSegment { name: last_segment.name, args: new_params });
+                    new_path
+                        .segments
+                        .push(PathSegment { name: last_segment.name, args: new_params });
 
-                            Type::ResolvedPath { path: new_path, did: *did }
-                        }
-                        _ => panic!("Unexpected data: {:?}, {:?}", ty, data),
-                    };
                     bounds.insert(GenericBound::TraitBound(
-                        PolyTrait { trait_: new_ty, generic_params: poly_trait.generic_params },
+                        PolyTrait { trait_: new_path, generic_params: poly_trait.generic_params },
                         hir::TraitBoundModifier::None,
                     ));
                 }
@@ -423,15 +410,15 @@ fn make_final_bounds(
             .collect()
     }
 
-    // Converts the calculated ParamEnv and lifetime information to a clean::Generics, suitable for
-    // display on the docs page. Cleaning the Predicates produces sub-optimal `WherePredicate`s,
-    // so we fix them up:
-    //
-    // * Multiple bounds for the same type are coalesced into one: e.g., 'T: Copy', 'T: Debug'
-    // becomes 'T: Copy + Debug'
-    // * Fn bounds are handled specially - instead of leaving it as 'T: Fn(), <T as Fn::Output> =
-    // K', we use the dedicated syntax 'T: Fn() -> K'
-    // * We explicitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
+    /// Converts the calculated `ParamEnv` and lifetime information to a [`clean::Generics`](Generics), suitable for
+    /// display on the docs page. Cleaning the `Predicates` produces sub-optimal [`WherePredicate`]s,
+    /// so we fix them up:
+    ///
+    /// * Multiple bounds for the same type are coalesced into one: e.g., `T: Copy`, `T: Debug`
+    /// becomes `T: Copy + Debug`
+    /// * `Fn` bounds are handled specially - instead of leaving it as `T: Fn(), <T as Fn::Output> =
+    /// K`, we use the dedicated syntax `T: Fn() -> K`
+    /// * We explicitly add a `?Sized` bound if we didn't find any `Sized` predicates for a type
     fn param_env_to_generics(
         &mut self,
         item_def_id: DefId,
@@ -476,7 +463,7 @@ fn param_env_to_generics(
         let mut has_sized = FxHashSet::default();
         let mut ty_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default();
         let mut lifetime_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default();
-        let mut ty_to_traits: FxHashMap<Type, FxHashSet<Type>> = Default::default();
+        let mut ty_to_traits: FxHashMap<Type, FxHashSet<Path>> = Default::default();
 
         let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = Default::default();
 
@@ -511,11 +498,11 @@ fn param_env_to_generics(
                     if b.is_sized_bound(self.cx) {
                         has_sized.insert(ty.clone());
                     } else if !b
-                        .get_trait_type()
-                        .and_then(|t| {
+                        .get_trait_path()
+                        .and_then(|trait_| {
                             ty_to_traits
                                 .get(&ty)
-                                .map(|bounds| bounds.contains(&strip_type(t.clone())))
+                                .map(|bounds| bounds.contains(&strip_path_generics(trait_.clone())))
                         })
                         .unwrap_or(false)
                     {
@@ -532,7 +519,7 @@ fn param_env_to_generics(
                                 // that we don't end up with duplicate bounds (e.g., for<'b, 'b>)
                                 for_generics.extend(p.generic_params.clone());
                                 p.generic_params = for_generics.into_iter().collect();
-                                self.is_fn_ty(&p.trait_)
+                                self.is_fn_trait(&p.trait_)
                             }
                             _ => false,
                         };
@@ -558,78 +545,59 @@ fn param_env_to_generics(
                     match lhs {
                         Type::QPath { name: left_name, ref self_type, ref trait_, .. } => {
                             let ty = &*self_type;
-                            match **trait_ {
-                                Type::ResolvedPath { path: ref trait_path, ref did } => {
-                                    let mut new_trait_path = trait_path.clone();
-
-                                    if self.is_fn_ty(trait_) && left_name == sym::Output {
-                                        ty_to_fn
-                                            .entry(*ty.clone())
-                                            .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone())))
-                                            .or_insert((None, Some(rhs)));
-                                        continue;
-                                    }
-
-                                    let args = &mut new_trait_path
-                                        .segments
-                                        .last_mut()
-                                        .expect("segments were empty")
-                                        .args;
-
-                                    match args {
-                                        // Convert something like '<T as Iterator::Item> = u8'
-                                        // to 'T: Iterator<Item=u8>'
-                                        GenericArgs::AngleBracketed {
-                                            ref mut bindings, ..
-                                        } => {
-                                            bindings.push(TypeBinding {
-                                                name: left_name,
-                                                kind: TypeBindingKind::Equality { ty: rhs },
-                                            });
-                                        }
-                                        GenericArgs::Parenthesized { .. } => {
-                                            existing_predicates.push(WherePredicate::EqPredicate {
-                                                lhs: lhs.clone(),
-                                                rhs,
-                                            });
-                                            continue; // If something other than a Fn ends up
-                                            // with parenthesis, leave it alone
-                                        }
-                                    }
-
-                                    let bounds = ty_to_bounds.entry(*ty.clone()).or_default();
-
-                                    bounds.insert(GenericBound::TraitBound(
-                                        PolyTrait {
-                                            trait_: Type::ResolvedPath {
-                                                path: new_trait_path,
-                                                did: *did,
-                                            },
-                                            generic_params: Vec::new(),
-                                        },
-                                        hir::TraitBoundModifier::None,
-                                    ));
-
-                                    // Remove any existing 'plain' bound (e.g., 'T: Iterator`) so
-                                    // that we don't see a
-                                    // duplicate bound like `T: Iterator + Iterator<Item=u8>`
-                                    // on the docs page.
-                                    bounds.remove(&GenericBound::TraitBound(
-                                        PolyTrait {
-                                            trait_: *trait_.clone(),
-                                            generic_params: Vec::new(),
-                                        },
-                                        hir::TraitBoundModifier::None,
-                                    ));
-                                    // Avoid creating any new duplicate bounds later in the outer
-                                    // loop
-                                    ty_to_traits
-                                        .entry(*ty.clone())
-                                        .or_default()
-                                        .insert(*trait_.clone());
+                            let mut new_trait = trait_.clone();
+
+                            if self.is_fn_trait(trait_) && left_name == sym::Output {
+                                ty_to_fn
+                                    .entry(*ty.clone())
+                                    .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone())))
+                                    .or_insert((None, Some(rhs)));
+                                continue;
+                            }
+
+                            let args = &mut new_trait
+                                .segments
+                                .last_mut()
+                                .expect("segments were empty")
+                                .args;
+
+                            match args {
+                                // Convert something like '<T as Iterator::Item> = u8'
+                                // to 'T: Iterator<Item=u8>'
+                                GenericArgs::AngleBracketed { ref mut bindings, .. } => {
+                                    bindings.push(TypeBinding {
+                                        name: left_name,
+                                        kind: TypeBindingKind::Equality { ty: rhs },
+                                    });
+                                }
+                                GenericArgs::Parenthesized { .. } => {
+                                    existing_predicates.push(WherePredicate::EqPredicate {
+                                        lhs: lhs.clone(),
+                                        rhs,
+                                    });
+                                    continue; // If something other than a Fn ends up
+                                    // with parenthesis, leave it alone
                                 }
-                                _ => panic!("Unexpected trait {:?} for {:?}", trait_, item_def_id),
                             }
+
+                            let bounds = ty_to_bounds.entry(*ty.clone()).or_default();
+
+                            bounds.insert(GenericBound::TraitBound(
+                                PolyTrait { trait_: new_trait, generic_params: Vec::new() },
+                                hir::TraitBoundModifier::None,
+                            ));
+
+                            // Remove any existing 'plain' bound (e.g., 'T: Iterator`) so
+                            // that we don't see a
+                            // duplicate bound like `T: Iterator + Iterator<Item=u8>`
+                            // on the docs page.
+                            bounds.remove(&GenericBound::TraitBound(
+                                PolyTrait { trait_: trait_.clone(), generic_params: Vec::new() },
+                                hir::TraitBoundModifier::None,
+                            ));
+                            // Avoid creating any new duplicate bounds later in the outer
+                            // loop
+                            ty_to_traits.entry(*ty.clone()).or_default().insert(trait_.clone());
                         }
                         _ => panic!("Unexpected LHS {:?} for {:?}", lhs, item_def_id),
                     }
@@ -664,11 +632,11 @@ fn param_env_to_generics(
         Generics { params: generic_params, where_predicates: existing_predicates }
     }
 
-    // Ensure that the predicates are in a consistent order. The precise
-    // ordering doesn't actually matter, but it's important that
-    // a given set of predicates always appears in the same order -
-    // both for visual consistency between 'rustdoc' runs, and to
-    // make writing tests much easier
+    /// Ensure that the predicates are in a consistent order. The precise
+    /// ordering doesn't actually matter, but it's important that
+    /// a given set of predicates always appears in the same order -
+    /// both for visual consistency between 'rustdoc' runs, and to
+    /// make writing tests much easier
     #[inline]
     fn sort_where_predicates(&self, mut predicates: &mut Vec<WherePredicate>) {
         // We should never have identical bounds - and if we do,
@@ -677,11 +645,11 @@ fn sort_where_predicates(&self, mut predicates: &mut Vec<WherePredicate>) {
         self.unstable_debug_sort(&mut predicates);
     }
 
-    // Ensure that the bounds are in a consistent order. The precise
-    // ordering doesn't actually matter, but it's important that
-    // a given set of bounds always appears in the same order -
-    // both for visual consistency between 'rustdoc' runs, and to
-    // make writing tests much easier
+    /// Ensure that the bounds are in a consistent order. The precise
+    /// ordering doesn't actually matter, but it's important that
+    /// a given set of bounds always appears in the same order -
+    /// both for visual consistency between 'rustdoc' runs, and to
+    /// make writing tests much easier
     #[inline]
     fn sort_where_bounds(&self, mut bounds: &mut Vec<GenericBound>) {
         // We should never have identical bounds - and if we do,
@@ -690,47 +658,43 @@ fn sort_where_bounds(&self, mut bounds: &mut Vec<GenericBound>) {
         self.unstable_debug_sort(&mut bounds);
     }
 
-    // This might look horrendously hacky, but it's actually not that bad.
-    //
-    // For performance reasons, we use several different FxHashMaps
-    // in the process of computing the final set of where predicates.
-    // However, the iteration order of a HashMap is completely unspecified.
-    // In fact, the iteration of an FxHashMap can even vary between platforms,
-    // since FxHasher has different behavior for 32-bit and 64-bit platforms.
-    //
-    // Obviously, it's extremely undesirable for documentation rendering
-    // to be dependent on the platform it's run on. Apart from being confusing
-    // to end users, it makes writing tests much more difficult, as predicates
-    // can appear in any order in the final result.
-    //
-    // To solve this problem, we sort WherePredicates and GenericBounds
-    // by their Debug string. The thing to keep in mind is that we don't really
-    // care what the final order is - we're synthesizing an impl or bound
-    // ourselves, so any order can be considered equally valid. By sorting the
-    // predicates and bounds, however, we ensure that for a given codebase, all
-    // auto-trait impls always render in exactly the same way.
-    //
-    // Using the Debug implementation for sorting prevents us from needing to
-    // write quite a bit of almost entirely useless code (e.g., how should two
-    // Types be sorted relative to each other). It also allows us to solve the
-    // problem for both WherePredicates and GenericBounds at the same time. This
-    // approach is probably somewhat slower, but the small number of items
-    // involved (impls rarely have more than a few bounds) means that it
-    // shouldn't matter in practice.
+    /// This might look horrendously hacky, but it's actually not that bad.
+    ///
+    /// For performance reasons, we use several different FxHashMaps
+    /// in the process of computing the final set of where predicates.
+    /// However, the iteration order of a HashMap is completely unspecified.
+    /// In fact, the iteration of an FxHashMap can even vary between platforms,
+    /// since FxHasher has different behavior for 32-bit and 64-bit platforms.
+    ///
+    /// Obviously, it's extremely undesirable for documentation rendering
+    /// to be dependent on the platform it's run on. Apart from being confusing
+    /// to end users, it makes writing tests much more difficult, as predicates
+    /// can appear in any order in the final result.
+    ///
+    /// To solve this problem, we sort WherePredicates and GenericBounds
+    /// by their Debug string. The thing to keep in mind is that we don't really
+    /// care what the final order is - we're synthesizing an impl or bound
+    /// ourselves, so any order can be considered equally valid. By sorting the
+    /// predicates and bounds, however, we ensure that for a given codebase, all
+    /// auto-trait impls always render in exactly the same way.
+    ///
+    /// Using the Debug implementation for sorting prevents us from needing to
+    /// write quite a bit of almost entirely useless code (e.g., how should two
+    /// Types be sorted relative to each other). It also allows us to solve the
+    /// problem for both WherePredicates and GenericBounds at the same time. This
+    /// approach is probably somewhat slower, but the small number of items
+    /// involved (impls rarely have more than a few bounds) means that it
+    /// shouldn't matter in practice.
     fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
         vec.sort_by_cached_key(|x| format!("{:?}", x))
     }
 
-    fn is_fn_ty(&self, ty: &Type) -> bool {
+    fn is_fn_trait(&self, path: &Path) -> bool {
         let tcx = self.cx.tcx;
-        match ty {
-            &Type::ResolvedPath { did, .. } => {
-                did == tcx.require_lang_item(LangItem::Fn, None)
-                    || did == tcx.require_lang_item(LangItem::FnMut, None)
-                    || did == tcx.require_lang_item(LangItem::FnOnce, None)
-            }
-            _ => false,
-        }
+        let did = path.def_id();
+        did == tcx.require_lang_item(LangItem::Fn, None)
+            || did == tcx.require_lang_item(LangItem::FnMut, None)
+            || did == tcx.require_lang_item(LangItem::FnOnce, None)
     }
 }
 
@@ -741,7 +705,7 @@ fn region_name(region: Region<'_>) -> Option<Symbol> {
     }
 }
 
-// Replaces all ReVars in a type with ty::Region's, using the provided map
+/// Replaces all [`ty::RegionVid`]s in a type with [`ty::Region`]s, using the provided map.
 struct RegionReplacer<'a, 'tcx> {
     vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
     tcx: TyCtxt<'tcx>,
index c2c1d369d6e8af8483eb83142bf9c6b4373a6b1f..843dda324da7fb75842b6ca3457f17f1b69bdcdc 100644 (file)
@@ -78,7 +78,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             );
                             match infcx.evaluate_obligation(&obligation) {
                                 Ok(eval_result) if eval_result.may_apply() => {}
-                                Err(traits::OverflowError::Cannonical) => {}
+                                Err(traits::OverflowError::Canonical) => {}
                                 Err(traits::OverflowError::ErrorReporting) => {}
                                 _ => {
                                     return false;
@@ -115,7 +115,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             .clean(self.cx),
                         // FIXME(eddyb) compute both `trait_` and `for_` from
                         // the post-inference `trait_ref`, as it's more accurate.
-                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
+                        trait_: Some(trait_ref.clean(self.cx)),
                         for_: ty.clean(self.cx),
                         items: self
                             .cx
index b463c1dc7146b6d5f9b6f98f915b6bc0a7d229cb..e11b802a09a3b9d3961083494b9705b99f3535b7 100644 (file)
@@ -446,20 +446,26 @@ fn merge_attrs(
         ),
     };
     let polarity = tcx.impl_polarity(did);
-    let trait_ = associated_trait.clean(cx).map(|bound| match bound {
-        clean::GenericBound::TraitBound(polyt, _) => polyt.trait_,
-        clean::GenericBound::Outlives(..) => unreachable!(),
-    });
-    if trait_.def_id() == tcx.lang_items().deref_trait() {
+    let trait_ = associated_trait.clean(cx);
+    if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
 
     // Return if the trait itself or any types of the generic parameters are doc(hidden).
-    let mut stack: Vec<&Type> = trait_.iter().collect();
-    stack.push(&for_);
+    let mut stack: Vec<&Type> = vec![&for_];
+
+    if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
+        if tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
+            return;
+        }
+    }
+    if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
+        stack.extend(generics);
+    }
+
     while let Some(ty) = stack.pop() {
         if let Some(did) = ty.def_id() {
-            if cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
+            if tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
                 return;
             }
         }
@@ -468,14 +474,14 @@ fn merge_attrs(
         }
     }
 
-    if let Some(trait_did) = trait_.def_id() {
-        record_extern_trait(cx, trait_did);
+    if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
+        record_extern_trait(cx, did);
     }
 
     let (merged_attrs, cfg) = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
     trace!("merged_attrs={:?}", merged_attrs);
 
-    trace!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
+    trace!("build_impl: impl {:?} for {:?}", trait_.as_ref().map(|t| t.def_id()), for_.def_id());
     ret.push(clean::Item::from_def_id_and_attrs_and_parts(
         did,
         None,
@@ -526,7 +532,6 @@ fn build_module(
                         item.ident.name,
                         clean::ImportSource {
                             path: clean::Path {
-                                global: false,
                                 res,
                                 segments: vec![clean::PathSegment {
                                     name: prim_ty.as_sym(),
@@ -621,11 +626,10 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
                 ref mut bounds,
                 ..
             } if *s == kw::SelfUpper => {
-                bounds.retain(|bound| match *bound {
-                    clean::GenericBound::TraitBound(
-                        clean::PolyTrait { trait_: clean::ResolvedPath { did, .. }, .. },
-                        _,
-                    ) => did != trait_did,
+                bounds.retain(|bound| match bound {
+                    clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
+                        trait_.def_id() != trait_did
+                    }
                     _ => true,
                 });
             }
@@ -633,18 +637,12 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
         }
     }
 
-    g.where_predicates.retain(|pred| match *pred {
+    g.where_predicates.retain(|pred| match pred {
         clean::WherePredicate::BoundPredicate {
-            ty:
-                clean::QPath {
-                    self_type: box clean::Generic(ref s),
-                    trait_: box clean::ResolvedPath { did, .. },
-                    name: ref _name,
-                    ..
-                },
-            ref bounds,
+            ty: clean::QPath { self_type: box clean::Generic(ref s), trait_, name: _, .. },
+            bounds,
             ..
-        } => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
+        } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
         _ => true,
     });
     g
index 969d15dd6a160e10a7a1b521a85eefffc4f37728..9d102d6878370dea44d839c83b57e15d9feeafde 100644 (file)
@@ -152,8 +152,8 @@ fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
     }
 }
 
-impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
+impl Clean<Path> for (ty::TraitRef<'_>, &[TypeBinding]) {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
         let (trait_ref, bounds) = *self;
         let kind = cx.tcx.def_kind(trait_ref.def_id).into();
         if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
@@ -168,16 +168,13 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
 
-        ResolvedPath { path, did: trait_ref.def_id }
+        path
     }
 }
 
-impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
-        GenericBound::TraitBound(
-            PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] },
-            hir::TraitBoundModifier::None,
-        )
+impl Clean<Path> for ty::TraitRef<'tcx> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
+        (*self, &[][..]).clean(cx)
     }
 }
 
@@ -384,16 +381,13 @@ fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
 impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         let lifted = self.lift_to_tcx(cx.tcx).unwrap();
-        let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) {
-            GenericBound::TraitBound(t, _) => t.trait_,
-            GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"),
-        };
+        let trait_ = lifted.trait_ref(cx.tcx).clean(cx);
         let self_type = self.self_ty().clean(cx);
         Type::QPath {
             name: cx.tcx.associated_item(self.item_def_id).ident.name,
             self_def_id: self_type.def_id(),
             self_type: box self_type,
-            trait_: box trait_,
+            trait_,
         }
     }
 }
@@ -896,10 +890,11 @@ fn clean(&self, _: &mut DocContext<'_>) -> bool {
     }
 }
 
-impl Clean<Type> for hir::TraitRef<'_> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
+impl Clean<Path> for hir::TraitRef<'_> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
         let path = self.path.clean(cx);
-        resolve_type(cx, path)
+        register_res(cx, path.res);
+        path
     }
 }
 
@@ -1105,9 +1100,8 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
                             if *name != my_name {
                                 return None;
                             }
-                            match **trait_ {
-                                ResolvedPath { did, .. } if did == self.container.id() => {}
-                                _ => return None,
+                            if trait_.def_id() != self.container.id() {
+                                return None;
                             }
                             match **self_type {
                                 Generic(ref s) if *s == kw::SelfUpper => {}
@@ -1273,19 +1267,18 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 return normalized_value.clean(cx);
             }
 
-            let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
-            let trait_segments = &segments[..segments.len() - 1];
+            let trait_segments = &p.segments[..p.segments.len() - 1];
             let trait_def = cx.tcx.associated_item(p.res.def_id()).container.id();
-            let trait_path = self::Path {
-                global: p.is_global(),
+            let trait_ = self::Path {
                 res: Res::Def(DefKind::Trait, trait_def),
                 segments: trait_segments.clean(cx),
             };
+            register_res(cx, trait_.res);
             Type::QPath {
                 name: p.segments.last().expect("segments were empty").ident.name,
                 self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)),
                 self_type: box qself.clean(cx),
-                trait_: box resolve_type(cx, trait_path),
+                trait_,
             }
         }
         hir::QPath::TypeRelative(ref qself, ref segment) => {
@@ -1296,12 +1289,13 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 ty::Error(_) => return Type::Infer,
                 _ => bug!("clean: expected associated type, found `{:?}`", ty),
             };
-            let trait_path = hir::Path { span, res, segments: &[] }.clean(cx);
+            let trait_ = hir::Path { span, res, segments: &[] }.clean(cx);
+            register_res(cx, trait_.res);
             Type::QPath {
                 name: segment.ident.name,
                 self_def_id: res.opt_def_id(),
                 self_type: box qself.clean(cx),
-                trait_: box resolve_type(cx, trait_path),
+                trait_,
             }
         }
         hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
@@ -1470,10 +1464,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                     let empty = cx.tcx.intern_substs(&[]);
                     let path = external_path(cx, did, false, vec![], empty);
                     inline::record_extern_fqn(cx, did, ItemType::Trait);
-                    let bound = PolyTrait {
-                        trait_: ResolvedPath { path, did },
-                        generic_params: Vec::new(),
-                    };
+                    let bound = PolyTrait { trait_: path, generic_params: Vec::new() };
                     bounds.push(bound);
                 }
 
@@ -1486,10 +1477,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 }
 
                 let path = external_path(cx, did, false, bindings, substs);
-                bounds.insert(
-                    0,
-                    PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
-                );
+                bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() });
 
                 DynTrait(bounds, lifetime)
             }
@@ -1728,11 +1716,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
 
 impl Clean<Path> for hir::Path<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Path {
-        Path {
-            global: self.is_global(),
-            res: self.res,
-            segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
-        }
+        Path { res: self.res, segments: self.segments.clean(cx) }
     }
 }
 
@@ -1898,7 +1882,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
 
     // If this impl block is an implementation of the Deref trait, then we
     // need to try inlining the target's inherent impl blocks as well.
-    if trait_.def_id() == tcx.lang_items().deref_trait() {
+    if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         build_deref_target_impls(cx, &items, &mut ret);
     }
 
@@ -1907,7 +1891,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
         DefKind::TyAlias => Some(tcx.type_of(did).clean(cx)),
         _ => None,
     });
-    let mut make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| {
+    let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
         let kind = ImplItem(Impl {
             span: types::rustc_span(tcx.hir().local_def_id(hir_id).to_def_id(), tcx),
             unsafety: impl_.unsafety,
index 257af6ab910163d9bd91b7d2cfa053870c5b6d52..4c81e75e8d6304b49b8055d90f75fcb0a7c98c4a 100644 (file)
             clean::GenericBound::TraitBound(ref mut tr, _) => tr,
             clean::GenericBound::Outlives(..) => return false,
         };
-        let (did, path) = match trait_ref.trait_ {
-            clean::ResolvedPath { did, ref mut path, .. } => (did, path),
-            _ => return false,
-        };
         // If this QPath's trait `trait_did` is the same as, or a supertrait
         // of, the bound's trait `did` then we can keep going, otherwise
         // this is just a plain old equality bound.
-        if !trait_is_same_or_supertrait(cx, did, trait_did) {
+        if !trait_is_same_or_supertrait(cx, trait_ref.trait_.def_id(), trait_did) {
             return false;
         }
-        let last = path.segments.last_mut().expect("segments were empty");
+        let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
         match last.args {
             PP::AngleBracketed { ref mut bindings, .. } => {
                 bindings.push(clean::TypeBinding {
index 5b722175f988cd9928c051c43878d9d176a116ad..d4cea8b4a9d289cb757b8a699555a69835c1562a 100644 (file)
@@ -120,8 +120,7 @@ fn from(id: DefId) -> Self {
     crate module: Item,
     crate externs: Vec<ExternalCrate>,
     crate primitives: ThinVec<(DefId, PrimitiveType)>,
-    // These are later on moved into `CACHEKEY`, leaving the map empty.
-    // Only here so that they can be filtered through the rustdoc passes.
+    /// Only here so that they can be filtered through the rustdoc passes.
     crate external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>,
     crate collapsed: bool,
 }
@@ -1147,7 +1146,7 @@ impl GenericBound {
         let path = external_path(cx, did, false, vec![], empty);
         inline::record_extern_fqn(cx, did, ItemType::Trait);
         GenericBound::TraitBound(
-            PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
+            PolyTrait { trait_: path, generic_params: Vec::new() },
             hir::TraitBoundModifier::Maybe,
         )
     }
@@ -1155,7 +1154,7 @@ impl GenericBound {
     crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
         use rustc_hir::TraitBoundModifier as TBM;
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
-            if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
+            if Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() {
                 return true;
             }
         }
@@ -1169,7 +1168,7 @@ impl GenericBound {
         None
     }
 
-    crate fn get_trait_type(&self) -> Option<Type> {
+    crate fn get_trait_path(&self) -> Option<Path> {
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             Some(trait_.clone())
         } else {
@@ -1401,53 +1400,53 @@ fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
 /// A trait reference, which may have higher ranked lifetimes.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct PolyTrait {
-    crate trait_: Type,
+    crate trait_: Path,
     crate generic_params: Vec<GenericParamDef>,
 }
 
-/// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
-/// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
-/// importantly, it does not preserve mutability or boxes.
+/// Rustdoc's representation of types, mostly based on the [`hir::Ty`].
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate enum Type {
-    /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
-    ResolvedPath {
-        path: Path,
-        did: DefId,
-    },
-    /// `dyn for<'a> Trait<'a> + Send + 'static`
+    /// A named type, which could be a trait.
+    ///
+    /// This is mostly Rustdoc's version of [`hir::Path`]. It has to be different because Rustdoc's [`PathSegment`] can contain cleaned generics.
+    ResolvedPath { path: Path, did: DefId },
+    /// A `dyn Trait` object: `dyn for<'a> Trait<'a> + Send + 'static`
     DynTrait(Vec<PolyTrait>, Option<Lifetime>),
-    /// For parameterized types, so the consumer of the JSON don't go
-    /// looking for types which don't exist anywhere.
+    /// A type parameter.
     Generic(Symbol),
-    /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
-    /// arrays, slices, and tuples.
+    /// A primitive (aka, builtin) type.
     Primitive(PrimitiveType),
-    /// `extern "ABI" fn`
+    /// A function pointer: `extern "ABI" fn(...) -> ...`
     BareFunction(Box<BareFunctionDecl>),
+    /// A tuple type: `(i32, &str)`.
     Tuple(Vec<Type>),
+    /// A slice type (does *not* include the `&`): `[i32]`
     Slice(Box<Type>),
-    /// The `String` field is about the size or the constant representing the array's length.
+    /// An array type.
+    ///
+    /// The `String` field is a stringified version of the array's length parameter.
     Array(Box<Type>, String),
+    /// A raw pointer type: `*const i32`, `*mut i32`
     RawPointer(Mutability, Box<Type>),
-    BorrowedRef {
-        lifetime: Option<Lifetime>,
-        mutability: Mutability,
-        type_: Box<Type>,
-    },
+    /// A reference type: `&i32`, `&'a mut Foo`
+    BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> },
 
-    // `<Type as Trait>::Name`
+    /// A qualified path to an associated item: `<Type as Trait>::Name`
     QPath {
         name: Symbol,
         self_type: Box<Type>,
+        /// FIXME: This is a hack that should be removed; see [this discussion][1].
+        ///
+        /// [1]: https://github.com/rust-lang/rust/pull/85479#discussion_r635729093
         self_def_id: Option<DefId>,
-        trait_: Box<Type>,
+        trait_: Path,
     },
 
-    // `_`
+    /// A type that is inferred: `_`
     Infer,
 
-    // `impl TraitA + TraitB + ...`
+    /// An `impl Trait`: `impl TraitA + TraitB + ...`
     ImplTrait(Vec<GenericBound>),
 }
 
@@ -1514,34 +1513,8 @@ impl Type {
     }
 
     crate fn generics(&self) -> Option<Vec<&Type>> {
-        match *self {
-            ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
-                if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
-                    Some(
-                        args.iter()
-                            .filter_map(|arg| match arg {
-                                GenericArg::Type(ty) => Some(ty),
-                                _ => None,
-                            })
-                            .collect(),
-                    )
-                } else {
-                    None
-                }
-            }),
-            _ => None,
-        }
-    }
-
-    crate fn bindings(&self) -> Option<&[TypeBinding]> {
-        match *self {
-            ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
-                if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
-                    Some(&**bindings)
-                } else {
-                    None
-                }
-            }),
+        match self {
+            ResolvedPath { path, .. } => path.generics(),
             _ => None,
         }
     }
@@ -1559,17 +1532,13 @@ impl Type {
             QPath { self_type, trait_, name, .. } => (self_type, trait_, name),
             _ => return None,
         };
-        let trait_did = match **trait_ {
-            ResolvedPath { did, .. } => did,
-            _ => return None,
-        };
-        Some((&self_, trait_did, *name))
+        Some((&self_, trait_.def_id(), *name))
     }
 
     fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
         let t: PrimitiveType = match *self {
             ResolvedPath { did, .. } => return Some(did),
-            DynTrait(ref bounds, _) => return bounds[0].trait_.inner_def_id(cache),
+            DynTrait(ref bounds, _) => return Some(bounds[0].trait_.def_id()),
             Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
             BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
             BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
@@ -1601,8 +1570,12 @@ fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
     }
 }
 
-/// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't
-/// paths, like `Unit`.
+/// A primitive (aka, builtin) type.
+///
+/// This represents things like `i32`, `str`, etc.
+///
+/// N.B. This has to be different from [`hir::PrimTy`] because it also includes types that aren't
+/// paths, like [`Self::Unit`].
 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
 crate enum PrimitiveType {
     Isize,
@@ -2000,12 +1973,15 @@ impl Span {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct Path {
-    crate global: bool,
     crate res: Res,
     crate segments: Vec<PathSegment>,
 }
 
 impl Path {
+    crate fn def_id(&self) -> DefId {
+        self.res.def_id()
+    }
+
     crate fn last(&self) -> Symbol {
         self.segments.last().expect("segments were empty").name
     }
@@ -2015,8 +1991,11 @@ impl Path {
     }
 
     crate fn whole_name(&self) -> String {
-        String::from(if self.global { "::" } else { "" })
-            + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
+        self.segments
+            .iter()
+            .map(|s| if s.name == kw::PathRoot { String::new() } else { s.name.to_string() })
+            .intersperse("::".into())
+            .collect()
     }
 
     /// Checks if this is a `T::Name` path for an associated type.
@@ -2028,6 +2007,33 @@ impl Path {
             _ => false,
         }
     }
+
+    crate fn generics(&self) -> Option<Vec<&Type>> {
+        self.segments.last().and_then(|seg| {
+            if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
+                Some(
+                    args.iter()
+                        .filter_map(|arg| match arg {
+                            GenericArg::Type(ty) => Some(ty),
+                            _ => None,
+                        })
+                        .collect(),
+                )
+            } else {
+                None
+            }
+        })
+    }
+
+    crate fn bindings(&self) -> Option<&[TypeBinding]> {
+        self.segments.last().and_then(|seg| {
+            if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
+                Some(&**bindings)
+            } else {
+                None
+            }
+        })
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -2171,7 +2177,7 @@ impl Constant {
     crate span: Span,
     crate unsafety: hir::Unsafety,
     crate generics: Generics,
-    crate trait_: Option<Type>,
+    crate trait_: Option<Path>,
     crate for_: Type,
     crate items: Vec<Item>,
     crate negative_polarity: bool,
@@ -2182,7 +2188,8 @@ impl Constant {
 impl Impl {
     crate fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet<Symbol> {
         self.trait_
-            .def_id()
+            .as_ref()
+            .map(|t| t.def_id())
             .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
             .unwrap_or_default()
     }
index 2a05787e40cf98abb6fb7917a1fffbad22436a85..de43daff6f0d7c8416420d53ee86103a2a4f892a 100644 (file)
@@ -2,7 +2,7 @@
 use crate::clean::blanket_impl::BlanketImplFinder;
 use crate::clean::{
     inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item,
-    ItemKind, Lifetime, Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type,
+    ItemKind, Lifetime, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Type,
     TypeBinding, Visibility,
 };
 use crate::core::DocContext;
@@ -147,7 +147,6 @@ pub(super) fn external_path(
     let def_kind = cx.tcx.def_kind(did);
     let name = cx.tcx.item_name(did);
     Path {
-        global: false,
         res: Res::Def(def_kind, did),
         segments: vec![PathSegment {
             name,
@@ -156,39 +155,8 @@ pub(super) fn external_path(
     }
 }
 
-crate fn strip_type(ty: Type) -> Type {
-    match ty {
-        Type::ResolvedPath { path, did } => Type::ResolvedPath { path: strip_path(&path), did },
-        Type::DynTrait(mut bounds, lt) => {
-            let first = bounds.remove(0);
-            let stripped_trait = strip_type(first.trait_);
-
-            bounds.insert(
-                0,
-                PolyTrait { trait_: stripped_trait, generic_params: first.generic_params },
-            );
-            Type::DynTrait(bounds, lt)
-        }
-        Type::Tuple(inner_tys) => {
-            Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect())
-        }
-        Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))),
-        Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s),
-        Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))),
-        Type::BorrowedRef { lifetime, mutability, type_ } => {
-            Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) }
-        }
-        Type::QPath { name, self_type, trait_, self_def_id } => Type::QPath {
-            name,
-            self_def_id,
-            self_type: Box::new(strip_type(*self_type)),
-            trait_: Box::new(strip_type(*trait_)),
-        },
-        _ => ty,
-    }
-}
-
-crate fn strip_path(path: &Path) -> Path {
+/// Remove the generic arguments from a path.
+crate fn strip_path_generics(path: Path) -> Path {
     let segments = path
         .segments
         .iter()
@@ -198,7 +166,7 @@ pub(super) fn external_path(
         })
         .collect();
 
-    Path { global: path.global, res: path.res, segments }
+    Path { res: path.res, segments }
 }
 
 crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
index cc9e081add199baac86fa3d2c85a43eda1d425a7..8b883ffaaf095cb4419f12f96bab71f6807b4002 100644 (file)
@@ -203,7 +203,9 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         // masked crate then remove it completely.
         if let clean::ImplItem(ref i) = *item.kind {
             if self.cache.masked_crates.contains(&item.def_id.krate())
-                || i.trait_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate))
+                || i.trait_
+                    .as_ref()
+                    .map_or(false, |t| self.cache.masked_crates.contains(&t.def_id().krate))
                 || i.for_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate))
             {
                 return None;
@@ -223,11 +225,11 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
 
         // Collect all the implementors of traits.
         if let clean::ImplItem(ref i) = *item.kind {
-            if let Some(did) = i.trait_.def_id() {
+            if let Some(trait_) = &i.trait_ {
                 if i.blanket_impl.is_none() {
                     self.cache
                         .implementors
-                        .entry(did)
+                        .entry(trait_.def_id())
                         .or_default()
                         .push(Impl { impl_item: item.clone() });
                 }
@@ -402,12 +404,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                     }
                     clean::DynTrait(ref bounds, _)
                     | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => {
-                        if let Some(did) = bounds[0].trait_.def_id() {
-                            self.cache.parent_stack.push(did);
-                            true
-                        } else {
-                            false
-                        }
+                        self.cache.parent_stack.push(bounds[0].trait_.def_id());
+                        true
                     }
                     ref t => {
                         let prim_did = t
@@ -441,9 +439,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                 }
                 clean::DynTrait(ref bounds, _)
                 | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => {
-                    if let Some(did) = bounds[0].trait_.def_id() {
-                        dids.insert(did);
-                    }
+                    dids.insert(bounds[0].trait_.def_id());
                 }
                 ref t => {
                     let did = t
index 6060b0560cf3c4669c3b7424684133389f48c412..4f0c5a9edee7185581c71bd1846d0151105f015a 100644 (file)
@@ -7,14 +7,12 @@
 crate use renderer::{run_format, FormatRenderer};
 
 use crate::clean;
-use crate::clean::types::GetDefId;
-use crate::formats::cache::Cache;
 
 /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
 /// impl.
 crate enum AssocItemRender<'a> {
     All,
-    DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool },
+    DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
 }
 
 /// For different handling of associated items from the Deref target of a type rather than the type
@@ -40,10 +38,6 @@ impl Impl {
     }
 
     crate fn trait_did(&self) -> Option<DefId> {
-        self.inner_impl().trait_.def_id()
-    }
-
-    crate fn trait_did_full(&self, cache: &Cache) -> Option<DefId> {
-        self.inner_impl().trait_.def_id_full(cache)
+        self.inner_impl().trait_.as_ref().map(|t| t.def_id())
     }
 }
index bcd78b2adc08513145b2a0194dc920613cc3d69c..f2751947c7eb95a6db9b8d8154e11e7e17228f84 100644 (file)
@@ -18,9 +18,7 @@
 use rustc_span::def_id::CRATE_DEF_INDEX;
 use rustc_target::spec::abi::Abi;
 
-use crate::clean::{
-    self, utils::find_nearest_parent_module, ExternalCrate, GetDefId, ItemId, PrimitiveType,
-};
+use crate::clean::{self, utils::find_nearest_parent_module, ExternalCrate, ItemId, PrimitiveType};
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::render::cache::ExternalLocation;
@@ -270,7 +268,7 @@ impl clean::Generics {
                         0 => String::new(),
                         _ if f.alternate() => {
                             format!(
-                                "for<{:#}> ",
+                                "for&lt;{:#}&gt; ",
                                 comma_sep(bound_params.iter().map(|lt| lt.print()))
                             )
                         }
@@ -914,15 +912,10 @@ fn fmt_type<'cx>(
             }
         }
         clean::QPath { ref name, ref self_type, ref trait_, ref self_def_id } => {
-            let should_show_cast = match *trait_ {
-                box clean::ResolvedPath { ref path, .. } => {
-                    !path.segments.is_empty()
-                        && self_def_id
-                            .zip(trait_.def_id())
-                            .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_)
-                }
-                _ => true,
-            };
+            let should_show_cast = !trait_.segments.is_empty()
+                && self_def_id
+                    .zip(Some(trait_.def_id()))
+                    .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_);
             if f.alternate() {
                 if should_show_cast {
                     write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
@@ -936,36 +929,31 @@ fn fmt_type<'cx>(
                     write!(f, "{}::", self_type.print(cx))?
                 }
             };
-            match *trait_ {
-                // It's pretty unsightly to look at `<A as B>::C` in output, and
-                // we've got hyperlinking on our side, so try to avoid longer
-                // notation as much as possible by making `C` a hyperlink to trait
-                // `B` to disambiguate.
-                //
-                // FIXME: this is still a lossy conversion and there should probably
-                //        be a better way of representing this in general? Most of
-                //        the ugliness comes from inlining across crates where
-                //        everything comes in as a fully resolved QPath (hard to
-                //        look at).
-                box clean::ResolvedPath { did, .. } => {
-                    match href(did, cx) {
-                        Ok((ref url, _, ref path)) if !f.alternate() => {
-                            write!(
-                                f,
-                                "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
+            // It's pretty unsightly to look at `<A as B>::C` in output, and
+            // we've got hyperlinking on our side, so try to avoid longer
+            // notation as much as possible by making `C` a hyperlink to trait
+            // `B` to disambiguate.
+            //
+            // FIXME: this is still a lossy conversion and there should probably
+            //        be a better way of representing this in general? Most of
+            //        the ugliness comes from inlining across crates where
+            //        everything comes in as a fully resolved QPath (hard to
+            //        look at).
+            match href(trait_.def_id(), cx) {
+                Ok((ref url, _, ref path)) if !f.alternate() => {
+                    write!(
+                        f,
+                        "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
                                     title=\"type {path}::{name}\">{name}</a>",
-                                url = url,
-                                shortty = ItemType::AssocType,
-                                name = name,
-                                path = path.join("::")
-                            )?;
-                        }
-                        _ => write!(f, "{}", name)?,
-                    }
-                    Ok(())
+                        url = url,
+                        shortty = ItemType::AssocType,
+                        name = name,
+                        path = path.join("::")
+                    )?;
                 }
-                _ => write!(f, "{}", name),
+                _ => write!(f, "{}", name)?,
             }
+            Ok(())
         }
     }
 }
@@ -979,6 +967,15 @@ impl clean::Type {
     }
 }
 
+impl clean::Path {
+    crate fn print<'b, 'a: 'b, 'tcx: 'a>(
+        &'a self,
+        cx: &'a Context<'tcx>,
+    ) -> impl fmt::Display + 'b + Captures<'tcx> {
+        display_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
+    }
+}
+
 impl clean::Impl {
     crate fn print<'a, 'tcx: 'a>(
         &'a self,
@@ -1059,7 +1056,11 @@ fn print_hrtb_with_space<'a, 'tcx: 'a>(
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
         display_fn(move |f| {
             if !self.generic_params.is_empty() {
-                write!(f, "for<{}> ", comma_sep(self.generic_params.iter().map(|g| g.print(cx))))
+                write!(
+                    f,
+                    "for&lt;{}&gt; ",
+                    comma_sep(self.generic_params.iter().map(|g| g.print(cx)))
+                )
             } else {
                 Ok(())
             }
index edd1d8b98fc64b276eabe71eb00c871668c7d407..9c05c80d55dfea35a5b8c820657ec6950d6a1394 100644 (file)
@@ -226,16 +226,13 @@ fn get_index_type(clean_type: &clean::Type) -> RenderType {
 fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option<Symbol> {
     match *clean_type {
         clean::ResolvedPath { ref path, .. } => {
-            let segments = &path.segments;
-            let path_segment = segments.iter().last().unwrap_or_else(|| {
-                panic!(
-                "get_index_type_name(clean_type: {:?}, accept_generic: {:?}) had length zero path",
-                clean_type, accept_generic
-            )
-            });
+            let path_segment = path.segments.last().unwrap();
             Some(path_segment.name)
         }
-        clean::DynTrait(ref bounds, _) => get_index_type_name(&bounds[0].trait_, accept_generic),
+        clean::DynTrait(ref bounds, _) => {
+            let path = &bounds[0].trait_;
+            Some(path.segments.last().unwrap().name)
+        }
         clean::Generic(s) if accept_generic => Some(s),
         clean::Primitive(ref p) => Some(p.as_sym()),
         clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic),
@@ -324,7 +321,8 @@ fn insert(res: &mut FxHashSet<(Type, ItemType)>, tcx: TyCtxt<'_>, ty: Type) -> u
         }
         if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
             for bound in bound.get_bounds().unwrap_or(&[]) {
-                if let Some(ty) = bound.get_trait_type() {
+                if let Some(path) = bound.get_trait_path() {
+                    let ty = Type::ResolvedPath { did: path.def_id(), path };
                     let adds = get_real_types(generics, &ty, tcx, recurse + 1, res);
                     nb_added += adds;
                     if adds == 0 && !ty.is_full_generic() {
index b99d2fe5aa0d17584ca78cbba5e80ddf75f129d2..011d3cfcf72d7a1171356fdaff2c57d5a84f6ec0 100644 (file)
@@ -1,6 +1,5 @@
 use std::cell::RefCell;
 use std::collections::BTreeMap;
-use std::error::Error as StdError;
 use std::io;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
@@ -16,6 +15,7 @@
 
 use super::cache::{build_index, ExternalLocation};
 use super::print_item::{full_path, item_path, print_item};
+use super::templates;
 use super::write_shared::write_shared;
 use super::{
     collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
@@ -33,7 +33,6 @@
 use crate::html::escape::Escape;
 use crate::html::format::Buffer;
 use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
-use crate::html::static_files::PAGE;
 use crate::html::{layout, sources};
 
 /// Major driving force in all rustdoc rendering. This contains information
@@ -225,7 +224,7 @@ fn render_item(&self, it: &clean::Item, is_module: bool) -> String {
                 &self.shared.layout,
                 &page,
                 |buf: &mut _| print_sidebar(self, it, buf),
-                |buf: &mut _| print_item(self, it, buf, &page),
+                |buf: &mut _| print_item(self, &self.shared.templates, it, buf, &page),
                 &self.shared.style_files,
             )
         } else {
@@ -416,12 +415,7 @@ fn init(
         };
         let mut issue_tracker_base_url = None;
         let mut include_sources = true;
-
-        let mut templates = tera::Tera::default();
-        templates.add_raw_template("page.html", PAGE).map_err(|e| Error {
-            file: "page.html".into(),
-            error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
-        })?;
+        let templates = templates::load()?;
 
         // Crawl the crate attributes looking for attributes which control how we're
         // going to emit HTML
index 11682afdf899ba0580be428629ebf1cb6a655c7d..dc5aec3b084f56a3b062ae037f7acee57922ef8b 100644 (file)
@@ -31,6 +31,7 @@
 mod context;
 mod print_item;
 mod span_map;
+mod templates;
 mod write_shared;
 
 crate use context::*;
@@ -716,18 +717,12 @@ fn short_item_info(
 
 // Render the list of items inside one of the sections "Trait Implementations",
 // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
-fn render_impls(
-    cx: &Context<'_>,
-    w: &mut Buffer,
-    traits: &[&&Impl],
-    containing_item: &clean::Item,
-) {
-    let cache = cx.cache();
+fn render_impls(cx: &Context<'_>, w: &mut Buffer, impls: &[&&Impl], containing_item: &clean::Item) {
     let tcx = cx.tcx();
-    let mut impls = traits
+    let mut rendered_impls = impls
         .iter()
         .map(|i| {
-            let did = i.trait_did_full(cache).unwrap();
+            let did = i.trait_did().unwrap();
             let provided_trait_methods = i.inner_impl().provided_trait_methods(tcx);
             let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods);
             let mut buffer = if w.is_for_html() { Buffer::html() } else { Buffer::new() };
@@ -751,8 +746,8 @@ fn render_impls(
             buffer.into_inner()
         })
         .collect::<Vec<_>>();
-    impls.sort();
-    w.write_str(&impls.join(""));
+    rendered_impls.sort();
+    w.write_str(&rendered_impls.join(""));
 }
 
 fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) -> String {
@@ -1097,13 +1092,11 @@ fn render_assoc_items(
         return;
     }
     if !traits.is_empty() {
-        let deref_impl = traits.iter().find(|t| {
-            t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
-        });
+        let deref_impl =
+            traits.iter().find(|t| t.trait_did() == cx.tcx().lang_items().deref_trait());
         if let Some(impl_) = deref_impl {
-            let has_deref_mut = traits.iter().any(|t| {
-                t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_mut_trait()
-            });
+            let has_deref_mut =
+                traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait());
             render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
         }
         let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
@@ -1221,45 +1214,39 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
 
 fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
     let mut out = Buffer::html();
-    let mut trait_ = String::new();
 
     if let Some(did) = decl.output.def_id_full(cx.cache()) {
         if let Some(impls) = cx.cache().impls.get(&did) {
             for i in impls {
                 let impl_ = i.inner_impl();
-                if impl_.trait_.def_id().map_or(false, |d| {
-                    cx.cache().traits.get(&d).map(|t| t.is_notable).unwrap_or(false)
-                }) {
-                    if out.is_empty() {
-                        write!(
-                            &mut out,
-                            "<div class=\"notable\">Notable traits for {}</div>\
-                             <code class=\"content\">",
-                            impl_.for_.print(cx)
-                        );
-                        trait_.push_str(&impl_.for_.print(cx).to_string());
-                    }
+                if let Some(trait_) = &impl_.trait_ {
+                    let trait_did = trait_.def_id();
 
-                    //use the "where" class here to make it small
-                    write!(
-                        &mut out,
-                        "<span class=\"where fmt-newline\">{}</span>",
-                        impl_.print(false, cx)
-                    );
-                    let t_did = impl_.trait_.def_id_full(cx.cache()).unwrap();
-                    for it in &impl_.items {
-                        if let clean::TypedefItem(ref tydef, _) = *it.kind {
-                            out.push_str("<span class=\"where fmt-newline\">    ");
-                            assoc_type(
+                    if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable) {
+                        if out.is_empty() {
+                            write!(
                                 &mut out,
-                                it,
-                                &[],
-                                Some(&tydef.type_),
-                                AssocItemLink::GotoSource(t_did.into(), &FxHashSet::default()),
-                                "",
-                                cx,
+                                "<div class=\"notable\">Notable traits for {}</div>\
+                             <code class=\"content\">",
+                                impl_.for_.print(cx)
                             );
-                            out.push_str(";</span>");
+                        }
+
+                        //use the "where" class here to make it small
+                        write!(
+                            &mut out,
+                            "<span class=\"where fmt-newline\">{}</span>",
+                            impl_.print(false, cx)
+                        );
+                        for it in &impl_.items {
+                            if let clean::TypedefItem(ref tydef, _) = *it.kind {
+                                out.push_str("<span class=\"where fmt-newline\">    ");
+                                let empty_set = FxHashSet::default();
+                                let src_link =
+                                    AssocItemLink::GotoSource(trait_did.into(), &empty_set);
+                                assoc_type(&mut out, it, &[], Some(&tydef.type_), src_link, "", cx);
+                                out.push_str(";</span>");
+                            }
                         }
                     }
                 }
@@ -1302,7 +1289,7 @@ fn render_impl(
 ) {
     let cache = cx.cache();
     let traits = &cache.traits;
-    let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]);
+    let trait_ = i.trait_did().map(|did| &traits[&did]);
     let mut close_tags = String::new();
 
     // For trait implementations, the `interesting` output contains all methods that have doc
@@ -1532,7 +1519,7 @@ fn render_default_items(
             if i.items.iter().any(|m| m.name == n) {
                 continue;
             }
-            let did = i.trait_.as_ref().unwrap().def_id_full(cx.cache()).unwrap();
+            let did = i.trait_.as_ref().unwrap().def_id();
             let provided_methods = i.provided_trait_methods(cx.tcx());
             let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);
 
@@ -1917,9 +1904,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
         }
 
         if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
-            if let Some(impl_) = v.iter().filter(|i| i.inner_impl().trait_.is_some()).find(|i| {
-                i.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
-            }) {
+            if let Some(impl_) =
+                v.iter().find(|i| i.trait_did() == cx.tcx().lang_items().deref_trait())
+            {
                 sidebar_deref_methods(cx, out, impl_, v);
             }
 
@@ -2017,9 +2004,7 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
                 }
             }
         }
-        let deref_mut = v.iter().filter(|i| i.inner_impl().trait_.is_some()).any(|i| {
-            i.inner_impl().trait_.def_id_full(c) == cx.tcx().lang_items().deref_mut_trait()
-        });
+        let deref_mut = v.iter().any(|i| i.trait_did() == cx.tcx().lang_items().deref_mut_trait());
         let inner_impl = target
             .def_id_full(c)
             .or_else(|| {
@@ -2086,10 +2071,10 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
 
 fn get_id_for_impl_on_foreign_type(
     for_: &clean::Type,
-    trait_: &clean::Type,
+    trait_: &clean::Path,
     cx: &Context<'_>,
 ) -> String {
-    small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx),))
+    small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx)))
 }
 
 fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
@@ -2400,6 +2385,15 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
     let mut visited = FxHashSet::default();
     let mut work = VecDeque::new();
 
+    let mut process_path = |did: DefId| {
+        let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone());
+        let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern);
+
+        if let Some(path) = fqp {
+            out.push(path.join("::"));
+        }
+    };
+
     work.push_back(first_ty);
 
     while let Some(ty) = work.pop_front() {
@@ -2408,14 +2402,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
         }
 
         match ty {
-            clean::Type::ResolvedPath { did, .. } => {
-                let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone());
-                let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern);
-
-                if let Some(path) = fqp {
-                    out.push(path.join("::"));
-                }
-            }
+            clean::Type::ResolvedPath { did, .. } => process_path(did),
             clean::Type::Tuple(tys) => {
                 work.extend(tys.into_iter());
             }
@@ -2433,7 +2420,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
             }
             clean::Type::QPath { self_type, trait_, .. } => {
                 work.push_back(*self_type);
-                work.push_back(*trait_);
+                process_path(trait_.def_id());
             }
             _ => {}
         }
index cab3fca708b2e46654a8285cda7ea19ffda82382..4cfc57ac99588d5aa859424438111c0a6a8c44f3 100644 (file)
 use crate::html::layout::Page;
 use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
 
+use serde::Serialize;
+
 const ITEM_TABLE_OPEN: &'static str = "<div class=\"item-table\">";
 const ITEM_TABLE_CLOSE: &'static str = "</div>";
 const ITEM_TABLE_ROW_OPEN: &'static str = "<div class=\"item-row\">";
 const ITEM_TABLE_ROW_CLOSE: &'static str = "</div>";
 
-pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
+// A component in a `use` path, like `string` in std::string::ToString
+#[derive(Serialize)]
+struct PathComponent<'a> {
+    path: String,
+    name: &'a str,
+}
+
+#[derive(Serialize)]
+struct ItemVars<'a> {
+    page: &'a Page<'a>,
+    static_root_path: &'a str,
+    typ: &'a str,
+    name: &'a str,
+    item_type: &'a str,
+    path_components: Vec<PathComponent<'a>>,
+    stability_since_raw: &'a str,
+    src_href: Option<&'a str>,
+}
+
+pub(super) fn print_item(
+    cx: &Context<'_>,
+    templates: &tera::Tera,
+    item: &clean::Item,
+    buf: &mut Buffer,
+    page: &Page<'_>,
+) {
     debug_assert!(!item.is_stripped());
-    // Write the breadcrumb trail header for the top
-    buf.write_str("<h1 class=\"fqn\"><span class=\"in-band\">");
-    let name = match *item.kind {
+    let typ = match *item.kind {
         clean::ModuleItem(_) => {
             if item.is_crate() {
                 "Crate "
@@ -73,48 +98,15 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
             unreachable!();
         }
     };
-    buf.write_str(name);
-    if !item.is_primitive() && !item.is_keyword() {
-        let cur = &cx.current;
-        let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
-        for (i, component) in cur.iter().enumerate().take(amt) {
-            write!(
-                buf,
-                "<a href=\"{}index.html\">{}</a>::<wbr>",
-                "../".repeat(cur.len() - i - 1),
-                component
-            );
-        }
-    }
-    write!(buf, "<a class=\"{}\" href=\"#\">{}</a>", item.type_(), item.name.as_ref().unwrap());
-    write!(
-        buf,
-        "<button id=\"copy-path\" onclick=\"copy_path(this)\" title=\"Copy item path to clipboard\">\
-            <img src=\"{static_root_path}clipboard{suffix}.svg\" \
-                width=\"19\" height=\"18\" \
-                alt=\"Copy item path\">\
-         </button>",
-        static_root_path = page.get_static_root_path(),
-        suffix = page.resource_suffix,
-    );
-
-    buf.write_str("</span>"); // in-band
-    buf.write_str("<span class=\"out-of-band\">");
+    let mut stability_since_raw = Buffer::new();
     render_stability_since_raw(
-        buf,
+        &mut stability_since_raw,
         item.stable_since(cx.tcx()).as_deref(),
         item.const_stability(cx.tcx()),
         None,
         None,
     );
-    buf.write_str(
-        "<span id=\"render-detail\">\
-                <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
-                    title=\"collapse all docs\">\
-                    [<span class=\"inner\">&#x2212;</span>]\
-                </a>\
-            </span>",
-    );
+    let stability_since_raw: String = stability_since_raw.into_inner();
 
     // Write `src` tag
     //
@@ -122,11 +114,38 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
     // [src] link in the downstream documentation will actually come back to
     // this page, and this link will be auto-clicked. The `id` attribute is
     // used to find the link to auto-click.
-    if cx.include_sources && !item.is_primitive() {
-        write_srclink(cx, item, buf);
-    }
+    let src_href =
+        if cx.include_sources && !item.is_primitive() { cx.src_href(item) } else { None };
+
+    let path_components = if item.is_primitive() || item.is_keyword() {
+        vec![]
+    } else {
+        let cur = &cx.current;
+        let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
+        cur.iter()
+            .enumerate()
+            .take(amt)
+            .map(|(i, component)| PathComponent {
+                path: "../".repeat(cur.len() - i - 1),
+                name: component,
+            })
+            .collect()
+    };
+
+    let item_vars = ItemVars {
+        page: page,
+        static_root_path: page.get_static_root_path(),
+        typ: typ,
+        name: &item.name.as_ref().unwrap().as_str(),
+        item_type: &item.type_().to_string(),
+        path_components: path_components,
+        stability_since_raw: &stability_since_raw,
+        src_href: src_href.as_deref(),
+    };
 
-    buf.write_str("</span></h1>"); // out-of-band
+    let teractx = tera::Context::from_serialize(item_vars).unwrap();
+    let heading = templates.render("print_item.html", &teractx).unwrap();
+    buf.write_str(&heading);
 
     match *item.kind {
         clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
diff --git a/src/librustdoc/html/render/templates.rs b/src/librustdoc/html/render/templates.rs
new file mode 100644 (file)
index 0000000..d1f1823
--- /dev/null
@@ -0,0 +1,20 @@
+use std::error::Error as StdError;
+
+use crate::error::Error;
+
+pub(crate) fn load() -> Result<tera::Tera, Error> {
+    let mut templates = tera::Tera::default();
+
+    macro_rules! include_template {
+        ($file:literal, $fullpath:literal) => {
+            templates.add_raw_template($file, include_str!($fullpath)).map_err(|e| Error {
+                file: $file.into(),
+                error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
+            })?
+        };
+    }
+
+    include_template!("page.html", "../templates/page.html");
+    include_template!("print_item.html", "../templates/print_item.html");
+    Ok(templates)
+}
index 5d33681847a4131ae0bf3eed3f7a89459402bed2..cea3452780e6f69a942efd13298ba7603c823895 100644 (file)
@@ -773,8 +773,6 @@ h2.small-section-header > .anchor {
 
 .item-table {
        display: table-row;
-       /* align content left */
-       justify-items: start;
 }
 .item-row {
        display: table-row;
@@ -1969,4 +1967,8 @@ details.undocumented[open] > summary::before {
        .docblock {
                margin-left: 12px;
        }
+
+       .docblock code {
+               overflow-wrap: anywhere;
+       }
 }
index 6f3d08ea655691350729431fad47730689b2edf2..ccc25e6cc495fae43b31844288cfdbd3c728c341 100644 (file)
@@ -70,8 +70,6 @@
 crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png");
 crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
 
-crate static PAGE: &str = include_str!("templates/page.html");
-
 /// The built-in themes given to every documentation site.
 crate mod themes {
     /// The "light" theme, selected by default when no setting is available. Used as the basis for
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
new file mode 100644 (file)
index 0000000..5a468f3
--- /dev/null
@@ -0,0 +1,26 @@
+<h1 class="fqn"> {#- -#}
+    <span class="in-band"> {#- -#}
+        {{-typ-}}
+        {#- The breadcrumbs of the item path, like std::string -#}
+        {%- for component in path_components -%}
+        <a href="{{component.path | safe}}index.html">{{component.name}}</a>::<wbr>
+        {%- endfor -%}
+        <a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
+        <button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
+            <img src="{{static_root_path | safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
+                width="19" height="18" {# -#}
+                alt="Copy item path"> {#- -#}
+        </button> {#- -#}
+    </span> {#- -#}
+    <span class="out-of-band"> {#- -#}
+        {{- stability_since_raw | safe -}}
+        <span id="render-detail"> {#- -#}
+            <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
+                [<span class="inner">&#x2212;</span>] {#- -#}
+            </a> {#- -#}
+        </span> {#- -#}
+        {%- if src_href -%}
+        <a class="srclink" href="{{src_href | safe}}" title="goto source code">[src]</a>
+        {%- endif -%}
+    </span> {#- -#}
+</h1> {#- -#}
index 661453521d1cc2a2baa95aaf4d7c1bb5ca923fd1..4098f17db818a576c7741282c7acb57c0029a93f 100644 (file)
@@ -364,8 +364,11 @@ fn from_tcx(bound: clean::GenericBound, tcx: TyCtxt<'_>) -> Self {
         use clean::GenericBound::*;
         match bound {
             TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
+                // FIXME: should `trait_` be a clean::Path equivalent in JSON?
+                let trait_ =
+                    clean::ResolvedPath { did: trait_.def_id(), path: trait_ }.into_tcx(tcx);
                 GenericBound::TraitBound {
-                    trait_: trait_.into_tcx(tcx),
+                    trait_,
                     generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
                     modifier: from_trait_bound_modifier(modifier),
                 }
@@ -395,15 +398,12 @@ fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
                 param_names: Vec::new(),
             },
             DynTrait(mut bounds, lt) => {
-                let (path, id) = match bounds.remove(0).trait_ {
-                    ResolvedPath { path, did, .. } => (path, did),
-                    _ => unreachable!(),
-                };
+                let first_trait = bounds.remove(0).trait_;
 
                 Type::ResolvedPath {
-                    name: path.whole_name(),
-                    id: from_item_id(id.into()),
-                    args: path
+                    name: first_trait.whole_name(),
+                    id: from_item_id(first_trait.def_id().into()),
+                    args: first_trait
                         .segments
                         .last()
                         .map(|args| Box::new(args.clone().args.into_tcx(tcx))),
@@ -434,11 +434,15 @@ fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
                 mutable: mutability == ast::Mutability::Mut,
                 type_: Box::new((*type_).into_tcx(tcx)),
             },
-            QPath { name, self_type, trait_, .. } => Type::QualifiedPath {
-                name: name.to_string(),
-                self_type: Box::new((*self_type).into_tcx(tcx)),
-                trait_: Box::new((*trait_).into_tcx(tcx)),
-            },
+            QPath { name, self_type, trait_, .. } => {
+                // FIXME: should `trait_` be a clean::Path equivalent in JSON?
+                let trait_ = ResolvedPath { did: trait_.def_id(), path: trait_ }.into_tcx(tcx);
+                Type::QualifiedPath {
+                    name: name.to_string(),
+                    self_type: Box::new((*self_type).into_tcx(tcx)),
+                    trait_: Box::new(trait_),
+                }
+            }
         }
     }
 }
@@ -507,6 +511,11 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
             blanket_impl,
             span: _span,
         } = impl_;
+        // FIXME: should `trait_` be a clean::Path equivalent in JSON?
+        let trait_ = trait_.map(|path| {
+            let did = path.def_id();
+            clean::ResolvedPath { path, did }.into_tcx(tcx)
+        });
         Impl {
             is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
             generics: generics.into_tcx(tcx),
@@ -514,7 +523,7 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
                 .into_iter()
                 .map(|x| x.to_string())
                 .collect(),
-            trait_: trait_.map(|x| x.into_tcx(tcx)),
+            trait_,
             for_: for_.into_tcx(tcx),
             items: ids(items),
             negative: negative_polarity,
index eefe50caa345e85548377051cc9e7d10bb0c1a08..319dd7b42b0ee69cb4d2d23d656f79188977aa82 100644 (file)
@@ -57,7 +57,9 @@
     // scan through included items ahead of time to splice in Deref targets to the "valid" sets
     for it in &new_items {
         if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
-            if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
+            if cleaner.keep_impl(for_)
+                && trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait()
+            {
                 let target = items
                     .iter()
                     .find_map(|item| match *item.kind {
@@ -78,7 +80,9 @@
     new_items.retain(|it| {
         if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
             cleaner.keep_impl(for_)
-                || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
+                || trait_
+                    .as_ref()
+                    .map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
                 || blanket_impl.is_some()
         } else {
             true
index 90300dbd16b136261991b283abfeda085b8f6578..8b1fd662f85fdef57602ae5c3891b28af3547076 100644 (file)
@@ -134,7 +134,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
                     return None;
                 }
             }
-            if let Some(did) = imp.trait_.def_id() {
+            if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) {
                 if did.is_local() && !self.retained.contains(&did.into()) {
                     debug!("ImplStripper: impl item for stripped trait; removing");
                     return None;
diff --git a/src/test/codegen/debug-vtable.rs b/src/test/codegen/debug-vtable.rs
new file mode 100644 (file)
index 0000000..851d68d
--- /dev/null
@@ -0,0 +1,47 @@
+// compile-flags: -Cdebuginfo=2 -Copt-level=0 -Ccodegen-units=1
+// ignore-tidy-linelength
+
+// This test checks the debuginfo for the expected 3 vtables is generated for correct names and number
+// of entries.
+
+// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTrait>::{vtable}"
+// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTrait>::vtable$"
+// NONMSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()",
+// MSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$<tuple$<> >",
+// CHECK: !DISubrange(count: 5
+
+// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTraitWithGenerics<u64, i8>>::{vtable}"
+// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTraitWithGenerics<u64,i8> >::vtable$"
+// CHECK: !DISubrange(count: 4
+
+// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as _>::{vtable}"
+// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, _>::vtable$"
+// CHECK: !DISubrange(count: 3
+
+#![crate_type = "lib"]
+
+pub struct Foo;
+
+pub trait SomeTrait {
+    fn method1(&self) -> u32;
+    fn method2(&self) -> u32;
+}
+
+impl SomeTrait for Foo {
+    fn method1(&self) -> u32 { 1 }
+    fn method2(&self) -> u32 { 2 }
+}
+
+pub trait SomeTraitWithGenerics<T, U> {
+    fn method1(&self) -> (T, U);
+}
+
+impl SomeTraitWithGenerics<u64, i8> for Foo {
+    fn method1(&self) -> (u64, i8) { (1, 2) }
+}
+
+pub fn foo(x: &Foo) -> (u32, (u64, i8), &dyn Send) {
+    let y: &dyn SomeTrait = x;
+    let z: &dyn SomeTraitWithGenerics<u64, i8> = x;
+    (y.method1(), z.method1(), x as &dyn Send)
+}
diff --git a/src/test/codegen/vtabletype.rs b/src/test/codegen/vtabletype.rs
deleted file mode 100644 (file)
index 82d65b1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// This test depends on a patch that was committed to upstream LLVM
-// after 5.0, then backported to the Rust LLVM fork.
-
-// ignore-windows
-// ignore-macos
-
-// compile-flags: -g -C no-prepopulate-passes
-
-// CHECK-LABEL: @main
-// CHECK: {{.*}}DICompositeType{{.*}}name: "vtable",{{.*}}vtableHolder:{{.*}}
-
-pub trait T {
-}
-
-impl T for f64 {
-}
-
-pub fn main() {
-    let d = 23.0f64;
-    let td = &d as &T;
-}
diff --git a/src/test/rustdoc-gui/docblock-big-code-mobile.goml b/src/test/rustdoc-gui/docblock-big-code-mobile.goml
new file mode 100644 (file)
index 0000000..12677a5
--- /dev/null
@@ -0,0 +1,9 @@
+// If we have a long `<code>`, we need to ensure that it'll be fully displayed on mobile, meaning
+// that it'll be on two lines.
+emulate: "iPhone 8" // it has the following size: (375, 667)
+goto: file://|DOC_PATH|/test_docs/long_code_block/index.html
+// We now check that the block is on two lines:
+show-text: true // We need to enable text draw to be able to have the "real" size
+// Little explanations for this test: if the text wasn't displayed on two lines, it would take
+// around 20px (which is the font size).
+assert-property: (".docblock p > code", {"offsetHeight": "42"})
index 0aa1426a36abf38b349b98044699601e7295b2e3..2a147e64d8bf2706f4f137774b07bd79993661aa 100644 (file)
@@ -120,3 +120,6 @@ pub mod keyword {}
 pub mod huge_amount_of_consts {
     include!(concat!(env!("OUT_DIR"), "/huge_amount_of_consts.rs"));
 }
+
+/// Very long code text `hereIgoWithLongTextBecauseWhyNotAndWhyWouldntI`.
+pub mod long_code_block {}
index 47fea5a23a78da3714bca9e4b2c1e93cea612984..0ac03195fa3418481d6d1419f129b2db8aad9af7 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL | impl Eq for &dyn DynEq {}
    |      ^^ lifetime mismatch
    |
-   = note: expected trait `PartialEq`
-              found trait `PartialEq`
+   = note: expected trait `<&dyn DynEq as PartialEq>`
+              found trait `<&(dyn DynEq + 'static) as PartialEq>`
 note: the lifetime `'_` as defined on the impl at 9:13...
   --> $DIR/E0308-2.rs:9:13
    |
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs
new file mode 100644 (file)
index 0000000..2a34ed4
--- /dev/null
@@ -0,0 +1,31 @@
+#![deny(non_exhaustive_omitted_patterns)]
+//~^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+//~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+#![allow(non_exhaustive_omitted_patterns)]
+//~^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+//~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+
+fn main() {
+    enum Foo {
+        A, B, C,
+    }
+
+    #[allow(non_exhaustive_omitted_patterns)]
+    match Foo::A {
+        Foo::A => {}
+        Foo::B => {}
+    }
+    //~^^^^^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+
+    match Foo::A {
+        Foo::A => {}
+        Foo::B => {}
+        #[warn(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+}
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
new file mode 100644 (file)
index 0000000..691f64c
--- /dev/null
@@ -0,0 +1,93 @@
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:1:1
+   |
+LL | #![deny(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:4:1
+   |
+LL | #![allow(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:26:9
+   |
+LL |         #[warn(non_exhaustive_omitted_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:1:1
+   |
+LL | #![deny(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:4:1
+   |
+LL | #![allow(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:26:9
+   |
+LL |         #[warn(non_exhaustive_omitted_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
index 03e3311e0f39bac7d151723e1276e51e79bcba52..02c80c2940824ca76c02091170d99e0bec7b58a0 100644 (file)
@@ -19,8 +19,8 @@ note: ...so that the types are compatible
    |
 LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
    |        ^^^^^^^^^
-   = note: expected `Publisher<'_>`
-              found `Publisher<'_>`
+   = note: expected `<MyStruct<'a> as Publisher<'_>>`
+              found `<MyStruct<'_> as Publisher<'_>>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-65230.rs b/src/test/ui/issues/issue-65230.rs
new file mode 100644 (file)
index 0000000..54141d2
--- /dev/null
@@ -0,0 +1,11 @@
+trait T0 {}
+trait T1: T0 {}
+
+trait T2 {}
+
+impl<'a> T0 for &'a (dyn T2 + 'static) {}
+
+impl T1 for &dyn T2 {}
+//~^ ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-65230.stderr b/src/test/ui/issues/issue-65230.stderr
new file mode 100644 (file)
index 0000000..d75428f
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-65230.rs:8:6
+   |
+LL | impl T1 for &dyn T2 {}
+   |      ^^ lifetime mismatch
+   |
+   = note: expected trait `<&dyn T2 as T0>`
+              found trait `<&(dyn T2 + 'static) as T0>`
+note: the lifetime `'_` as defined on the impl at 8:13...
+  --> $DIR/issue-65230.rs:8:13
+   |
+LL | impl T1 for &dyn T2 {}
+   |             ^
+   = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index 3dee3345db640b85d5e1614a02e0a41113257dec..4e69dda8721d641509f0e6abbf7a8565d555f696 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     let _x = *s;
    |         ^^ lifetime mismatch
    |
-   = note: expected type `Sized`
-              found type `Sized`
+   = note: expected type `<<&'a T as A>::X as Sized>`
+              found type `<<&'static T as A>::X as Sized>`
 note: the lifetime `'a` as defined on the function body at 9:8...
   --> $DIR/issue-50716.rs:9:8
    |
index 0caf186db1d5fac483284bcb1435303ca0560378..03f5265e376f060c3a50c4a47d7862ff86055029 100644 (file)
@@ -2,7 +2,6 @@
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
-#![feature(proc_macro_is_available)]
 
 extern crate proc_macro;
 
index 52f7e00d572801dc6a0a6e65af47c851826175f1..b32bb61b495d3177203a02ca52a6dff1cc00fa4b 100644 (file)
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(proc_macro_is_available)]
-
 extern crate proc_macro;
 
 // aux-build:is-available.rs
index c196ded404ddcef8345eefa22c186d9769a8ce25..ce1b5c7c377a49d05ffe10c056a4d506a6739741 100644 (file)
@@ -1,5 +1,7 @@
 // Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly.
 
+#![feature(non_exhaustive_omitted_patterns_lint)]
+
 // aux-build:enums.rs
 extern crate enums;
 
index e66fd8008a10bbd07cd7b599f0f6667963dea5ec..5b21e0402b192795c1008904da22eae97f7d24af 100644 (file)
@@ -1,11 +1,11 @@
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:127:9
+  --> $DIR/reachable-patterns.rs:129:9
    |
 LL |         VariantNonExhaustive::Bar { x, .. } => {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:124:12
+  --> $DIR/reachable-patterns.rs:126:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,13 +13,13 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:132:9
+  --> $DIR/reachable-patterns.rs:134:9
    |
 LL |     let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:131:12
+  --> $DIR/reachable-patterns.rs:133:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,13 +27,13 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:140:29
+  --> $DIR/reachable-patterns.rs:142:29
    |
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:139:12
+  --> $DIR/reachable-patterns.rs:141:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:140:9
+  --> $DIR/reachable-patterns.rs:142:9
    |
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed
@@ -50,13 +50,13 @@ LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested
    = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:54:9
+  --> $DIR/reachable-patterns.rs:56:9
    |
 LL |         _ => {}
    |         ^ pattern `Struct { .. }` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:53:16
+  --> $DIR/reachable-patterns.rs:55:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,13 +64,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:61:9
+  --> $DIR/reachable-patterns.rs:63:9
    |
 LL |         _ => {}
    |         ^ pattern `Tuple(_)` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:60:16
+  --> $DIR/reachable-patterns.rs:62:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -78,13 +78,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:71:9
+  --> $DIR/reachable-patterns.rs:73:9
    |
 LL |         _ => {}
    |         ^ pattern `Unit` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:70:16
+  --> $DIR/reachable-patterns.rs:72:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -92,13 +92,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:88:32
+  --> $DIR/reachable-patterns.rs:90:32
    |
 LL |         NestedNonExhaustive::A(_) => {}
    |                                ^ patterns `Tuple(_)` and `Struct { .. }` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:85:12
+  --> $DIR/reachable-patterns.rs:87:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,7 +106,7 @@ LL |     #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:90:9
+  --> $DIR/reachable-patterns.rs:92:9
    |
 LL |         _ => {}
    |         ^ pattern `C` not covered
@@ -115,13 +115,13 @@ LL |         _ => {}
    = note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:120:9
+  --> $DIR/reachable-patterns.rs:122:9
    |
 LL |         _ => {}
    |         ^ patterns `HostUnreachable`, `NetworkUnreachable`, `NetworkDown` and 18 more not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:97:12
+  --> $DIR/reachable-patterns.rs:99:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,13 +129,13 @@ LL |     #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `ErrorKind` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:157:9
+  --> $DIR/reachable-patterns.rs:159:9
    |
 LL |         _ => {}
    |         ^ pattern `A(_)` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:155:12
+  --> $DIR/reachable-patterns.rs:157:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd-intrinsic/issue-85855.rs b/src/test/ui/simd-intrinsic/issue-85855.rs
deleted file mode 100644 (file)
index f276fbd..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Check that appropriate errors are reported if an intrinsic is defined
-// with the wrong number of generic lifetime/type/const parameters, and
-// that no ICE occurs in these cases.
-
-#![feature(platform_intrinsics)]
-#![crate_type="lib"]
-
-extern "platform-intrinsic" {
-    fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
-    //~^ ERROR: intrinsic has wrong number of lifetime parameters
-
-    fn simd_add<'a, T>(x: T, y: T) -> T;
-
-    fn simd_sub<T, U>(x: T, y: U);
-    //~^ ERROR: intrinsic has wrong number of type parameters
-
-    fn simd_mul<T, const N: usize>(x: T, y: T);
-    //~^ ERROR: intrinsic has wrong number of const parameters
-}
diff --git a/src/test/ui/simd-intrinsic/issue-85855.stderr b/src/test/ui/simd-intrinsic/issue-85855.stderr
deleted file mode 100644 (file)
index fb2f1fb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0094]: intrinsic has wrong number of lifetime parameters: found 1, expected 0
-  --> $DIR/issue-85855.rs:9:27
-   |
-LL |     fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
-   |                           ^^^^^^^^^^^ expected 0 lifetime parameters
-
-error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
-  --> $DIR/issue-85855.rs:14:16
-   |
-LL |     fn simd_sub<T, U>(x: T, y: U);
-   |                ^^^^^^ expected 1 type parameter
-
-error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0
-  --> $DIR/issue-85855.rs:17:16
-   |
-LL |     fn simd_mul<T, const N: usize>(x: T, y: T);
-   |                ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0094`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
deleted file mode 100644 (file)
index 9736d1b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// build-fail
-// ignore-emscripten
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct x4<T>(pub T, pub T, pub T, pub T);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-extern "platform-intrinsic" {
-    fn simd_saturating_add<T>(x: T, y: T) -> T;
-    fn simd_saturating_sub<T>(x: T, y: T) -> T;
-}
-
-fn main() {
-    let x = i32x4(0, 0, 0, 0);
-    let y = x4(0_usize, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-
-    unsafe {
-        simd_saturating_add(x, x);
-        simd_saturating_add(y, y);
-        simd_saturating_sub(x, x);
-        simd_saturating_sub(y, y);
-
-        simd_saturating_add(z, z);
-        //~^ ERROR expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-        simd_saturating_sub(z, z);
-        //~^ ERROR expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr
deleted file mode 100644 (file)
index 0e88540..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_saturating_add` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-  --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:33:9
-   |
-LL |         simd_saturating_add(z, z);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_saturating_sub` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-  --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:35:9
-   |
-LL |         simd_saturating_sub(z, z);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs
deleted file mode 100644 (file)
index 3576eed..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-extern "platform-intrinsic" {
-    fn simd_add<T>(x: T, y: T) -> T;
-    fn simd_sub<T>(x: T, y: T) -> T;
-    fn simd_mul<T>(x: T, y: T) -> T;
-    fn simd_div<T>(x: T, y: T) -> T;
-    fn simd_rem<T>(x: T, y: T) -> T;
-    fn simd_shl<T>(x: T, y: T) -> T;
-    fn simd_shr<T>(x: T, y: T) -> T;
-    fn simd_and<T>(x: T, y: T) -> T;
-    fn simd_or<T>(x: T, y: T) -> T;
-    fn simd_xor<T>(x: T, y: T) -> T;
-
-    fn simd_neg<T>(x: T) -> T;
-}
-
-fn main() {
-    let x = i32x4(0, 0, 0, 0);
-    let y = u32x4(0, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-
-    unsafe {
-        simd_add(x, x);
-        simd_add(y, y);
-        simd_add(z, z);
-        simd_sub(x, x);
-        simd_sub(y, y);
-        simd_sub(z, z);
-        simd_mul(x, x);
-        simd_mul(y, y);
-        simd_mul(z, z);
-        simd_div(x, x);
-        simd_div(y, y);
-        simd_div(z, z);
-        simd_rem(x, x);
-        simd_rem(y, y);
-        simd_rem(z, z);
-
-        simd_shl(x, x);
-        simd_shl(y, y);
-        simd_shr(x, x);
-        simd_shr(y, y);
-        simd_and(x, x);
-        simd_and(y, y);
-        simd_or(x, x);
-        simd_or(y, y);
-        simd_xor(x, x);
-        simd_xor(y, y);
-
-        simd_neg(x);
-        simd_neg(z);
-
-
-        simd_add(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_sub(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_mul(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_div(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_shl(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_shr(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_and(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_or(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_xor(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-
-        simd_neg(0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-
-
-        simd_shl(z, z);
-//~^ ERROR unsupported operation on `f32x4` with element `f32`
-        simd_shr(z, z);
-//~^ ERROR unsupported operation on `f32x4` with element `f32`
-        simd_and(z, z);
-//~^ ERROR unsupported operation on `f32x4` with element `f32`
-        simd_or(z, z);
-//~^ ERROR unsupported operation on `f32x4` with element `f32`
-        simd_xor(z, z);
-//~^ ERROR unsupported operation on `f32x4` with element `f32`
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.stderr
deleted file mode 100644 (file)
index 99c5196..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:69:9
-   |
-LL |         simd_add(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:71:9
-   |
-LL |         simd_sub(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:73:9
-   |
-LL |         simd_mul(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:75:9
-   |
-LL |         simd_div(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:77:9
-   |
-LL |         simd_shl(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:79:9
-   |
-LL |         simd_shr(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:81:9
-   |
-LL |         simd_and(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:83:9
-   |
-LL |         simd_or(0, 0);
-   |         ^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:85:9
-   |
-LL |         simd_xor(0, 0);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:88:9
-   |
-LL |         simd_neg(0);
-   |         ^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:92:9
-   |
-LL |         simd_shl(z, z);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:94:9
-   |
-LL |         simd_shr(z, z);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:96:9
-   |
-LL |         simd_and(z, z);
-   |         ^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:98:9
-   |
-LL |         simd_or(z, z);
-   |         ^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:100:9
-   |
-LL |         simd_xor(z, z);
-   |         ^^^^^^^^^^^^^^
-
-error: aborting due to 15 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
deleted file mode 100644 (file)
index ed267d8..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-// build-fail
-
-// Test that the simd_bitmask intrinsic produces ok-ish error
-// messages when misused.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x2(pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x8(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x16(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x32(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x64(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-extern "platform-intrinsic" {
-    fn simd_bitmask<T, U>(x: T) -> U;
-}
-
-fn main() {
-    let m2 = u32x2(0, 0);
-    let m4 = u32x4(0, 0, 0, 0);
-    let m8 = u8x8(0, 0, 0, 0, 0, 0, 0, 0);
-    let m16 = u8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-    let m32 = u8x32(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-    let m64 = u8x64(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
-    unsafe {
-        let _: u8 = simd_bitmask(m2);
-        let _: u8 = simd_bitmask(m4);
-        let _: u8 = simd_bitmask(m8);
-        let _: u16 = simd_bitmask(m16);
-        let _: u32 = simd_bitmask(m32);
-        let _: u64 = simd_bitmask(m64);
-
-        let _: u16 = simd_bitmask(m2);
-        //~^ ERROR bitmask `u16`, expected `u8`
-
-        let _: u16 = simd_bitmask(m8);
-        //~^ ERROR bitmask `u16`, expected `u8`
-
-        let _: u32 = simd_bitmask(m16);
-        //~^ ERROR bitmask `u32`, expected `u16`
-
-        let _: u64 = simd_bitmask(m32);
-        //~^ ERROR bitmask `u64`, expected `u32`
-
-        let _: u128 = simd_bitmask(m64);
-        //~^ ERROR bitmask `u128`, expected `u64`
-
-   }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr
deleted file mode 100644 (file)
index 8cb235b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:76:22
-   |
-LL |         let _: u16 = simd_bitmask(m2);
-   |                      ^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:79:22
-   |
-LL |         let _: u16 = simd_bitmask(m8);
-   |                      ^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u32`, expected `u16`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:82:22
-   |
-LL |         let _: u32 = simd_bitmask(m16);
-   |                      ^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u64`, expected `u32`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:85:22
-   |
-LL |         let _: u64 = simd_bitmask(m32);
-   |                      ^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u128`, expected `u64`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:88:23
-   |
-LL |         let _: u128 = simd_bitmask(m64);
-   |                       ^^^^^^^^^^^^^^^^^
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs
deleted file mode 100644 (file)
index 4f4fa06..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32,
-             i32, i32, i32, i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct f32x4(f32, f32, f32, f32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct f32x8(f32, f32, f32, f32,
-             f32, f32, f32, f32);
-
-
-extern "platform-intrinsic" {
-    fn simd_cast<T, U>(x: T) -> U;
-}
-
-fn main() {
-    let x = i32x4(0, 0, 0, 0);
-
-    unsafe {
-        simd_cast::<i32, i32>(0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_cast::<i32, i32x4>(0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_cast::<i32x4, i32>(x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-        simd_cast::<_, i32x8>(x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.stderr
deleted file mode 100644 (file)
index d794a74..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-cast.rs:34:9
-   |
-LL |         simd_cast::<i32, i32>(0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-cast.rs:36:9
-   |
-LL |         simd_cast::<i32, i32x4>(0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-cast.rs:38:9
-   |
-LL |         simd_cast::<i32x4, i32>(x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
-  --> $DIR/simd-intrinsic-generic-cast.rs:40:9
-   |
-LL |         simd_cast::<_, i32x8>(x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs
deleted file mode 100644 (file)
index 3cd3804..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i16x8(i16, i16, i16, i16,
-             i16, i16, i16, i16);
-
-extern "platform-intrinsic" {
-    fn simd_eq<T, U>(x: T, y: T) -> U;
-    fn simd_ne<T, U>(x: T, y: T) -> U;
-    fn simd_lt<T, U>(x: T, y: T) -> U;
-    fn simd_le<T, U>(x: T, y: T) -> U;
-    fn simd_gt<T, U>(x: T, y: T) -> U;
-    fn simd_ge<T, U>(x: T, y: T) -> U;
-}
-
-fn main() {
-    let x = i32x4(0, 0, 0, 0);
-
-    unsafe {
-        simd_eq::<i32, i32>(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_ne::<i32, i32>(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_lt::<i32, i32>(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_le::<i32, i32>(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_gt::<i32, i32>(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_ge::<i32, i32>(0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-
-        simd_eq::<_, i32>(x, x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-        simd_ne::<_, i32>(x, x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-        simd_lt::<_, i32>(x, x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-        simd_le::<_, i32>(x, x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-        simd_gt::<_, i32>(x, x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-        simd_ge::<_, i32>(x, x);
-        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
-
-        simd_eq::<_, i16x8>(x, x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-        simd_ne::<_, i16x8>(x, x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-        simd_lt::<_, i16x8>(x, x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-        simd_le::<_, i16x8>(x, x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-        simd_gt::<_, i16x8>(x, x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-        simd_ge::<_, i16x8>(x, x);
-//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.stderr
deleted file mode 100644 (file)
index 36c6b93..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:28:9
-   |
-LL |         simd_eq::<i32, i32>(0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:30:9
-   |
-LL |         simd_ne::<i32, i32>(0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:32:9
-   |
-LL |         simd_lt::<i32, i32>(0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:34:9
-   |
-LL |         simd_le::<i32, i32>(0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:36:9
-   |
-LL |         simd_gt::<i32, i32>(0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:38:9
-   |
-LL |         simd_ge::<i32, i32>(0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:41:9
-   |
-LL |         simd_eq::<_, i32>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:43:9
-   |
-LL |         simd_ne::<_, i32>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:45:9
-   |
-LL |         simd_lt::<_, i32>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:47:9
-   |
-LL |         simd_le::<_, i32>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:49:9
-   |
-LL |         simd_gt::<_, i32>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:51:9
-   |
-LL |         simd_ge::<_, i32>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:54:9
-   |
-LL |         simd_eq::<_, i16x8>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:56:9
-   |
-LL |         simd_ne::<_, i16x8>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:58:9
-   |
-LL |         simd_lt::<_, i16x8>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:60:9
-   |
-LL |         simd_le::<_, i16x8>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:62:9
-   |
-LL |         simd_gt::<_, i16x8>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:64:9
-   |
-LL |         simd_ge::<_, i16x8>(x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 18 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs
deleted file mode 100644 (file)
index abde691..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics, rustc_attrs)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32,
-             i32, i32, i32, i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct f32x2(f32, f32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct f32x4(f32, f32, f32, f32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-#[allow(non_camel_case_types)]
-struct f32x8(f32, f32, f32, f32,
-             f32, f32, f32, f32);
-
-extern "platform-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
-
-    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
-    fn simd_shuffle4<T, U>(x: T, y: T, idx: [u32; 4]) -> U;
-    fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
-}
-
-fn main() {
-    let x = i32x4(0, 0, 0, 0);
-
-    unsafe {
-        simd_insert(0, 0, 0);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        simd_insert(x, 0, 1.0);
-        //~^ ERROR expected inserted type `i32` (element of input `i32x4`), found `f64`
-        simd_extract::<_, f32>(x, 0);
-        //~^ ERROR expected return type `i32` (element of input `i32x4`), found `f32`
-
-        const IDX2: [u32; 2] = [0; 2];
-        simd_shuffle2::<i32, i32>(0, 0, IDX2);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        const IDX4: [u32; 4] = [0; 4];
-        simd_shuffle4::<i32, i32>(0, 0, IDX4);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        const IDX8: [u32; 8] = [0; 8];
-        simd_shuffle8::<i32, i32>(0, 0, IDX8);
-        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-
-        simd_shuffle2::<_, f32x2>(x, x, IDX2);
-//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-        simd_shuffle4::<_, f32x4>(x, x, IDX4);
-//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-        simd_shuffle8::<_, f32x8>(x, x, IDX8);
-//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-
-        simd_shuffle2::<_, i32x8>(x, x, IDX2);
-        //~^ ERROR expected return type of length 2, found `i32x8` with length 8
-        simd_shuffle4::<_, i32x8>(x, x, IDX4);
-        //~^ ERROR expected return type of length 4, found `i32x8` with length 8
-        simd_shuffle8::<_, i32x2>(x, x, IDX8);
-        //~^ ERROR expected return type of length 8, found `i32x2` with length 2
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.stderr
deleted file mode 100644 (file)
index 4220411..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:46:9
-   |
-LL |         simd_insert(0, 0, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
-  --> $DIR/simd-intrinsic-generic-elements.rs:48:9
-   |
-LL |         simd_insert(x, 0, 1.0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:50:9
-   |
-LL |         simd_extract::<_, f32>(x, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:54:9
-   |
-LL |         simd_shuffle2::<i32, i32>(0, 0, IDX2);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:57:9
-   |
-LL |         simd_shuffle4::<i32, i32>(0, 0, IDX4);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:60:9
-   |
-LL |         simd_shuffle8::<i32, i32>(0, 0, IDX8);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:63:9
-   |
-LL |         simd_shuffle2::<_, f32x2>(x, x, IDX2);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:65:9
-   |
-LL |         simd_shuffle4::<_, f32x4>(x, x, IDX4);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:67:9
-   |
-LL |         simd_shuffle8::<_, f32x8>(x, x, IDX8);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/simd-intrinsic-generic-elements.rs:70:9
-   |
-LL |         simd_shuffle2::<_, i32x8>(x, x, IDX2);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/simd-intrinsic-generic-elements.rs:72:9
-   |
-LL |         simd_shuffle4::<_, i32x8>(x, x, IDX4);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/simd-intrinsic-generic-elements.rs:74:9
-   |
-LL |         simd_shuffle8::<_, i32x2>(x, x, IDX8);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
deleted file mode 100644 (file)
index ede4b26..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// build-fail
-// ignore-emscripten
-
-// Test that the simd_reduce_{op} intrinsics produce ok-ish error
-// messages when misused.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-
-extern "platform-intrinsic" {
-    fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
-    fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
-    fn simd_reduce_and<T, U>(x: T) -> U;
-    fn simd_reduce_or<T, U>(x: T) -> U;
-    fn simd_reduce_xor<T, U>(x: T) -> U;
-    fn simd_reduce_all<T>(x: T) -> bool;
-    fn simd_reduce_any<T>(x: T) -> bool;
-}
-
-fn main() {
-    let x = u32x4(0, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-
-    unsafe {
-        simd_reduce_add_ordered(z, 0);
-        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
-        simd_reduce_mul_ordered(z, 1);
-        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
-
-        let _: f32 = simd_reduce_and(x);
-        //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
-        let _: f32 = simd_reduce_or(x);
-        //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
-        let _: f32 = simd_reduce_xor(x);
-        //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
-
-        let _: f32 = simd_reduce_and(z);
-        //~^ ERROR unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
-        let _: f32 = simd_reduce_or(z);
-        //~^ ERROR unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
-        let _: f32 = simd_reduce_xor(z);
-        //~^ ERROR unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
-
-        let _: bool = simd_reduce_all(z);
-        //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
-        let _: bool = simd_reduce_any(z);
-        //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
deleted file mode 100644 (file)
index 91a62f6..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:34:9
-   |
-LL |         simd_reduce_add_ordered(z, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:36:9
-   |
-LL |         simd_reduce_mul_ordered(z, 1);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:39:22
-   |
-LL |         let _: f32 = simd_reduce_and(x);
-   |                      ^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:41:22
-   |
-LL |         let _: f32 = simd_reduce_or(x);
-   |                      ^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:43:22
-   |
-LL |         let _: f32 = simd_reduce_xor(x);
-   |                      ^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:46:22
-   |
-LL |         let _: f32 = simd_reduce_and(z);
-   |                      ^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:48:22
-   |
-LL |         let _: f32 = simd_reduce_or(z);
-   |                      ^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:50:22
-   |
-LL |         let _: f32 = simd_reduce_xor(z);
-   |                      ^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:53:23
-   |
-LL |         let _: bool = simd_reduce_all(z);
-   |                       ^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:55:23
-   |
-LL |         let _: bool = simd_reduce_any(z);
-   |                       ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 10 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
deleted file mode 100644 (file)
index 7d68af4..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-// build-fail
-
-// Test that the simd_select intrinsic produces ok-ish error
-// messages when misused.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq)]
-struct b8x4(pub i8, pub i8, pub i8, pub i8);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq)]
-struct b8x8(pub i8, pub i8, pub i8, pub i8,
-            pub i8, pub i8, pub i8, pub i8);
-
-extern "platform-intrinsic" {
-    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
-    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
-}
-
-fn main() {
-    let m4 = b8x4(0, 0, 0, 0);
-    let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0);
-    let x = u32x4(0, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-
-    unsafe {
-        simd_select(m4, x, x);
-
-        simd_select(m8, x, x);
-        //~^ ERROR mismatched lengths: mask length `8` != other vector length `4`
-
-        simd_select(x, x, x);
-        //~^ ERROR mask element type is `u32`, expected `i_`
-
-        simd_select(z, z, z);
-        //~^ ERROR mask element type is `f32`, expected `i_`
-
-        simd_select(m4, 0u32, 1u32);
-        //~^ ERROR found non-SIMD `u32`
-
-        simd_select_bitmask(0u16, x, x);
-        //~^ ERROR mask length `16` != other vector length `4`
-        //
-        simd_select_bitmask(0u8, 1u32, 2u32);
-        //~^ ERROR found non-SIMD `u32`
-
-        simd_select_bitmask(0.0f32, x, x);
-        //~^ ERROR `f32` is not an integral type
-
-        simd_select_bitmask("x", x, x);
-        //~^ ERROR `&str` is not an integral type
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
deleted file mode 100644 (file)
index a1ef0bb..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
-  --> $DIR/simd-intrinsic-generic-select.rs:40:9
-   |
-LL |         simd_select(m8, x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_`
-  --> $DIR/simd-intrinsic-generic-select.rs:43:9
-   |
-LL |         simd_select(x, x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_`
-  --> $DIR/simd-intrinsic-generic-select.rs:46:9
-   |
-LL |         simd_select(z, z, z);
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32`
-  --> $DIR/simd-intrinsic-generic-select.rs:49:9
-   |
-LL |         simd_select(m4, 0u32, 1u32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `16` != other vector length `4`
-  --> $DIR/simd-intrinsic-generic-select.rs:52:9
-   |
-LL |         simd_select_bitmask(0u16, x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32`
-  --> $DIR/simd-intrinsic-generic-select.rs:55:9
-   |
-LL |         simd_select_bitmask(0u8, 1u32, 2u32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type
-  --> $DIR/simd-intrinsic-generic-select.rs:58:9
-   |
-LL |         simd_select_bitmask(0.0f32, x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type
-  --> $DIR/simd-intrinsic-generic-select.rs:61:9
-   |
-LL |         simd_select_bitmask("x", x, x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 8 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs
deleted file mode 100644 (file)
index 9611780..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// build-fail
-
-// Test that the simd_shuffle intrinsic produces ok-ish error
-// messages when misused.
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct Simd<T, const N: usize>([T; N]);
-
-extern "platform-intrinsic" {
-    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
-}
-
-fn main() {
-    const I: [u32; 2] = [0; 2];
-    const I2: [f32; 2] = [0.; 2];
-    let v = Simd::<u32, 4>([0; 4]);
-
-    unsafe {
-        let _: Simd<u32, 2> = simd_shuffle(v, v, I);
-
-        let _: Simd<u32, 4> = simd_shuffle(v, v, I);
-        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
-
-        let _: Simd<f32, 2> = simd_shuffle(v, v, I);
-        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
-
-        let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
-        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
-    }
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr
deleted file mode 100644 (file)
index 9eeb000..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4_usize>` with length 4
-  --> $DIR/simd-intrinsic-generic-shuffle.rs:24:31
-   |
-LL |         let _: Simd<u32, 4> = simd_shuffle(v, v, I);
-   |                               ^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd<u32, 4_usize>`), found `Simd<f32, 2_usize>` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-shuffle.rs:27:31
-   |
-LL |         let _: Simd<f32, 2> = simd_shuffle(v, v, I);
-   |                               ^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
-  --> $DIR/simd-intrinsic-generic-shuffle.rs:30:31
-   |
-LL |         let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs
deleted file mode 100644 (file)
index 7221b3a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being
-// passed the wrong Instance, causing issues with inlining. See #67557.
-//
-// run-pass
-// compile-flags: -Zmir-opt-level=4
-#![feature(platform_intrinsics, repr_simd)]
-
-extern "platform-intrinsic" {
-    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
-}
-
-#[repr(simd)]
-#[derive(Debug, PartialEq)]
-struct Simd2(u8, u8);
-
-fn main() {
-    unsafe {
-        let _: Simd2 = inline_me();
-    }
-}
-
-#[inline(always)]
-unsafe fn inline_me() -> Simd2 {
-    const IDX: [u32; 2] = [0, 3];
-    simd_shuffle2(Simd2(10, 11), Simd2(12, 13), IDX)
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs
deleted file mode 100644 (file)
index 0d15427..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed
-// the wrong Instance, causing issues with inlining. See #67557.
-//
-// run-pass
-// compile-flags: -Zmir-opt-level=4
-#![feature(platform_intrinsics, repr_simd)]
-
-extern "platform-intrinsic" {
-    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
-}
-
-#[repr(simd)]
-#[derive(Debug, PartialEq)]
-struct Simd2(u8, u8);
-
-fn main() {
-    unsafe {
-        const IDX: [u32; 2] = [0, 1];
-        let p_res: Simd2 = simd_shuffle2(Simd2(10, 11), Simd2(12, 13), IDX);
-        let a_res: Simd2 = inline_me();
-
-        assert_10_11(p_res);
-        assert_10_13(a_res);
-    }
-}
-
-#[inline(never)]
-fn assert_10_11(x: Simd2) {
-    assert_eq!(x, Simd2(10, 11));
-}
-
-#[inline(never)]
-fn assert_10_13(x: Simd2) {
-    assert_eq!(x, Simd2(10, 13));
-}
-
-
-#[inline(always)]
-unsafe fn inline_me() -> Simd2 {
-    const IDX: [u32; 2] = [0, 3];
-    simd_shuffle2(Simd2(10, 11), Simd2(12, 13), IDX)
-}
diff --git a/src/test/ui/simd/array-trait.rs b/src/test/ui/simd/array-trait.rs
new file mode 100644 (file)
index 0000000..45c10b3
--- /dev/null
@@ -0,0 +1,41 @@
+// Figuring out the size of a vector type that depends on traits doesn't ICE
+
+#![allow(dead_code)]
+
+// pretty-expanded FIXME #23616
+
+#![feature(repr_simd, platform_intrinsics, generic_const_exprs)]
+#![allow(non_camel_case_types, incomplete_features)]
+
+pub trait Simd {
+    type Lane: Clone + Copy;
+    const SIZE: usize;
+}
+
+pub struct i32x4;
+impl Simd for i32x4 {
+    type Lane = i32;
+    const SIZE: usize = 4;
+}
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct T<S: Simd>([S::Lane; S::SIZE]);
+//~^ ERROR unconstrained generic constant
+
+extern "platform-intrinsic" {
+    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+    fn simd_extract<T, E>(x: T, idx: u32) -> E;
+}
+
+pub fn main() {
+    let mut t = T::<i32x4>([0; 4]);
+    unsafe {
+        for i in 0_i32..4 {
+            t = simd_insert(t, i as u32, i);
+        }
+        for i in 0_i32..4 {
+            assert_eq!(i, simd_extract(t, i as u32));
+        }
+    }
+}
diff --git a/src/test/ui/simd/array-trait.stderr b/src/test/ui/simd/array-trait.stderr
new file mode 100644 (file)
index 0000000..765215c
--- /dev/null
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+  --> $DIR/array-trait.rs:23:23
+   |
+LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
+   |                       ^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/simd/array-type.rs b/src/test/ui/simd/array-type.rs
new file mode 100644 (file)
index 0000000..7d66395
--- /dev/null
@@ -0,0 +1,42 @@
+// run-pass
+#![allow(dead_code)]
+
+// pretty-expanded FIXME #23616
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct S([i32; 4]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct T<const N: usize>([i32; N]);
+
+extern "platform-intrinsic" {
+    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+    fn simd_extract<T, E>(x: T, idx: u32) -> E;
+}
+
+pub fn main() {
+    let mut s = S([0; 4]);
+
+    unsafe {
+        for i in 0_i32..4 {
+            s = simd_insert(s, i as u32, i);
+        }
+        for i in 0_i32..4 {
+            assert_eq!(i, simd_extract(s, i as u32));
+        }
+    }
+
+    let mut t = T::<4>([0; 4]);
+    unsafe {
+        for i in 0_i32..4 {
+            t = simd_insert(t, i as u32, i);
+        }
+        for i in 0_i32..4 {
+            assert_eq!(i, simd_extract(t, i as u32));
+        }
+    }
+}
diff --git a/src/test/ui/simd/generics.rs b/src/test/ui/simd/generics.rs
new file mode 100644 (file)
index 0000000..fa9d35e
--- /dev/null
@@ -0,0 +1,85 @@
+// run-pass
+#![allow(non_camel_case_types)]
+#![feature(repr_simd, platform_intrinsics)]
+
+use std::ops;
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct f32x4(f32, f32, f32, f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct A<const N: usize>([f32; N]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct B<T>([T; 4]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct C<T, const N: usize>([T; N]);
+
+
+extern "platform-intrinsic" {
+    fn simd_add<T>(x: T, y: T) -> T;
+}
+
+fn add<T: ops::Add<Output=T>>(lhs: T, rhs: T) -> T {
+    lhs + rhs
+}
+
+impl ops::Add for f32x4 {
+    type Output = f32x4;
+
+    fn add(self, rhs: f32x4) -> f32x4 {
+        unsafe { simd_add(self, rhs) }
+    }
+}
+
+impl ops::Add for A<4> {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        unsafe { simd_add(self, rhs) }
+    }
+}
+
+impl ops::Add for B<f32> {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        unsafe { simd_add(self, rhs) }
+    }
+}
+
+impl ops::Add for C<f32, 4> {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        unsafe { simd_add(self, rhs) }
+    }
+}
+
+
+pub fn main() {
+    let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32];
+    let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32];
+
+    // lame-o
+    let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
+    let f32x4(a0, a1, a2, a3) = add(a, a);
+    assert_eq!(a0, 2.0f32);
+    assert_eq!(a1, 4.0f32);
+    assert_eq!(a2, 6.0f32);
+    assert_eq!(a3, 8.0f32);
+
+    let a = A(x);
+    assert_eq!(add(a, a).0, y);
+
+    let b = B(x);
+    assert_eq!(add(b, b).0, y);
+
+    let c = C(x);
+    assert_eq!(add(c, c).0, y);
+}
diff --git a/src/test/ui/simd/intrinsic/float-math-pass.rs b/src/test/ui/simd/intrinsic/float-math-pass.rs
new file mode 100644 (file)
index 0000000..7a4f746
--- /dev/null
@@ -0,0 +1,114 @@
+// run-pass
+// ignore-emscripten
+// ignore-android
+
+// FIXME: this test fails on arm-android because the NDK version 14 is too old.
+// It needs at least version 18. We disable it on all android build bots because
+// there is no way in compile-test to disable it for an (arch,os) pair.
+
+// Test that the simd floating-point math intrinsics produce correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_fsqrt<T>(x: T) -> T;
+    fn simd_fabs<T>(x: T) -> T;
+    fn simd_fsin<T>(x: T) -> T;
+    fn simd_fcos<T>(x: T) -> T;
+    fn simd_fexp<T>(x: T) -> T;
+    fn simd_fexp2<T>(x: T) -> T;
+    fn simd_fma<T>(x: T, y: T, z: T) -> T;
+    fn simd_flog<T>(x: T) -> T;
+    fn simd_flog10<T>(x: T) -> T;
+    fn simd_flog2<T>(x: T) -> T;
+    fn simd_fpow<T>(x: T, y: T) -> T;
+    fn simd_fpowi<T>(x: T, y: i32) -> T;
+
+    // rounding functions
+    fn simd_ceil<T>(x: T) -> T;
+    fn simd_floor<T>(x: T) -> T;
+    fn simd_round<T>(x: T) -> T;
+    fn simd_trunc<T>(x: T) -> T;
+}
+
+macro_rules! assert_approx_eq_f32 {
+    ($a:expr, $b:expr) => ({
+        let (a, b) = (&$a, &$b);
+        assert!((*a - *b).abs() < 1.0e-6,
+                "{} is not approximately equal to {}", *a, *b);
+    })
+}
+macro_rules! assert_approx_eq {
+    ($a:expr, $b:expr) => ({
+        let a = $a;
+        let b = $b;
+        assert_approx_eq_f32!(a.0, b.0);
+        assert_approx_eq_f32!(a.1, b.1);
+        assert_approx_eq_f32!(a.2, b.2);
+        assert_approx_eq_f32!(a.3, b.3);
+    })
+}
+
+fn main() {
+    let x = f32x4(1.0, 1.0, 1.0, 1.0);
+    let y = f32x4(-1.0, -1.0, -1.0, -1.0);
+    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+
+    let h = f32x4(0.5, 0.5, 0.5, 0.5);
+
+    unsafe {
+        let r = simd_fabs(y);
+        assert_approx_eq!(x, r);
+
+        let r = simd_fcos(z);
+        assert_approx_eq!(x, r);
+
+        let r = simd_fexp(z);
+        assert_approx_eq!(x, r);
+
+        let r = simd_fexp2(z);
+        assert_approx_eq!(x, r);
+
+        let r = simd_fma(x, h, h);
+        assert_approx_eq!(x, r);
+
+        let r = simd_fsqrt(x);
+        assert_approx_eq!(x, r);
+
+        let r = simd_flog(x);
+        assert_approx_eq!(z, r);
+
+        let r = simd_flog2(x);
+        assert_approx_eq!(z, r);
+
+        let r = simd_flog10(x);
+        assert_approx_eq!(z, r);
+
+        let r = simd_fpow(h, x);
+        assert_approx_eq!(h, r);
+
+        let r = simd_fpowi(h, 1);
+        assert_approx_eq!(h, r);
+
+        let r = simd_fsin(z);
+        assert_approx_eq!(z, r);
+
+        // rounding functions
+        let r = simd_floor(h);
+        assert_eq!(z, r);
+
+        let r = simd_ceil(h);
+        assert_eq!(x, r);
+
+        let r = simd_round(h);
+        assert_eq!(x, r);
+
+        let r = simd_trunc(h);
+        assert_eq!(z, r);
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/float-minmax-pass.rs b/src/test/ui/simd/intrinsic/float-minmax-pass.rs
new file mode 100644 (file)
index 0000000..d79be61
--- /dev/null
@@ -0,0 +1,52 @@
+// run-pass
+// ignore-emscripten
+
+// Test that the simd_f{min,max} intrinsics produce the correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_fmin<T>(x: T, y: T) -> T;
+    fn simd_fmax<T>(x: T, y: T) -> T;
+}
+
+fn main() {
+    let x = f32x4(1.0, 2.0, 3.0, 4.0);
+    let y = f32x4(2.0, 1.0, 4.0, 3.0);
+
+    #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
+    let nan = f32::NAN;
+    // MIPS hardware treats f32::NAN as SNAN. Clear the signaling bit.
+    // See https://github.com/rust-lang/rust/issues/52746.
+    #[cfg(any(target_arch = "mips", target_arch = "mips64"))]
+    let nan = f32::from_bits(f32::NAN.to_bits() - 1);
+
+    let n = f32x4(nan, nan, nan, nan);
+
+    unsafe {
+        let min0 = simd_fmin(x, y);
+        let min1 = simd_fmin(y, x);
+        assert_eq!(min0, min1);
+        let e = f32x4(1.0, 1.0, 3.0, 3.0);
+        assert_eq!(min0, e);
+        let minn = simd_fmin(x, n);
+        assert_eq!(minn, x);
+        let minn = simd_fmin(y, n);
+        assert_eq!(minn, y);
+
+        let max0 = simd_fmax(x, y);
+        let max1 = simd_fmax(y, x);
+        assert_eq!(max0, max1);
+        let e = f32x4(2.0, 2.0, 4.0, 4.0);
+        assert_eq!(max0, e);
+        let maxn = simd_fmax(x, n);
+        assert_eq!(maxn, x);
+        let maxn = simd_fmax(y, n);
+        assert_eq!(maxn, y);
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-arithmetic-2.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-2.rs
new file mode 100644 (file)
index 0000000..3576eed
--- /dev/null
@@ -0,0 +1,103 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_add<T>(x: T, y: T) -> T;
+    fn simd_sub<T>(x: T, y: T) -> T;
+    fn simd_mul<T>(x: T, y: T) -> T;
+    fn simd_div<T>(x: T, y: T) -> T;
+    fn simd_rem<T>(x: T, y: T) -> T;
+    fn simd_shl<T>(x: T, y: T) -> T;
+    fn simd_shr<T>(x: T, y: T) -> T;
+    fn simd_and<T>(x: T, y: T) -> T;
+    fn simd_or<T>(x: T, y: T) -> T;
+    fn simd_xor<T>(x: T, y: T) -> T;
+
+    fn simd_neg<T>(x: T) -> T;
+}
+
+fn main() {
+    let x = i32x4(0, 0, 0, 0);
+    let y = u32x4(0, 0, 0, 0);
+    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+
+    unsafe {
+        simd_add(x, x);
+        simd_add(y, y);
+        simd_add(z, z);
+        simd_sub(x, x);
+        simd_sub(y, y);
+        simd_sub(z, z);
+        simd_mul(x, x);
+        simd_mul(y, y);
+        simd_mul(z, z);
+        simd_div(x, x);
+        simd_div(y, y);
+        simd_div(z, z);
+        simd_rem(x, x);
+        simd_rem(y, y);
+        simd_rem(z, z);
+
+        simd_shl(x, x);
+        simd_shl(y, y);
+        simd_shr(x, x);
+        simd_shr(y, y);
+        simd_and(x, x);
+        simd_and(y, y);
+        simd_or(x, x);
+        simd_or(y, y);
+        simd_xor(x, x);
+        simd_xor(y, y);
+
+        simd_neg(x);
+        simd_neg(z);
+
+
+        simd_add(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_sub(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_mul(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_div(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_shl(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_shr(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_and(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_or(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_xor(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+
+        simd_neg(0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+
+
+        simd_shl(z, z);
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
+        simd_shr(z, z);
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
+        simd_and(z, z);
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
+        simd_or(z, z);
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
+        simd_xor(z, z);
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-arithmetic-2.stderr b/src/test/ui/simd/intrinsic/generic-arithmetic-2.stderr
new file mode 100644 (file)
index 0000000..0f0a7ea
--- /dev/null
@@ -0,0 +1,93 @@
+error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:69:9
+   |
+LL |         simd_add(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:71:9
+   |
+LL |         simd_sub(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:73:9
+   |
+LL |         simd_mul(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:75:9
+   |
+LL |         simd_div(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:77:9
+   |
+LL |         simd_shl(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:79:9
+   |
+LL |         simd_shr(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:81:9
+   |
+LL |         simd_and(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:83:9
+   |
+LL |         simd_or(0, 0);
+   |         ^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:85:9
+   |
+LL |         simd_xor(0, 0);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:88:9
+   |
+LL |         simd_neg(0);
+   |         ^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:92:9
+   |
+LL |         simd_shl(z, z);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:94:9
+   |
+LL |         simd_shr(z, z);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:96:9
+   |
+LL |         simd_and(z, z);
+   |         ^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:98:9
+   |
+LL |         simd_or(z, z);
+   |         ^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:100:9
+   |
+LL |         simd_xor(z, z);
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 15 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
new file mode 100644 (file)
index 0000000..c507b8d
--- /dev/null
@@ -0,0 +1,136 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct U32<const N: usize>([u32; N]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+macro_rules! all_eq {
+    ($a: expr, $b: expr) => {{
+        let a = $a;
+        let b = $b;
+        assert!(a.0 == b.0 && a.1 == b.1 && a.2 == b.2 && a.3 == b.3);
+    }}
+}
+
+macro_rules! all_eq_ {
+    ($a: expr, $b: expr) => {{
+        let a = $a;
+        let b = $b;
+        assert!(a.0 == b.0);
+    }}
+}
+
+
+extern "platform-intrinsic" {
+    fn simd_add<T>(x: T, y: T) -> T;
+    fn simd_sub<T>(x: T, y: T) -> T;
+    fn simd_mul<T>(x: T, y: T) -> T;
+    fn simd_div<T>(x: T, y: T) -> T;
+    fn simd_rem<T>(x: T, y: T) -> T;
+    fn simd_shl<T>(x: T, y: T) -> T;
+    fn simd_shr<T>(x: T, y: T) -> T;
+    fn simd_and<T>(x: T, y: T) -> T;
+    fn simd_or<T>(x: T, y: T) -> T;
+    fn simd_xor<T>(x: T, y: T) -> T;
+
+    fn simd_neg<T>(x: T) -> T;
+}
+
+fn main() {
+    let x1 = i32x4(1, 2, 3, 4);
+    let y1 = U32::<4>([1, 2, 3, 4]);
+    let z1 = f32x4(1.0, 2.0, 3.0, 4.0);
+    let x2 = i32x4(2, 3, 4, 5);
+    let y2 = U32::<4>([2, 3, 4, 5]);
+    let z2 = f32x4(2.0, 3.0, 4.0, 5.0);
+
+    unsafe {
+        all_eq!(simd_add(x1, x2), i32x4(3, 5, 7, 9));
+        all_eq!(simd_add(x2, x1), i32x4(3, 5, 7, 9));
+        all_eq_!(simd_add(y1, y2), U32::<4>([3, 5, 7, 9]));
+        all_eq_!(simd_add(y2, y1), U32::<4>([3, 5, 7, 9]));
+        all_eq!(simd_add(z1, z2), f32x4(3.0, 5.0, 7.0, 9.0));
+        all_eq!(simd_add(z2, z1), f32x4(3.0, 5.0, 7.0, 9.0));
+
+        all_eq!(simd_mul(x1, x2), i32x4(2, 6, 12, 20));
+        all_eq!(simd_mul(x2, x1), i32x4(2, 6, 12, 20));
+        all_eq_!(simd_mul(y1, y2), U32::<4>([2, 6, 12, 20]));
+        all_eq_!(simd_mul(y2, y1), U32::<4>([2, 6, 12, 20]));
+        all_eq!(simd_mul(z1, z2), f32x4(2.0, 6.0, 12.0, 20.0));
+        all_eq!(simd_mul(z2, z1), f32x4(2.0, 6.0, 12.0, 20.0));
+
+        all_eq!(simd_sub(x2, x1), i32x4(1, 1, 1, 1));
+        all_eq!(simd_sub(x1, x2), i32x4(-1, -1, -1, -1));
+        all_eq_!(simd_sub(y2, y1), U32::<4>([1, 1, 1, 1]));
+        all_eq_!(simd_sub(y1, y2), U32::<4>([!0, !0, !0, !0]));
+        all_eq!(simd_sub(z2, z1), f32x4(1.0, 1.0, 1.0, 1.0));
+        all_eq!(simd_sub(z1, z2), f32x4(-1.0, -1.0, -1.0, -1.0));
+
+        all_eq!(simd_div(x1, x1), i32x4(1, 1, 1, 1));
+        all_eq!(simd_div(i32x4(2, 4, 6, 8), i32x4(2, 2, 2, 2)), x1);
+        all_eq_!(simd_div(y1, y1), U32::<4>([1, 1, 1, 1]));
+        all_eq_!(simd_div(U32::<4>([2, 4, 6, 8]), U32::<4>([2, 2, 2, 2])), y1);
+        all_eq!(simd_div(z1, z1), f32x4(1.0, 1.0, 1.0, 1.0));
+        all_eq!(simd_div(z1, z2), f32x4(1.0/2.0, 2.0/3.0, 3.0/4.0, 4.0/5.0));
+        all_eq!(simd_div(z2, z1), f32x4(2.0/1.0, 3.0/2.0, 4.0/3.0, 5.0/4.0));
+
+        all_eq!(simd_rem(x1, x1), i32x4(0, 0, 0, 0));
+        all_eq!(simd_rem(x2, x1), i32x4(0, 1, 1, 1));
+        all_eq_!(simd_rem(y1, y1), U32::<4>([0, 0, 0, 0]));
+        all_eq_!(simd_rem(y2, y1), U32::<4>([0, 1, 1, 1]));
+        all_eq!(simd_rem(z1, z1), f32x4(0.0, 0.0, 0.0, 0.0));
+        all_eq!(simd_rem(z1, z2), z1);
+        all_eq!(simd_rem(z2, z1), f32x4(0.0, 1.0, 1.0, 1.0));
+
+        all_eq!(simd_shl(x1, x2), i32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5));
+        all_eq!(simd_shl(x2, x1), i32x4(2 << 1, 3 << 2, 4 << 3, 5 << 4));
+        all_eq_!(simd_shl(y1, y2), U32::<4>([1 << 2, 2 << 3, 3 << 4, 4 << 5]));
+        all_eq_!(simd_shl(y2, y1), U32::<4>([2 << 1, 3 << 2, 4 << 3, 5 << 4]));
+
+        // test right-shift by assuming left-shift is correct
+        all_eq!(simd_shr(simd_shl(x1, x2), x2), x1);
+        all_eq!(simd_shr(simd_shl(x2, x1), x1), x2);
+        all_eq_!(simd_shr(simd_shl(y1, y2), y2), y1);
+        all_eq_!(simd_shr(simd_shl(y2, y1), y1), y2);
+
+        // ensure we get logical vs. arithmetic shifts correct
+        let (a, b, c, d) = (-12, -123, -1234, -12345);
+        all_eq!(simd_shr(i32x4(a, b, c, d), x1), i32x4(a >> 1, b >> 2, c >> 3, d >> 4));
+        all_eq_!(simd_shr(U32::<4>([a as u32, b as u32, c as u32, d as u32]), y1),
+                U32::<4>([(a as u32) >> 1, (b as u32) >> 2, (c as u32) >> 3, (d as u32) >> 4]));
+
+        all_eq!(simd_and(x1, x2), i32x4(0, 2, 0, 4));
+        all_eq!(simd_and(x2, x1), i32x4(0, 2, 0, 4));
+        all_eq_!(simd_and(y1, y2), U32::<4>([0, 2, 0, 4]));
+        all_eq_!(simd_and(y2, y1), U32::<4>([0, 2, 0, 4]));
+
+        all_eq!(simd_or(x1, x2), i32x4(3, 3, 7, 5));
+        all_eq!(simd_or(x2, x1), i32x4(3, 3, 7, 5));
+        all_eq_!(simd_or(y1, y2), U32::<4>([3, 3, 7, 5]));
+        all_eq_!(simd_or(y2, y1), U32::<4>([3, 3, 7, 5]));
+
+        all_eq!(simd_xor(x1, x2), i32x4(3, 1, 7, 1));
+        all_eq!(simd_xor(x2, x1), i32x4(3, 1, 7, 1));
+        all_eq_!(simd_xor(y1, y2), U32::<4>([3, 1, 7, 1]));
+        all_eq_!(simd_xor(y2, y1), U32::<4>([3, 1, 7, 1]));
+
+        all_eq!(simd_neg(x1), i32x4(-1, -2, -3, -4));
+        all_eq!(simd_neg(x2), i32x4(-2, -3, -4, -5));
+        all_eq!(simd_neg(z1), f32x4(-1.0, -2.0, -3.0, -4.0));
+        all_eq!(simd_neg(z2), f32x4(-2.0, -3.0, -4.0, -5.0));
+
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
new file mode 100644 (file)
index 0000000..9736d1b
--- /dev/null
@@ -0,0 +1,38 @@
+// build-fail
+// ignore-emscripten
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct x4<T>(pub T, pub T, pub T, pub T);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_saturating_add<T>(x: T, y: T) -> T;
+    fn simd_saturating_sub<T>(x: T, y: T) -> T;
+}
+
+fn main() {
+    let x = i32x4(0, 0, 0, 0);
+    let y = x4(0_usize, 0, 0, 0);
+    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+
+    unsafe {
+        simd_saturating_add(x, x);
+        simd_saturating_add(y, y);
+        simd_saturating_sub(x, x);
+        simd_saturating_sub(y, y);
+
+        simd_saturating_add(z, z);
+        //~^ ERROR expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
+        simd_saturating_sub(z, z);
+        //~^ ERROR expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr
new file mode 100644 (file)
index 0000000..f349cb5
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0511]: invalid monomorphization of `simd_saturating_add` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
+  --> $DIR/generic-arithmetic-saturating-2.rs:33:9
+   |
+LL |         simd_saturating_add(z, z);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_saturating_sub` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
+  --> $DIR/generic-arithmetic-saturating-2.rs:35:9
+   |
+LL |         simd_saturating_sub(z, z);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
new file mode 100644 (file)
index 0000000..c11d14b
--- /dev/null
@@ -0,0 +1,91 @@
+// run-pass
+// ignore-emscripten
+
+#![allow(non_camel_case_types)]
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct I32<const N: usize>([i32; N]);
+
+extern "platform-intrinsic" {
+    fn simd_saturating_add<T>(x: T, y: T) -> T;
+    fn simd_saturating_sub<T>(x: T, y: T) -> T;
+}
+
+fn main() {
+    // unsigned
+    {
+        const M: u32 = u32::MAX;
+
+        let a = u32x4(1, 2, 3, 4);
+        let b = u32x4(2, 4, 6, 8);
+        let m = u32x4(M, M, M, M);
+        let m1 = u32x4(M - 1, M - 1, M - 1, M - 1);
+        let z = u32x4(0, 0, 0, 0);
+
+        unsafe {
+            assert_eq!(simd_saturating_add(z, z), z);
+            assert_eq!(simd_saturating_add(z, a), a);
+            assert_eq!(simd_saturating_add(b, z), b);
+            assert_eq!(simd_saturating_add(a, a), b);
+            assert_eq!(simd_saturating_add(a, m), m);
+            assert_eq!(simd_saturating_add(m, b), m);
+            assert_eq!(simd_saturating_add(m1, a), m);
+
+            assert_eq!(simd_saturating_sub(b, z), b);
+            assert_eq!(simd_saturating_sub(b, a), a);
+            assert_eq!(simd_saturating_sub(a, a), z);
+            assert_eq!(simd_saturating_sub(a, b), z);
+            assert_eq!(simd_saturating_sub(a, m1), z);
+            assert_eq!(simd_saturating_sub(b, m1), z);
+        }
+    }
+
+    // signed
+    {
+        const MIN: i32 = i32::MIN;
+        const MAX: i32 = i32::MAX;
+
+        let a = I32::<4>([1, 2, 3, 4]);
+        let b = I32::<4>([2, 4, 6, 8]);
+        let c = I32::<4>([-1, -2, -3, -4]);
+        let d = I32::<4>([-2, -4, -6, -8]);
+
+        let max = I32::<4>([MAX, MAX, MAX, MAX]);
+        let max1 = I32::<4>([MAX - 1, MAX - 1, MAX - 1, MAX - 1]);
+        let min = I32::<4>([MIN, MIN, MIN, MIN]);
+        let min1 = I32::<4>([MIN + 1, MIN + 1, MIN + 1, MIN + 1]);
+
+        let z = I32::<4>([0, 0, 0, 0]);
+
+        unsafe {
+            assert_eq!(simd_saturating_add(z, z).0, z.0);
+            assert_eq!(simd_saturating_add(z, a).0, a.0);
+            assert_eq!(simd_saturating_add(b, z).0, b.0);
+            assert_eq!(simd_saturating_add(a, a).0, b.0);
+            assert_eq!(simd_saturating_add(a, max).0, max.0);
+            assert_eq!(simd_saturating_add(max, b).0, max.0);
+            assert_eq!(simd_saturating_add(max1, a).0, max.0);
+            assert_eq!(simd_saturating_add(min1, z).0, min1.0);
+            assert_eq!(simd_saturating_add(min, z).0, min.0);
+            assert_eq!(simd_saturating_add(min1, c).0, min.0);
+            assert_eq!(simd_saturating_add(min, c).0, min.0);
+            assert_eq!(simd_saturating_add(min1, d).0, min.0);
+            assert_eq!(simd_saturating_add(min, d).0, min.0);
+
+            assert_eq!(simd_saturating_sub(b, z).0, b.0);
+            assert_eq!(simd_saturating_sub(b, a).0, a.0);
+            assert_eq!(simd_saturating_sub(a, a).0, z.0);
+            assert_eq!(simd_saturating_sub(a, b).0, c.0);
+            assert_eq!(simd_saturating_sub(z, max).0, min1.0);
+            assert_eq!(simd_saturating_sub(min1, z).0, min1.0);
+            assert_eq!(simd_saturating_sub(min1, a).0, min.0);
+            assert_eq!(simd_saturating_sub(min1, b).0, min.0);
+        }
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-bitmask-pass.rs b/src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
new file mode 100644 (file)
index 0000000..8c43684
--- /dev/null
@@ -0,0 +1,62 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+// ignore-emscripten
+// ignore-endian-big behavior of simd_bitmask is endian-specific
+
+// Test that the simd_bitmask intrinsic produces correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct u8x4(pub u8, pub u8, pub u8, pub u8);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct Tx4<T>(pub T, pub T, pub T, pub T);
+
+extern "platform-intrinsic" {
+    fn simd_bitmask<T, U>(x: T) -> U;
+}
+
+fn main() {
+    let z = u32x4(0, 0, 0, 0);
+    let ez = 0_u8;
+
+    let o = u32x4(!0, !0, !0, !0);
+    let eo = 0b_1111_u8;
+
+    let m0 = u32x4(!0, 0, !0, 0);
+    let e0 = 0b_0000_0101_u8;
+
+    // Check that the MSB is extracted:
+    let m = u8x4(0b_1000_0000, 0b_0100_0001, 0b_1100_0001, 0b_1111_1111);
+    let e = 0b_1101;
+
+    // Check usize / isize
+    let msize: Tx4<usize> = Tx4(usize::MAX, 0, usize::MAX, usize::MAX);
+
+    unsafe {
+        let r: u8 = simd_bitmask(z);
+        assert_eq!(r, ez);
+
+        let r: u8 = simd_bitmask(o);
+        assert_eq!(r, eo);
+
+        let r: u8 = simd_bitmask(m0);
+        assert_eq!(r, e0);
+
+        let r: u8 = simd_bitmask(m);
+        assert_eq!(r, e);
+
+        let r: u8 = simd_bitmask(msize);
+        assert_eq!(r, e);
+
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-bitmask.rs b/src/test/ui/simd/intrinsic/generic-bitmask.rs
new file mode 100644 (file)
index 0000000..92c4e67
--- /dev/null
@@ -0,0 +1,69 @@
+// build-fail
+
+// Test that the simd_bitmask intrinsic produces ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x2([u32; 2]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x4([u32; 4]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x8([u8; 8]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x16([u8; 16]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x32([u8; 32]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x64([u8; 64]);
+
+extern "platform-intrinsic" {
+    fn simd_bitmask<T, U>(x: T) -> U;
+}
+
+fn main() {
+    let m2 = u32x2([0; 2]);
+    let m4 = u32x4([0; 4]);
+    let m8 = u8x8([0; 8]);
+    let m16 = u8x16([0; 16]);
+    let m32 = u8x32([0; 32]);
+    let m64 = u8x64([0; 64]);
+
+    unsafe {
+        let _: u8 = simd_bitmask(m2);
+        let _: u8 = simd_bitmask(m4);
+        let _: u8 = simd_bitmask(m8);
+        let _: u16 = simd_bitmask(m16);
+        let _: u32 = simd_bitmask(m32);
+        let _: u64 = simd_bitmask(m64);
+
+        let _: u16 = simd_bitmask(m2);
+        //~^ ERROR bitmask `u16`, expected `u8`
+
+        let _: u16 = simd_bitmask(m8);
+        //~^ ERROR bitmask `u16`, expected `u8`
+
+        let _: u32 = simd_bitmask(m16);
+        //~^ ERROR bitmask `u32`, expected `u16`
+
+        let _: u64 = simd_bitmask(m32);
+        //~^ ERROR bitmask `u64`, expected `u32`
+
+        let _: u128 = simd_bitmask(m64);
+        //~^ ERROR bitmask `u128`, expected `u64`
+
+   }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-bitmask.stderr b/src/test/ui/simd/intrinsic/generic-bitmask.stderr
new file mode 100644 (file)
index 0000000..5aaae68
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8`
+  --> $DIR/generic-bitmask.rs:53:22
+   |
+LL |         let _: u16 = simd_bitmask(m2);
+   |                      ^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8`
+  --> $DIR/generic-bitmask.rs:56:22
+   |
+LL |         let _: u16 = simd_bitmask(m8);
+   |                      ^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u32`, expected `u16`
+  --> $DIR/generic-bitmask.rs:59:22
+   |
+LL |         let _: u32 = simd_bitmask(m16);
+   |                      ^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u64`, expected `u32`
+  --> $DIR/generic-bitmask.rs:62:22
+   |
+LL |         let _: u64 = simd_bitmask(m32);
+   |                      ^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u128`, expected `u64`
+  --> $DIR/generic-bitmask.rs:65:23
+   |
+LL |         let _: u128 = simd_bitmask(m64);
+   |                       ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-cast-pass.rs b/src/test/ui/simd/intrinsic/generic-cast-pass.rs
new file mode 100644 (file)
index 0000000..15f232e
--- /dev/null
@@ -0,0 +1,121 @@
+// run-pass
+#![allow(unused_must_use)]
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+
+#![feature(repr_simd, platform_intrinsics, concat_idents, test)]
+#![allow(non_camel_case_types)]
+
+extern crate test;
+
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct i8x4(i8, i8, i8, i8);
+
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct u32x4(u32, u32, u32, u32);
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct u8x4(u8, u8, u8, u8);
+
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct f32x4(f32, f32, f32, f32);
+
+#[repr(simd)]
+#[derive(PartialEq, Debug)]
+struct f64x4(f64, f64, f64, f64);
+
+
+extern "platform-intrinsic" {
+    fn simd_cast<T, U>(x: T) -> U;
+}
+
+const A: i32 = -1234567;
+const B: i32 = 12345678;
+const C: i32 = -123456789;
+const D: i32 = 1234567890;
+
+trait Foo {
+    fn is_float() -> bool { false }
+    fn in_range(x: i32) -> bool;
+}
+impl Foo for i32 {
+    fn in_range(_: i32) -> bool { true }
+}
+impl Foo for i8 {
+    fn in_range(x: i32) -> bool { -128 <= x && x < 128 }
+}
+impl Foo for u32 {
+    fn in_range(x: i32) -> bool { 0 <= x }
+}
+impl Foo for u8 {
+    fn in_range(x: i32) -> bool { 0 <= x && x < 128 }
+}
+impl Foo for f32 {
+    fn is_float() -> bool { true }
+    fn in_range(_: i32) -> bool { true }
+}
+impl Foo for f64 {
+    fn is_float() -> bool { true }
+    fn in_range(_: i32) -> bool { true }
+}
+
+fn main() {
+    macro_rules! test {
+        ($from: ident, $to: ident) => {{
+            // force the casts to actually happen, or else LLVM/rustc
+            // may fold them and get slightly different results.
+            let (a, b, c, d) = test::black_box((A as $from, B as $from, C as $from, D as $from));
+            // the SIMD vectors are all FOOx4, so we can concat_idents
+            // so we don't have to pass in the extra args to the macro
+            let mut from = simd_cast(concat_idents!($from, x4)(a, b, c, d));
+            let mut to = concat_idents!($to, x4)(a as $to,
+                                                 b as $to,
+                                                 c as $to,
+                                                 d as $to);
+            // assist type inference, it needs to know what `from` is
+            // for the `if` statements.
+            to == from;
+
+            // there are platform differences for some out of range
+            // casts, so we just normalize such things: it's OK for
+            // "invalid" calculations to result in nonsense answers.
+            // (e.g., negative float to unsigned integer goes through a
+            // library routine on the default i686 platforms, and the
+            // implementation of that routine differs on e.g., Linux
+            // vs. macOS, resulting in different answers.)
+            if $from::is_float() {
+                if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; }
+                if !$to::in_range(B) { from.1 = 0 as $to; to.1 = 0 as $to; }
+                if !$to::in_range(C) { from.2 = 0 as $to; to.2 = 0 as $to; }
+                if !$to::in_range(D) { from.3 = 0 as $to; to.3 = 0 as $to; }
+            }
+
+            assert!(to == from,
+                    "{} -> {} ({:?} != {:?})", stringify!($from), stringify!($to),
+                    from, to);
+        }}
+    }
+    macro_rules! tests {
+        (: $($to: ident),*) => { () };
+        // repeating the list twice is easier than writing a cartesian
+        // product macro
+        ($from: ident $(, $from_: ident)*: $($to: ident),*) => {
+            fn $from() { unsafe { $( test!($from, $to); )* } }
+            tests!($($from_),*: $($to),*)
+        };
+        ($($types: ident),*) => {{
+            tests!($($types),* : $($types),*);
+            $($types();)*
+        }}
+    }
+
+    // test various combinations, including truncation,
+    // signed/unsigned extension, and floating point casts.
+    tests!(i32, i8, u32, u8, f32);
+    tests!(i32, u32, f32, f64)
+}
diff --git a/src/test/ui/simd/intrinsic/generic-cast.rs b/src/test/ui/simd/intrinsic/generic-cast.rs
new file mode 100644 (file)
index 0000000..4f4fa06
--- /dev/null
@@ -0,0 +1,43 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i32x8(i32, i32, i32, i32,
+             i32, i32, i32, i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct f32x4(f32, f32, f32, f32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct f32x8(f32, f32, f32, f32,
+             f32, f32, f32, f32);
+
+
+extern "platform-intrinsic" {
+    fn simd_cast<T, U>(x: T) -> U;
+}
+
+fn main() {
+    let x = i32x4(0, 0, 0, 0);
+
+    unsafe {
+        simd_cast::<i32, i32>(0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_cast::<i32, i32x4>(0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_cast::<i32x4, i32>(x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+        simd_cast::<_, i32x8>(x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-cast.stderr b/src/test/ui/simd/intrinsic/generic-cast.stderr
new file mode 100644 (file)
index 0000000..2226bbb
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-cast.rs:34:9
+   |
+LL |         simd_cast::<i32, i32>(0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-cast.rs:36:9
+   |
+LL |         simd_cast::<i32, i32x4>(0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-cast.rs:38:9
+   |
+LL |         simd_cast::<i32x4, i32>(x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
+  --> $DIR/generic-cast.rs:40:9
+   |
+LL |         simd_cast::<_, i32x8>(x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-comparison-pass.rs b/src/test/ui/simd/intrinsic/generic-comparison-pass.rs
new file mode 100644 (file)
index 0000000..da5c42a
--- /dev/null
@@ -0,0 +1,106 @@
+// run-pass
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+// revisions: mir thir
+// [thir]compile-flags: -Zthir-unsafeck
+
+#![feature(repr_simd, platform_intrinsics, concat_idents)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u32x4(pub u32, pub u32, pub u32, pub u32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_eq<T, U>(x: T, y: T) -> U;
+    fn simd_ne<T, U>(x: T, y: T) -> U;
+    fn simd_lt<T, U>(x: T, y: T) -> U;
+    fn simd_le<T, U>(x: T, y: T) -> U;
+    fn simd_gt<T, U>(x: T, y: T) -> U;
+    fn simd_ge<T, U>(x: T, y: T) -> U;
+}
+
+macro_rules! cmp {
+    ($method: ident($lhs: expr, $rhs: expr)) => {{
+        let lhs = $lhs;
+        let rhs = $rhs;
+        let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs);
+        // assume the scalar version is correct/the behaviour we want.
+        assert!((e.0 != 0) == lhs.0 .$method(&rhs.0));
+        assert!((e.1 != 0) == lhs.1 .$method(&rhs.1));
+        assert!((e.2 != 0) == lhs.2 .$method(&rhs.2));
+        assert!((e.3 != 0) == lhs.3 .$method(&rhs.3));
+    }}
+}
+macro_rules! tests {
+    ($($lhs: ident, $rhs: ident;)*) => {{
+        $(
+            (|| {
+                cmp!(eq($lhs, $rhs));
+                cmp!(ne($lhs, $rhs));
+
+                // test both directions
+                cmp!(lt($lhs, $rhs));
+                cmp!(lt($rhs, $lhs));
+
+                cmp!(le($lhs, $rhs));
+                cmp!(le($rhs, $lhs));
+
+                cmp!(gt($lhs, $rhs));
+                cmp!(gt($rhs, $lhs));
+
+                cmp!(ge($lhs, $rhs));
+                cmp!(ge($rhs, $lhs));
+            })();
+            )*
+    }}
+}
+fn main() {
+    // 13 vs. -100 tests that we get signed vs. unsigned comparisons
+    // correct (i32: 13 > -100, u32: 13 < -100).    let i1 = i32x4(10, -11, 12, 13);
+    let i1 = i32x4(10, -11, 12, 13);
+    let i2 = i32x4(5, -5, 20, -100);
+    let i3 = i32x4(10, -11, 20, -100);
+
+    let u1 = u32x4(10, !11+1, 12, 13);
+    let u2 = u32x4(5, !5+1, 20, !100+1);
+    let u3 = u32x4(10, !11+1, 20, !100+1);
+
+    let f1 = f32x4(10.0, -11.0, 12.0, 13.0);
+    let f2 = f32x4(5.0, -5.0, 20.0, -100.0);
+    let f3 = f32x4(10.0, -11.0, 20.0, -100.0);
+
+    unsafe {
+        tests! {
+            i1, i1;
+            u1, u1;
+            f1, f1;
+
+            i1, i2;
+            u1, u2;
+            f1, f2;
+
+            i1, i3;
+            u1, u3;
+            f1, f3;
+        }
+    }
+
+    // NAN comparisons are special:
+    // -11 (*)    13
+    // -5        -100 (*)
+    let f4 = f32x4(f32::NAN, f1.1, f32::NAN, f2.3);
+
+    unsafe {
+        tests! {
+            f1, f4;
+            f2, f4;
+            f4, f4;
+        }
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-comparison.rs b/src/test/ui/simd/intrinsic/generic-comparison.rs
new file mode 100644 (file)
index 0000000..3cd3804
--- /dev/null
@@ -0,0 +1,67 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i16x8(i16, i16, i16, i16,
+             i16, i16, i16, i16);
+
+extern "platform-intrinsic" {
+    fn simd_eq<T, U>(x: T, y: T) -> U;
+    fn simd_ne<T, U>(x: T, y: T) -> U;
+    fn simd_lt<T, U>(x: T, y: T) -> U;
+    fn simd_le<T, U>(x: T, y: T) -> U;
+    fn simd_gt<T, U>(x: T, y: T) -> U;
+    fn simd_ge<T, U>(x: T, y: T) -> U;
+}
+
+fn main() {
+    let x = i32x4(0, 0, 0, 0);
+
+    unsafe {
+        simd_eq::<i32, i32>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_ne::<i32, i32>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_lt::<i32, i32>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_le::<i32, i32>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_gt::<i32, i32>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_ge::<i32, i32>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+
+        simd_eq::<_, i32>(x, x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+        simd_ne::<_, i32>(x, x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+        simd_lt::<_, i32>(x, x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+        simd_le::<_, i32>(x, x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+        simd_gt::<_, i32>(x, x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+        simd_ge::<_, i32>(x, x);
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
+
+        simd_eq::<_, i16x8>(x, x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+        simd_ne::<_, i16x8>(x, x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+        simd_lt::<_, i16x8>(x, x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+        simd_le::<_, i16x8>(x, x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+        simd_gt::<_, i16x8>(x, x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+        simd_ge::<_, i16x8>(x, x);
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-comparison.stderr b/src/test/ui/simd/intrinsic/generic-comparison.stderr
new file mode 100644 (file)
index 0000000..0eae268
--- /dev/null
@@ -0,0 +1,111 @@
+error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:28:9
+   |
+LL |         simd_eq::<i32, i32>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:30:9
+   |
+LL |         simd_ne::<i32, i32>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:32:9
+   |
+LL |         simd_lt::<i32, i32>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:34:9
+   |
+LL |         simd_le::<i32, i32>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:36:9
+   |
+LL |         simd_gt::<i32, i32>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:38:9
+   |
+LL |         simd_ge::<i32, i32>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:41:9
+   |
+LL |         simd_eq::<_, i32>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:43:9
+   |
+LL |         simd_ne::<_, i32>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:45:9
+   |
+LL |         simd_lt::<_, i32>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:47:9
+   |
+LL |         simd_le::<_, i32>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:49:9
+   |
+LL |         simd_gt::<_, i32>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD return type, found non-SIMD `i32`
+  --> $DIR/generic-comparison.rs:51:9
+   |
+LL |         simd_ge::<_, i32>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+  --> $DIR/generic-comparison.rs:54:9
+   |
+LL |         simd_eq::<_, i16x8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+  --> $DIR/generic-comparison.rs:56:9
+   |
+LL |         simd_ne::<_, i16x8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+  --> $DIR/generic-comparison.rs:58:9
+   |
+LL |         simd_lt::<_, i16x8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+  --> $DIR/generic-comparison.rs:60:9
+   |
+LL |         simd_le::<_, i16x8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+  --> $DIR/generic-comparison.rs:62:9
+   |
+LL |         simd_gt::<_, i16x8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
+  --> $DIR/generic-comparison.rs:64:9
+   |
+LL |         simd_ge::<_, i16x8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 18 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-elements-pass.rs b/src/test/ui/simd/intrinsic/generic-elements-pass.rs
new file mode 100644 (file)
index 0000000..08544bc
--- /dev/null
@@ -0,0 +1,103 @@
+// run-pass
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(incomplete_features)]
+#![feature(inline_const)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[allow(non_camel_case_types)]
+struct i32x2(i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[allow(non_camel_case_types)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[allow(non_camel_case_types)]
+struct i32x8(i32, i32, i32, i32,
+             i32, i32, i32, i32);
+
+extern "platform-intrinsic" {
+    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+    fn simd_extract<T, E>(x: T, idx: u32) -> E;
+
+    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
+    fn simd_shuffle4<T, U>(x: T, y: T, idx: [u32; 4]) -> U;
+    fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
+}
+
+macro_rules! all_eq {
+    ($a: expr, $b: expr) => {{
+        let a = $a;
+        let b = $b;
+        // type inference works better with the concrete type on the
+        // left, but humans work better with the expected on the
+        // right.
+        assert!(b == a,
+                "{:?} != {:?}", a, b);
+    }}
+}
+
+fn main() {
+    let x2 = i32x2(20, 21);
+    let x4 = i32x4(40, 41, 42, 43);
+    let x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87);
+    unsafe {
+        all_eq!(simd_insert(x2, 0, 100), i32x2(100, 21));
+        all_eq!(simd_insert(x2, 1, 100), i32x2(20, 100));
+
+        all_eq!(simd_insert(x4, 0, 100), i32x4(100, 41, 42, 43));
+        all_eq!(simd_insert(x4, 1, 100), i32x4(40, 100, 42, 43));
+        all_eq!(simd_insert(x4, 2, 100), i32x4(40, 41, 100, 43));
+        all_eq!(simd_insert(x4, 3, 100), i32x4(40, 41, 42, 100));
+
+        all_eq!(simd_insert(x8, 0, 100), i32x8(100, 81, 82, 83, 84, 85, 86, 87));
+        all_eq!(simd_insert(x8, 1, 100), i32x8(80, 100, 82, 83, 84, 85, 86, 87));
+        all_eq!(simd_insert(x8, 2, 100), i32x8(80, 81, 100, 83, 84, 85, 86, 87));
+        all_eq!(simd_insert(x8, 3, 100), i32x8(80, 81, 82, 100, 84, 85, 86, 87));
+        all_eq!(simd_insert(x8, 4, 100), i32x8(80, 81, 82, 83, 100, 85, 86, 87));
+        all_eq!(simd_insert(x8, 5, 100), i32x8(80, 81, 82, 83, 84, 100, 86, 87));
+        all_eq!(simd_insert(x8, 6, 100), i32x8(80, 81, 82, 83, 84, 85, 100, 87));
+        all_eq!(simd_insert(x8, 7, 100), i32x8(80, 81, 82, 83, 84, 85, 86, 100));
+
+        all_eq!(simd_extract(x2, 0), 20);
+        all_eq!(simd_extract(x2, 1), 21);
+
+        all_eq!(simd_extract(x4, 0), 40);
+        all_eq!(simd_extract(x4, 1), 41);
+        all_eq!(simd_extract(x4, 2), 42);
+        all_eq!(simd_extract(x4, 3), 43);
+
+        all_eq!(simd_extract(x8, 0), 80);
+        all_eq!(simd_extract(x8, 1), 81);
+        all_eq!(simd_extract(x8, 2), 82);
+        all_eq!(simd_extract(x8, 3), 83);
+        all_eq!(simd_extract(x8, 4), 84);
+        all_eq!(simd_extract(x8, 5), 85);
+        all_eq!(simd_extract(x8, 6), 86);
+        all_eq!(simd_extract(x8, 7), 87);
+    }
+
+    let y2 = i32x2(120, 121);
+    let y4 = i32x4(140, 141, 142, 143);
+    let y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187);
+    unsafe {
+        all_eq!(simd_shuffle2(x2, y2, const { [3u32, 0] }), i32x2(121, 20));
+        all_eq!(simd_shuffle4(x2, y2, const { [3u32, 0, 1, 2] }), i32x4(121, 20, 21, 120));
+        all_eq!(simd_shuffle8(x2, y2, const { [3u32, 0, 1, 2, 1, 2, 3, 0] }),
+                i32x8(121, 20, 21, 120, 21, 120, 121, 20));
+
+        all_eq!(simd_shuffle2(x4, y4, const { [7u32, 2] }), i32x2(143, 42));
+        all_eq!(simd_shuffle4(x4, y4, const { [7u32, 2, 5, 0] }), i32x4(143, 42, 141, 40));
+        all_eq!(simd_shuffle8(x4, y4, const { [7u32, 2, 5, 0, 3, 6, 4, 1] }),
+                i32x8(143, 42, 141, 40, 43, 142, 140, 41));
+
+        all_eq!(simd_shuffle2(x8, y8, const { [11u32, 5] }), i32x2(183, 85));
+        all_eq!(simd_shuffle4(x8, y8, const { [11u32, 5, 15, 0] }), i32x4(183, 85, 187, 80));
+        all_eq!(simd_shuffle8(x8, y8, const { [11u32, 5, 15, 0, 3, 8, 12, 1] }),
+                i32x8(183, 85, 187, 80, 83, 180, 184, 81));
+    }
+
+}
diff --git a/src/test/ui/simd/intrinsic/generic-elements.rs b/src/test/ui/simd/intrinsic/generic-elements.rs
new file mode 100644 (file)
index 0000000..abde691
--- /dev/null
@@ -0,0 +1,77 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics, rustc_attrs)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i32x2(i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct i32x8(i32, i32, i32, i32,
+             i32, i32, i32, i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct f32x2(f32, f32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct f32x4(f32, f32, f32, f32);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct f32x8(f32, f32, f32, f32,
+             f32, f32, f32, f32);
+
+extern "platform-intrinsic" {
+    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+    fn simd_extract<T, E>(x: T, idx: u32) -> E;
+
+    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
+    fn simd_shuffle4<T, U>(x: T, y: T, idx: [u32; 4]) -> U;
+    fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
+}
+
+fn main() {
+    let x = i32x4(0, 0, 0, 0);
+
+    unsafe {
+        simd_insert(0, 0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_insert(x, 0, 1.0);
+        //~^ ERROR expected inserted type `i32` (element of input `i32x4`), found `f64`
+        simd_extract::<_, f32>(x, 0);
+        //~^ ERROR expected return type `i32` (element of input `i32x4`), found `f32`
+
+        const IDX2: [u32; 2] = [0; 2];
+        simd_shuffle2::<i32, i32>(0, 0, IDX2);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        const IDX4: [u32; 4] = [0; 4];
+        simd_shuffle4::<i32, i32>(0, 0, IDX4);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        const IDX8: [u32; 8] = [0; 8];
+        simd_shuffle8::<i32, i32>(0, 0, IDX8);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+
+        simd_shuffle2::<_, f32x2>(x, x, IDX2);
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
+        simd_shuffle4::<_, f32x4>(x, x, IDX4);
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
+        simd_shuffle8::<_, f32x8>(x, x, IDX8);
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
+
+        simd_shuffle2::<_, i32x8>(x, x, IDX2);
+        //~^ ERROR expected return type of length 2, found `i32x8` with length 8
+        simd_shuffle4::<_, i32x8>(x, x, IDX4);
+        //~^ ERROR expected return type of length 4, found `i32x8` with length 8
+        simd_shuffle8::<_, i32x2>(x, x, IDX8);
+        //~^ ERROR expected return type of length 8, found `i32x2` with length 2
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-elements.stderr b/src/test/ui/simd/intrinsic/generic-elements.stderr
new file mode 100644 (file)
index 0000000..5b423f7
--- /dev/null
@@ -0,0 +1,75 @@
+error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:46:9
+   |
+LL |         simd_insert(0, 0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
+  --> $DIR/generic-elements.rs:48:9
+   |
+LL |         simd_insert(x, 0, 1.0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
+  --> $DIR/generic-elements.rs:50:9
+   |
+LL |         simd_extract::<_, f32>(x, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:54:9
+   |
+LL |         simd_shuffle2::<i32, i32>(0, 0, IDX2);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:57:9
+   |
+LL |         simd_shuffle4::<i32, i32>(0, 0, IDX4);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:60:9
+   |
+LL |         simd_shuffle8::<i32, i32>(0, 0, IDX8);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
+  --> $DIR/generic-elements.rs:63:9
+   |
+LL |         simd_shuffle2::<_, f32x2>(x, x, IDX2);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
+  --> $DIR/generic-elements.rs:65:9
+   |
+LL |         simd_shuffle4::<_, f32x4>(x, x, IDX4);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
+  --> $DIR/generic-elements.rs:67:9
+   |
+LL |         simd_shuffle8::<_, f32x8>(x, x, IDX8);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected return type of length 2, found `i32x8` with length 8
+  --> $DIR/generic-elements.rs:70:9
+   |
+LL |         simd_shuffle2::<_, i32x8>(x, x, IDX2);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected return type of length 4, found `i32x8` with length 8
+  --> $DIR/generic-elements.rs:72:9
+   |
+LL |         simd_shuffle4::<_, i32x8>(x, x, IDX4);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected return type of length 8, found `i32x2` with length 2
+  --> $DIR/generic-elements.rs:74:9
+   |
+LL |         simd_shuffle8::<_, i32x2>(x, x, IDX8);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-gather-pass.rs b/src/test/ui/simd/intrinsic/generic-gather-pass.rs
new file mode 100644 (file)
index 0000000..805caeb
--- /dev/null
@@ -0,0 +1,141 @@
+// run-pass
+// ignore-emscripten
+
+// Test that the simd_{gather,scatter} intrinsics produce the correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct x4<T>(pub T, pub T, pub T, pub T);
+
+extern "platform-intrinsic" {
+    fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
+    fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
+}
+
+fn main() {
+    let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.];
+
+    let default = x4(-3_f32, -3., -3., -3.);
+    let s_strided = x4(0_f32, 2., -3., 6.);
+    let mask = x4(-1_i32, -1, 0, -1);
+
+    // reading from *const
+    unsafe {
+        let pointer = &x[0] as *const f32;
+        let pointers =  x4(
+            pointer.offset(0) as *const f32,
+            pointer.offset(2),
+            pointer.offset(4),
+            pointer.offset(6)
+        );
+
+        let r_strided = simd_gather(default, pointers, mask);
+
+        assert_eq!(r_strided, s_strided);
+    }
+
+    // reading from *mut
+    unsafe {
+        let pointer = &mut x[0] as *mut f32;
+        let pointers = x4(
+            pointer.offset(0) as *mut f32,
+            pointer.offset(2),
+            pointer.offset(4),
+            pointer.offset(6)
+        );
+
+        let r_strided = simd_gather(default, pointers, mask);
+
+        assert_eq!(r_strided, s_strided);
+    }
+
+    // writing to *mut
+    unsafe {
+        let pointer = &mut x[0] as *mut f32;
+        let pointers = x4(
+            pointer.offset(0) as *mut f32,
+            pointer.offset(2),
+            pointer.offset(4),
+            pointer.offset(6)
+        );
+
+        let values = x4(42_f32, 43_f32, 44_f32, 45_f32);
+        simd_scatter(values, pointers, mask);
+
+        assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]);
+    }
+
+    // test modifying array of *const f32
+    let mut y = [
+        &x[0] as *const f32,
+        &x[1] as *const f32,
+        &x[2] as *const f32,
+        &x[3] as *const f32,
+        &x[4] as *const f32,
+        &x[5] as *const f32,
+        &x[6] as *const f32,
+        &x[7] as *const f32
+    ];
+
+    let default = x4(y[0], y[0], y[0], y[0]);
+    let s_strided = x4(y[0], y[2], y[0], y[6]);
+
+    // reading from *const
+    unsafe {
+        let pointer = &y[0] as *const *const f32;
+        let pointers = x4(
+            pointer.offset(0) as *const *const f32,
+            pointer.offset(2),
+            pointer.offset(4),
+            pointer.offset(6)
+        );
+
+        let r_strided = simd_gather(default, pointers, mask);
+
+        assert_eq!(r_strided, s_strided);
+    }
+
+    // reading from *mut
+    unsafe {
+        let pointer = &mut y[0] as *mut *const f32;
+        let pointers = x4(
+            pointer.offset(0) as *mut *const f32,
+            pointer.offset(2),
+            pointer.offset(4),
+            pointer.offset(6)
+        );
+
+        let r_strided = simd_gather(default, pointers, mask);
+
+        assert_eq!(r_strided, s_strided);
+    }
+
+    // writing to *mut
+    unsafe {
+        let pointer = &mut y[0] as *mut *const f32;
+        let pointers = x4(
+            pointer.offset(0) as *mut *const f32,
+            pointer.offset(2),
+            pointer.offset(4),
+            pointer.offset(6)
+        );
+
+        let values = x4(y[7], y[6], y[5], y[1]);
+        simd_scatter(values, pointers, mask);
+
+        let s = [
+            &x[7] as *const f32,
+            &x[1] as *const f32,
+            &x[6] as *const f32,
+            &x[3] as *const f32,
+            &x[4] as *const f32,
+            &x[5] as *const f32,
+            &x[1] as *const f32,
+            &x[7] as *const f32
+        ];
+        assert_eq!(y, s);
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-reduction-pass.rs b/src/test/ui/simd/intrinsic/generic-reduction-pass.rs
new file mode 100644 (file)
index 0000000..4a54afe
--- /dev/null
@@ -0,0 +1,155 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+// ignore-emscripten
+
+// Test that the simd_reduce_{op} intrinsics produce the correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct b8x4(pub i8, pub i8, pub i8, pub i8);
+
+extern "platform-intrinsic" {
+    fn simd_reduce_add_unordered<T, U>(x: T) -> U;
+    fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
+    fn simd_reduce_add_ordered<T, U>(x: T, acc: U) -> U;
+    fn simd_reduce_mul_ordered<T, U>(x: T, acc: U) -> U;
+    fn simd_reduce_min<T, U>(x: T) -> U;
+    fn simd_reduce_max<T, U>(x: T) -> U;
+    fn simd_reduce_min_nanless<T, U>(x: T) -> U;
+    fn simd_reduce_max_nanless<T, U>(x: T) -> U;
+    fn simd_reduce_and<T, U>(x: T) -> U;
+    fn simd_reduce_or<T, U>(x: T) -> U;
+    fn simd_reduce_xor<T, U>(x: T) -> U;
+    fn simd_reduce_all<T>(x: T) -> bool;
+    fn simd_reduce_any<T>(x: T) -> bool;
+}
+
+fn main() {
+    unsafe {
+        let x = i32x4(1, -2, 3, 4);
+        let r: i32 = simd_reduce_add_unordered(x);
+        assert_eq!(r, 6_i32);
+        let r: i32 = simd_reduce_mul_unordered(x);
+        assert_eq!(r, -24_i32);
+        let r: i32 = simd_reduce_add_ordered(x, -1);
+        assert_eq!(r, 5_i32);
+        let r: i32 = simd_reduce_mul_ordered(x, -1);
+        assert_eq!(r, 24_i32);
+
+        let r: i32 = simd_reduce_min(x);
+        assert_eq!(r, -2_i32);
+        let r: i32 = simd_reduce_max(x);
+        assert_eq!(r, 4_i32);
+
+        let x = i32x4(-1, -1, -1, -1);
+        let r: i32 = simd_reduce_and(x);
+        assert_eq!(r, -1_i32);
+        let r: i32 = simd_reduce_or(x);
+        assert_eq!(r, -1_i32);
+        let r: i32 = simd_reduce_xor(x);
+        assert_eq!(r, 0_i32);
+
+        let x = i32x4(-1, -1, 0, -1);
+        let r: i32 = simd_reduce_and(x);
+        assert_eq!(r, 0_i32);
+        let r: i32 = simd_reduce_or(x);
+        assert_eq!(r, -1_i32);
+        let r: i32 = simd_reduce_xor(x);
+        assert_eq!(r, -1_i32);
+    }
+
+    unsafe {
+        let x = u32x4(1, 2, 3, 4);
+        let r: u32 = simd_reduce_add_unordered(x);
+        assert_eq!(r, 10_u32);
+        let r: u32 = simd_reduce_mul_unordered(x);
+        assert_eq!(r, 24_u32);
+        let r: u32 = simd_reduce_add_ordered(x, 1);
+        assert_eq!(r, 11_u32);
+        let r: u32 = simd_reduce_mul_ordered(x, 2);
+        assert_eq!(r, 48_u32);
+
+        let r: u32 = simd_reduce_min(x);
+        assert_eq!(r, 1_u32);
+        let r: u32 = simd_reduce_max(x);
+        assert_eq!(r, 4_u32);
+
+        let t = u32::MAX;
+        let x = u32x4(t, t, t, t);
+        let r: u32 = simd_reduce_and(x);
+        assert_eq!(r, t);
+        let r: u32 = simd_reduce_or(x);
+        assert_eq!(r, t);
+        let r: u32 = simd_reduce_xor(x);
+        assert_eq!(r, 0_u32);
+
+        let x = u32x4(t, t, 0, t);
+        let r: u32 = simd_reduce_and(x);
+        assert_eq!(r, 0_u32);
+        let r: u32 = simd_reduce_or(x);
+        assert_eq!(r, t);
+        let r: u32 = simd_reduce_xor(x);
+        assert_eq!(r, t);
+    }
+
+    unsafe {
+        let x = f32x4(1., -2., 3., 4.);
+        let r: f32 = simd_reduce_add_unordered(x);
+        assert_eq!(r, 6_f32);
+        let r: f32 = simd_reduce_mul_unordered(x);
+        assert_eq!(r, -24_f32);
+        let r: f32 = simd_reduce_add_ordered(x, 0.);
+        assert_eq!(r, 6_f32);
+        let r: f32 = simd_reduce_mul_ordered(x, 1.);
+        assert_eq!(r, -24_f32);
+        let r: f32 = simd_reduce_add_ordered(x, 1.);
+        assert_eq!(r, 7_f32);
+        let r: f32 = simd_reduce_mul_ordered(x, 2.);
+        assert_eq!(r, -48_f32);
+
+        let r: f32 = simd_reduce_min(x);
+        assert_eq!(r, -2_f32);
+        let r: f32 = simd_reduce_max(x);
+        assert_eq!(r, 4_f32);
+        let r: f32 = simd_reduce_min_nanless(x);
+        assert_eq!(r, -2_f32);
+        let r: f32 = simd_reduce_max_nanless(x);
+        assert_eq!(r, 4_f32);
+    }
+
+    unsafe {
+        let x = b8x4(!0, !0, !0, !0);
+        let r: bool = simd_reduce_all(x);
+        assert_eq!(r, true);
+        let r: bool = simd_reduce_any(x);
+        assert_eq!(r, true);
+
+        let x = b8x4(!0, !0, 0, !0);
+        let r: bool = simd_reduce_all(x);
+        assert_eq!(r, false);
+        let r: bool = simd_reduce_any(x);
+        assert_eq!(r, true);
+
+        let x = b8x4(0, 0, 0, 0);
+        let r: bool = simd_reduce_all(x);
+        assert_eq!(r, false);
+        let r: bool = simd_reduce_any(x);
+        assert_eq!(r, false);
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-reduction.rs b/src/test/ui/simd/intrinsic/generic-reduction.rs
new file mode 100644 (file)
index 0000000..ede4b26
--- /dev/null
@@ -0,0 +1,58 @@
+// build-fail
+// ignore-emscripten
+
+// Test that the simd_reduce_{op} intrinsics produce ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+
+extern "platform-intrinsic" {
+    fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
+    fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
+    fn simd_reduce_and<T, U>(x: T) -> U;
+    fn simd_reduce_or<T, U>(x: T) -> U;
+    fn simd_reduce_xor<T, U>(x: T) -> U;
+    fn simd_reduce_all<T>(x: T) -> bool;
+    fn simd_reduce_any<T>(x: T) -> bool;
+}
+
+fn main() {
+    let x = u32x4(0, 0, 0, 0);
+    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+
+    unsafe {
+        simd_reduce_add_ordered(z, 0);
+        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
+        simd_reduce_mul_ordered(z, 1);
+        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
+
+        let _: f32 = simd_reduce_and(x);
+        //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
+        let _: f32 = simd_reduce_or(x);
+        //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
+        let _: f32 = simd_reduce_xor(x);
+        //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
+
+        let _: f32 = simd_reduce_and(z);
+        //~^ ERROR unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
+        let _: f32 = simd_reduce_or(z);
+        //~^ ERROR unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
+        let _: f32 = simd_reduce_xor(z);
+        //~^ ERROR unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
+
+        let _: bool = simd_reduce_all(z);
+        //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
+        let _: bool = simd_reduce_any(z);
+        //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-reduction.stderr b/src/test/ui/simd/intrinsic/generic-reduction.stderr
new file mode 100644 (file)
index 0000000..1028faf
--- /dev/null
@@ -0,0 +1,63 @@
+error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
+  --> $DIR/generic-reduction.rs:34:9
+   |
+LL |         simd_reduce_add_ordered(z, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
+  --> $DIR/generic-reduction.rs:36:9
+   |
+LL |         simd_reduce_mul_ordered(z, 1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
+  --> $DIR/generic-reduction.rs:39:22
+   |
+LL |         let _: f32 = simd_reduce_and(x);
+   |                      ^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
+  --> $DIR/generic-reduction.rs:41:22
+   |
+LL |         let _: f32 = simd_reduce_or(x);
+   |                      ^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
+  --> $DIR/generic-reduction.rs:43:22
+   |
+LL |         let _: f32 = simd_reduce_xor(x);
+   |                      ^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
+  --> $DIR/generic-reduction.rs:46:22
+   |
+LL |         let _: f32 = simd_reduce_and(z);
+   |                      ^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
+  --> $DIR/generic-reduction.rs:48:22
+   |
+LL |         let _: f32 = simd_reduce_or(z);
+   |                      ^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
+  --> $DIR/generic-reduction.rs:50:22
+   |
+LL |         let _: f32 = simd_reduce_xor(z);
+   |                      ^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
+  --> $DIR/generic-reduction.rs:53:23
+   |
+LL |         let _: bool = simd_reduce_all(z);
+   |                       ^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
+  --> $DIR/generic-reduction.rs:55:23
+   |
+LL |         let _: bool = simd_reduce_any(z);
+   |                       ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-select-pass.rs b/src/test/ui/simd/intrinsic/generic-select-pass.rs
new file mode 100644 (file)
index 0000000..b850cf9
--- /dev/null
@@ -0,0 +1,195 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+// ignore-emscripten
+// ignore-endian-big behavior of simd_select_bitmask is endian-specific
+
+// Test that the simd_select intrinsics produces correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct b8x4(pub i8, pub i8, pub i8, pub i8);
+
+extern "platform-intrinsic" {
+    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
+}
+
+fn main() {
+    let m0 = b8x4(!0, !0, !0, !0);
+    let m1 = b8x4(0, 0, 0, 0);
+    let m2 = b8x4(!0, !0, 0, 0);
+    let m3 = b8x4(0, 0, !0, !0);
+    let m4 = b8x4(!0, 0, !0, 0);
+
+    unsafe {
+        let a = i32x4(1, -2, 3, 4);
+        let b = i32x4(5, 6, -7, 8);
+
+        let r: i32x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m2, a, b);
+        let e = i32x4(1, -2, -7, 8);
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m3, a, b);
+        let e = i32x4(5, 6, 3, 4);
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m4, a, b);
+        let e = i32x4(1, 6, 3, 8);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let a = u32x4(1, 2, 3, 4);
+        let b = u32x4(5, 6, 7, 8);
+
+        let r: u32x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m2, a, b);
+        let e = u32x4(1, 2, 7, 8);
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m3, a, b);
+        let e = u32x4(5, 6, 3, 4);
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m4, a, b);
+        let e = u32x4(1, 6, 3, 8);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let a = f32x4(1., 2., 3., 4.);
+        let b = f32x4(5., 6., 7., 8.);
+
+        let r: f32x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m2, a, b);
+        let e = f32x4(1., 2., 7., 8.);
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m3, a, b);
+        let e = f32x4(5., 6., 3., 4.);
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m4, a, b);
+        let e = f32x4(1., 6., 3., 8.);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let t = !0 as i8;
+        let f = 0 as i8;
+        let a = b8x4(t, f, t, f);
+        let b = b8x4(f, f, f, t);
+
+        let r: b8x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m2, a, b);
+        let e = b8x4(t, f, f, t);
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m3, a, b);
+        let e = b8x4(f, f, t, f);
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m4, a, b);
+        let e = b8x4(t, f, t, t);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7);
+        let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15);
+
+        let r: u32x8 = simd_select_bitmask(0u8, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0xffu8, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b);
+        let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15);
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b);
+        let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7);
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b);
+        let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let a = u32x4(0, 1, 2, 3);
+        let b = u32x4(4, 5, 6, 7);
+
+        let r: u32x4 = simd_select_bitmask(0u8, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select_bitmask(0xfu8, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select_bitmask(0b0101u8, a, b);
+        let e = u32x4(0, 5, 2, 7);
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select_bitmask(0b1010u8, a, b);
+        let e = u32x4(4, 1, 6, 3);
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select_bitmask(0b1100u8, a, b);
+        let e = u32x4(4, 5, 2, 3);
+        assert_eq!(r, e);
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-select.rs b/src/test/ui/simd/intrinsic/generic-select.rs
new file mode 100644 (file)
index 0000000..7d68af4
--- /dev/null
@@ -0,0 +1,64 @@
+// build-fail
+
+// Test that the simd_select intrinsic produces ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq)]
+struct b8x4(pub i8, pub i8, pub i8, pub i8);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq)]
+struct b8x8(pub i8, pub i8, pub i8, pub i8,
+            pub i8, pub i8, pub i8, pub i8);
+
+extern "platform-intrinsic" {
+    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
+}
+
+fn main() {
+    let m4 = b8x4(0, 0, 0, 0);
+    let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0);
+    let x = u32x4(0, 0, 0, 0);
+    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+
+    unsafe {
+        simd_select(m4, x, x);
+
+        simd_select(m8, x, x);
+        //~^ ERROR mismatched lengths: mask length `8` != other vector length `4`
+
+        simd_select(x, x, x);
+        //~^ ERROR mask element type is `u32`, expected `i_`
+
+        simd_select(z, z, z);
+        //~^ ERROR mask element type is `f32`, expected `i_`
+
+        simd_select(m4, 0u32, 1u32);
+        //~^ ERROR found non-SIMD `u32`
+
+        simd_select_bitmask(0u16, x, x);
+        //~^ ERROR mask length `16` != other vector length `4`
+        //
+        simd_select_bitmask(0u8, 1u32, 2u32);
+        //~^ ERROR found non-SIMD `u32`
+
+        simd_select_bitmask(0.0f32, x, x);
+        //~^ ERROR `f32` is not an integral type
+
+        simd_select_bitmask("x", x, x);
+        //~^ ERROR `&str` is not an integral type
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-select.stderr b/src/test/ui/simd/intrinsic/generic-select.stderr
new file mode 100644 (file)
index 0000000..c53d581
--- /dev/null
@@ -0,0 +1,51 @@
+error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
+  --> $DIR/generic-select.rs:40:9
+   |
+LL |         simd_select(m8, x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_`
+  --> $DIR/generic-select.rs:43:9
+   |
+LL |         simd_select(x, x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_`
+  --> $DIR/generic-select.rs:46:9
+   |
+LL |         simd_select(z, z, z);
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32`
+  --> $DIR/generic-select.rs:49:9
+   |
+LL |         simd_select(m4, 0u32, 1u32);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `16` != other vector length `4`
+  --> $DIR/generic-select.rs:52:9
+   |
+LL |         simd_select_bitmask(0u16, x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32`
+  --> $DIR/generic-select.rs:55:9
+   |
+LL |         simd_select_bitmask(0u8, 1u32, 2u32);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type
+  --> $DIR/generic-select.rs:58:9
+   |
+LL |         simd_select_bitmask(0.0f32, x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type
+  --> $DIR/generic-select.rs:61:9
+   |
+LL |         simd_select_bitmask("x", x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/generic-shuffle.rs b/src/test/ui/simd/intrinsic/generic-shuffle.rs
new file mode 100644 (file)
index 0000000..9611780
--- /dev/null
@@ -0,0 +1,33 @@
+// build-fail
+
+// Test that the simd_shuffle intrinsic produces ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct Simd<T, const N: usize>([T; N]);
+
+extern "platform-intrinsic" {
+    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+}
+
+fn main() {
+    const I: [u32; 2] = [0; 2];
+    const I2: [f32; 2] = [0.; 2];
+    let v = Simd::<u32, 4>([0; 4]);
+
+    unsafe {
+        let _: Simd<u32, 2> = simd_shuffle(v, v, I);
+
+        let _: Simd<u32, 4> = simd_shuffle(v, v, I);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+
+        let _: Simd<f32, 2> = simd_shuffle(v, v, I);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+
+        let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+    }
+}
diff --git a/src/test/ui/simd/intrinsic/generic-shuffle.stderr b/src/test/ui/simd/intrinsic/generic-shuffle.stderr
new file mode 100644 (file)
index 0000000..44c57cd
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4_usize>` with length 4
+  --> $DIR/generic-shuffle.rs:24:31
+   |
+LL |         let _: Simd<u32, 4> = simd_shuffle(v, v, I);
+   |                               ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd<u32, 4_usize>`), found `Simd<f32, 2_usize>` with element type `f32`
+  --> $DIR/generic-shuffle.rs:27:31
+   |
+LL |         let _: Simd<f32, 2> = simd_shuffle(v, v, I);
+   |                               ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
+  --> $DIR/generic-shuffle.rs:30:31
+   |
+LL |         let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
+   |                               ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs b/src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs
new file mode 100644 (file)
index 0000000..7221b3a
--- /dev/null
@@ -0,0 +1,26 @@
+// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being
+// passed the wrong Instance, causing issues with inlining. See #67557.
+//
+// run-pass
+// compile-flags: -Zmir-opt-level=4
+#![feature(platform_intrinsics, repr_simd)]
+
+extern "platform-intrinsic" {
+    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
+}
+
+#[repr(simd)]
+#[derive(Debug, PartialEq)]
+struct Simd2(u8, u8);
+
+fn main() {
+    unsafe {
+        let _: Simd2 = inline_me();
+    }
+}
+
+#[inline(always)]
+unsafe fn inline_me() -> Simd2 {
+    const IDX: [u32; 2] = [0, 3];
+    simd_shuffle2(Simd2(10, 11), Simd2(12, 13), IDX)
+}
diff --git a/src/test/ui/simd/intrinsic/inlining-issue67557.rs b/src/test/ui/simd/intrinsic/inlining-issue67557.rs
new file mode 100644 (file)
index 0000000..0d15427
--- /dev/null
@@ -0,0 +1,42 @@
+// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed
+// the wrong Instance, causing issues with inlining. See #67557.
+//
+// run-pass
+// compile-flags: -Zmir-opt-level=4
+#![feature(platform_intrinsics, repr_simd)]
+
+extern "platform-intrinsic" {
+    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
+}
+
+#[repr(simd)]
+#[derive(Debug, PartialEq)]
+struct Simd2(u8, u8);
+
+fn main() {
+    unsafe {
+        const IDX: [u32; 2] = [0, 1];
+        let p_res: Simd2 = simd_shuffle2(Simd2(10, 11), Simd2(12, 13), IDX);
+        let a_res: Simd2 = inline_me();
+
+        assert_10_11(p_res);
+        assert_10_13(a_res);
+    }
+}
+
+#[inline(never)]
+fn assert_10_11(x: Simd2) {
+    assert_eq!(x, Simd2(10, 11));
+}
+
+#[inline(never)]
+fn assert_10_13(x: Simd2) {
+    assert_eq!(x, Simd2(10, 13));
+}
+
+
+#[inline(always)]
+unsafe fn inline_me() -> Simd2 {
+    const IDX: [u32; 2] = [0, 3];
+    simd_shuffle2(Simd2(10, 11), Simd2(12, 13), IDX)
+}
diff --git a/src/test/ui/simd/intrinsic/issue-85855.rs b/src/test/ui/simd/intrinsic/issue-85855.rs
new file mode 100644 (file)
index 0000000..f276fbd
--- /dev/null
@@ -0,0 +1,19 @@
+// Check that appropriate errors are reported if an intrinsic is defined
+// with the wrong number of generic lifetime/type/const parameters, and
+// that no ICE occurs in these cases.
+
+#![feature(platform_intrinsics)]
+#![crate_type="lib"]
+
+extern "platform-intrinsic" {
+    fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
+    //~^ ERROR: intrinsic has wrong number of lifetime parameters
+
+    fn simd_add<'a, T>(x: T, y: T) -> T;
+
+    fn simd_sub<T, U>(x: T, y: U);
+    //~^ ERROR: intrinsic has wrong number of type parameters
+
+    fn simd_mul<T, const N: usize>(x: T, y: T);
+    //~^ ERROR: intrinsic has wrong number of const parameters
+}
diff --git a/src/test/ui/simd/intrinsic/issue-85855.stderr b/src/test/ui/simd/intrinsic/issue-85855.stderr
new file mode 100644 (file)
index 0000000..fb2f1fb
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0094]: intrinsic has wrong number of lifetime parameters: found 1, expected 0
+  --> $DIR/issue-85855.rs:9:27
+   |
+LL |     fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
+   |                           ^^^^^^^^^^^ expected 0 lifetime parameters
+
+error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
+  --> $DIR/issue-85855.rs:14:16
+   |
+LL |     fn simd_sub<T, U>(x: T, y: U);
+   |                ^^^^^^ expected 1 type parameter
+
+error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0
+  --> $DIR/issue-85855.rs:17:16
+   |
+LL |     fn simd_mul<T, const N: usize>(x: T, y: T);
+   |                ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0094`.
index aae6ce4663fbacd32705b45ff14c5578698ea50a..0dee3a0e869d79eaaeffd40c37b10159dd0a86f8 100644 (file)
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x2(u8, u8);
+struct u8x2([u8; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x4(u8, u8, u8, u8);
+struct u8x4([u8; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x8(u8, u8, u8, u8, u8, u8, u8, u8);
+struct u8x8([u8; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x16(
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-);
+struct u8x16([u8; 16]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x32(
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-);
+struct u8x32([u8; 32]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x64(
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-);
+struct u8x64([u8; 64]);
+
+extern "platform-intrinsic" {
+    pub fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
+    pub fn simd_shuffle4<T, U>(x: T, y: T, idx: [u32; 4]) -> U;
+    pub fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
+    pub fn simd_shuffle16<T, U>(x: T, y: T, idx: [u32; 16]) -> U;
+    pub fn simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U;
+    pub fn simd_shuffle64<T, U>(x: T, y: T, idx: [u32; 64]) -> U;
+}
 
 // Test vectors by lane size. Since LLVM does not distinguish between a shuffle
 // over two f32s and a shuffle over two u64s, or any other such combination,
 // it is not necessary to test every possible vector, only lane counts.
 macro_rules! test_shuffle_lanes {
-    ($n:literal, $x:ident, $y:ident, $t:tt) => {
+    ($n:literal, $x:ident, $y:ident) => {
         unsafe {
                 let shuffle: $x = {
                     const ARR: [u32; $n] = {
@@ -155,11 +49,10 @@ macro_rules! test_shuffle_lanes {
                         arr[0] = $n * 2;
                         arr
                     };
-                    extern "platform-intrinsic" {
-                        pub fn $y<T, U>(x: T, y: T, idx: [u32; $n]) -> U;
-                    }
-                    let vec1 = $x$t;
-                    let vec2 = $x$t;
+                    let mut n: u8 = $n;
+                    let vals = [0; $n].map(|_| { n = n - 1; n });
+                    let vec1 = $x(vals);
+                    let vec2 = $x(vals);
                     $y(vec1, vec2, ARR)
                 };
         }
@@ -175,24 +68,17 @@ macro_rules! test_shuffle_lanes {
 // And unfortunately, standard comments, as in the UI test harness, disappear in macros!
 
 fn main() {
-    test_shuffle_lanes!(2, u8x2, simd_shuffle2, (2, 1));
-    test_shuffle_lanes!(4, u8x4, simd_shuffle4, (4, 3, 2, 1));
-    test_shuffle_lanes!(8, u8x8, simd_shuffle8, (8, 7, 6, 5, 4, 3, 2, 1));
-    test_shuffle_lanes!(16, u8x16, simd_shuffle16,
-        (16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-    test_shuffle_lanes!(32, u8x32, simd_shuffle32,
-        (32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
-         15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-    test_shuffle_lanes!(64, u8x64, simd_shuffle64,
-        (64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
-         48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
-         32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
-         16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
+    test_shuffle_lanes!(2, u8x2, simd_shuffle2);
+    test_shuffle_lanes!(4, u8x4, simd_shuffle4);
+    test_shuffle_lanes!(8, u8x8, simd_shuffle8);
+    test_shuffle_lanes!(16, u8x16, simd_shuffle16);
+    test_shuffle_lanes!(32, u8x32, simd_shuffle32);
+    test_shuffle_lanes!(64, u8x64, simd_shuffle64);
 
     extern "platform-intrinsic" {
         fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
     }
-    let v = u8x2(0, 0);
+    let v = u8x2([0, 0]);
     const I: [u32; 2] = [4, 4];
     unsafe {
         let _: u8x2 = simd_shuffle(v, v, I);
index 737fb5e6e51e25c3f7f7cfb36a4294b5790e1f71..5492d14f7c924bcd2961d64da58babe31ce5f2f1 100644 (file)
@@ -1,78 +1,71 @@
 error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: shuffle index #0 is out of bounds (limit 4)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
 LL |                     $y(vec1, vec2, ARR)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL |     test_shuffle_lanes!(2, u8x2, simd_shuffle2, (2, 1));
-   |     ---------------------------------------------------- in this macro invocation
+LL |     test_shuffle_lanes!(2, u8x2, simd_shuffle2);
+   |     -------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: shuffle index #0 is out of bounds (limit 8)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
 LL |                     $y(vec1, vec2, ARR)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL |     test_shuffle_lanes!(4, u8x4, simd_shuffle4, (4, 3, 2, 1));
-   |     ---------------------------------------------------------- in this macro invocation
+LL |     test_shuffle_lanes!(4, u8x4, simd_shuffle4);
+   |     -------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: shuffle index #0 is out of bounds (limit 16)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
 LL |                     $y(vec1, vec2, ARR)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL |     test_shuffle_lanes!(8, u8x8, simd_shuffle8, (8, 7, 6, 5, 4, 3, 2, 1));
-   |     ---------------------------------------------------------------------- in this macro invocation
+LL |     test_shuffle_lanes!(8, u8x8, simd_shuffle8);
+   |     -------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle16` intrinsic: shuffle index #0 is out of bounds (limit 32)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
-LL |                       $y(vec1, vec2, ARR)
-   |                       ^^^^^^^^^^^^^^^^^^^
+LL |                     $y(vec1, vec2, ARR)
+   |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL | /     test_shuffle_lanes!(16, u8x16, simd_shuffle16,
-LL | |         (16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-   | |_________________________________________________________________- in this macro invocation
+LL |     test_shuffle_lanes!(16, u8x16, simd_shuffle16);
+   |     ----------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle32` intrinsic: shuffle index #0 is out of bounds (limit 64)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
-LL |                       $y(vec1, vec2, ARR)
-   |                       ^^^^^^^^^^^^^^^^^^^
+LL |                     $y(vec1, vec2, ARR)
+   |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL | /     test_shuffle_lanes!(32, u8x32, simd_shuffle32,
-LL | |         (32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
-LL | |          15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-   | |_____________________________________________________________- in this macro invocation
+LL |     test_shuffle_lanes!(32, u8x32, simd_shuffle32);
+   |     ----------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle64` intrinsic: shuffle index #0 is out of bounds (limit 128)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
-LL |                       $y(vec1, vec2, ARR)
-   |                       ^^^^^^^^^^^^^^^^^^^
+LL |                     $y(vec1, vec2, ARR)
+   |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL | /     test_shuffle_lanes!(64, u8x64, simd_shuffle64,
-LL | |         (64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
-LL | |          48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
-LL | |          32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
-LL | |          16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-   | |_________________________________________________________________- in this macro invocation
+LL |     test_shuffle_lanes!(64, u8x64, simd_shuffle64);
+   |     ----------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4)
-  --> $DIR/shuffle-not-out-of-bounds.rs:198:23
+  --> $DIR/shuffle-not-out-of-bounds.rs:84:23
    |
 LL |         let _: u8x2 = simd_shuffle(v, v, I);
    |                       ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-array-trait.rs b/src/test/ui/simd/simd-array-trait.rs
deleted file mode 100644 (file)
index 45c10b3..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Figuring out the size of a vector type that depends on traits doesn't ICE
-
-#![allow(dead_code)]
-
-// pretty-expanded FIXME #23616
-
-#![feature(repr_simd, platform_intrinsics, generic_const_exprs)]
-#![allow(non_camel_case_types, incomplete_features)]
-
-pub trait Simd {
-    type Lane: Clone + Copy;
-    const SIZE: usize;
-}
-
-pub struct i32x4;
-impl Simd for i32x4 {
-    type Lane = i32;
-    const SIZE: usize = 4;
-}
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct T<S: Simd>([S::Lane; S::SIZE]);
-//~^ ERROR unconstrained generic constant
-
-extern "platform-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
-}
-
-pub fn main() {
-    let mut t = T::<i32x4>([0; 4]);
-    unsafe {
-        for i in 0_i32..4 {
-            t = simd_insert(t, i as u32, i);
-        }
-        for i in 0_i32..4 {
-            assert_eq!(i, simd_extract(t, i as u32));
-        }
-    }
-}
diff --git a/src/test/ui/simd/simd-array-trait.stderr b/src/test/ui/simd/simd-array-trait.stderr
deleted file mode 100644 (file)
index 0e02883..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error: unconstrained generic constant
-  --> $DIR/simd-array-trait.rs:23:23
-   |
-LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
-   |                       ^^^^^^^^^^^^^^^^^^
-   |
-   = help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-array-type.rs b/src/test/ui/simd/simd-array-type.rs
deleted file mode 100644 (file)
index 7d66395..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-
-// pretty-expanded FIXME #23616
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct S([i32; 4]);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct T<const N: usize>([i32; N]);
-
-extern "platform-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
-}
-
-pub fn main() {
-    let mut s = S([0; 4]);
-
-    unsafe {
-        for i in 0_i32..4 {
-            s = simd_insert(s, i as u32, i);
-        }
-        for i in 0_i32..4 {
-            assert_eq!(i, simd_extract(s, i as u32));
-        }
-    }
-
-    let mut t = T::<4>([0; 4]);
-    unsafe {
-        for i in 0_i32..4 {
-            t = simd_insert(t, i as u32, i);
-        }
-        for i in 0_i32..4 {
-            assert_eq!(i, simd_extract(t, i as u32));
-        }
-    }
-}
diff --git a/src/test/ui/simd/simd-generics.rs b/src/test/ui/simd/simd-generics.rs
deleted file mode 100644 (file)
index fa9d35e..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// run-pass
-#![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics)]
-
-use std::ops;
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct f32x4(f32, f32, f32, f32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct A<const N: usize>([f32; N]);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct B<T>([T; 4]);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct C<T, const N: usize>([T; N]);
-
-
-extern "platform-intrinsic" {
-    fn simd_add<T>(x: T, y: T) -> T;
-}
-
-fn add<T: ops::Add<Output=T>>(lhs: T, rhs: T) -> T {
-    lhs + rhs
-}
-
-impl ops::Add for f32x4 {
-    type Output = f32x4;
-
-    fn add(self, rhs: f32x4) -> f32x4 {
-        unsafe { simd_add(self, rhs) }
-    }
-}
-
-impl ops::Add for A<4> {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        unsafe { simd_add(self, rhs) }
-    }
-}
-
-impl ops::Add for B<f32> {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        unsafe { simd_add(self, rhs) }
-    }
-}
-
-impl ops::Add for C<f32, 4> {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        unsafe { simd_add(self, rhs) }
-    }
-}
-
-
-pub fn main() {
-    let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32];
-    let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32];
-
-    // lame-o
-    let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
-    let f32x4(a0, a1, a2, a3) = add(a, a);
-    assert_eq!(a0, 2.0f32);
-    assert_eq!(a1, 4.0f32);
-    assert_eq!(a2, 6.0f32);
-    assert_eq!(a3, 8.0f32);
-
-    let a = A(x);
-    assert_eq!(add(a, a).0, y);
-
-    let b = B(x);
-    assert_eq!(add(b, b).0, y);
-
-    let c = C(x);
-    assert_eq!(add(c, c).0, y);
-}
diff --git a/src/test/ui/simd/simd-intrinsic-float-math.rs b/src/test/ui/simd/simd-intrinsic-float-math.rs
deleted file mode 100644 (file)
index 7a4f746..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// run-pass
-// ignore-emscripten
-// ignore-android
-
-// FIXME: this test fails on arm-android because the NDK version 14 is too old.
-// It needs at least version 18. We disable it on all android build bots because
-// there is no way in compile-test to disable it for an (arch,os) pair.
-
-// Test that the simd floating-point math intrinsics produce correct results.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-extern "platform-intrinsic" {
-    fn simd_fsqrt<T>(x: T) -> T;
-    fn simd_fabs<T>(x: T) -> T;
-    fn simd_fsin<T>(x: T) -> T;
-    fn simd_fcos<T>(x: T) -> T;
-    fn simd_fexp<T>(x: T) -> T;
-    fn simd_fexp2<T>(x: T) -> T;
-    fn simd_fma<T>(x: T, y: T, z: T) -> T;
-    fn simd_flog<T>(x: T) -> T;
-    fn simd_flog10<T>(x: T) -> T;
-    fn simd_flog2<T>(x: T) -> T;
-    fn simd_fpow<T>(x: T, y: T) -> T;
-    fn simd_fpowi<T>(x: T, y: i32) -> T;
-
-    // rounding functions
-    fn simd_ceil<T>(x: T) -> T;
-    fn simd_floor<T>(x: T) -> T;
-    fn simd_round<T>(x: T) -> T;
-    fn simd_trunc<T>(x: T) -> T;
-}
-
-macro_rules! assert_approx_eq_f32 {
-    ($a:expr, $b:expr) => ({
-        let (a, b) = (&$a, &$b);
-        assert!((*a - *b).abs() < 1.0e-6,
-                "{} is not approximately equal to {}", *a, *b);
-    })
-}
-macro_rules! assert_approx_eq {
-    ($a:expr, $b:expr) => ({
-        let a = $a;
-        let b = $b;
-        assert_approx_eq_f32!(a.0, b.0);
-        assert_approx_eq_f32!(a.1, b.1);
-        assert_approx_eq_f32!(a.2, b.2);
-        assert_approx_eq_f32!(a.3, b.3);
-    })
-}
-
-fn main() {
-    let x = f32x4(1.0, 1.0, 1.0, 1.0);
-    let y = f32x4(-1.0, -1.0, -1.0, -1.0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-
-    let h = f32x4(0.5, 0.5, 0.5, 0.5);
-
-    unsafe {
-        let r = simd_fabs(y);
-        assert_approx_eq!(x, r);
-
-        let r = simd_fcos(z);
-        assert_approx_eq!(x, r);
-
-        let r = simd_fexp(z);
-        assert_approx_eq!(x, r);
-
-        let r = simd_fexp2(z);
-        assert_approx_eq!(x, r);
-
-        let r = simd_fma(x, h, h);
-        assert_approx_eq!(x, r);
-
-        let r = simd_fsqrt(x);
-        assert_approx_eq!(x, r);
-
-        let r = simd_flog(x);
-        assert_approx_eq!(z, r);
-
-        let r = simd_flog2(x);
-        assert_approx_eq!(z, r);
-
-        let r = simd_flog10(x);
-        assert_approx_eq!(z, r);
-
-        let r = simd_fpow(h, x);
-        assert_approx_eq!(h, r);
-
-        let r = simd_fpowi(h, 1);
-        assert_approx_eq!(h, r);
-
-        let r = simd_fsin(z);
-        assert_approx_eq!(z, r);
-
-        // rounding functions
-        let r = simd_floor(h);
-        assert_eq!(z, r);
-
-        let r = simd_ceil(h);
-        assert_eq!(x, r);
-
-        let r = simd_round(h);
-        assert_eq!(x, r);
-
-        let r = simd_trunc(h);
-        assert_eq!(z, r);
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-float-minmax.rs b/src/test/ui/simd/simd-intrinsic-float-minmax.rs
deleted file mode 100644 (file)
index d79be61..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// run-pass
-// ignore-emscripten
-
-// Test that the simd_f{min,max} intrinsics produce the correct results.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-extern "platform-intrinsic" {
-    fn simd_fmin<T>(x: T, y: T) -> T;
-    fn simd_fmax<T>(x: T, y: T) -> T;
-}
-
-fn main() {
-    let x = f32x4(1.0, 2.0, 3.0, 4.0);
-    let y = f32x4(2.0, 1.0, 4.0, 3.0);
-
-    #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
-    let nan = f32::NAN;
-    // MIPS hardware treats f32::NAN as SNAN. Clear the signaling bit.
-    // See https://github.com/rust-lang/rust/issues/52746.
-    #[cfg(any(target_arch = "mips", target_arch = "mips64"))]
-    let nan = f32::from_bits(f32::NAN.to_bits() - 1);
-
-    let n = f32x4(nan, nan, nan, nan);
-
-    unsafe {
-        let min0 = simd_fmin(x, y);
-        let min1 = simd_fmin(y, x);
-        assert_eq!(min0, min1);
-        let e = f32x4(1.0, 1.0, 3.0, 3.0);
-        assert_eq!(min0, e);
-        let minn = simd_fmin(x, n);
-        assert_eq!(minn, x);
-        let minn = simd_fmin(y, n);
-        assert_eq!(minn, y);
-
-        let max0 = simd_fmax(x, y);
-        let max1 = simd_fmax(y, x);
-        assert_eq!(max0, max1);
-        let e = f32x4(2.0, 2.0, 4.0, 4.0);
-        assert_eq!(max0, e);
-        let maxn = simd_fmax(x, n);
-        assert_eq!(maxn, x);
-        let maxn = simd_fmax(y, n);
-        assert_eq!(maxn, y);
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs
deleted file mode 100644 (file)
index c11d14b..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-// run-pass
-// ignore-emscripten
-
-#![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct I32<const N: usize>([i32; N]);
-
-extern "platform-intrinsic" {
-    fn simd_saturating_add<T>(x: T, y: T) -> T;
-    fn simd_saturating_sub<T>(x: T, y: T) -> T;
-}
-
-fn main() {
-    // unsigned
-    {
-        const M: u32 = u32::MAX;
-
-        let a = u32x4(1, 2, 3, 4);
-        let b = u32x4(2, 4, 6, 8);
-        let m = u32x4(M, M, M, M);
-        let m1 = u32x4(M - 1, M - 1, M - 1, M - 1);
-        let z = u32x4(0, 0, 0, 0);
-
-        unsafe {
-            assert_eq!(simd_saturating_add(z, z), z);
-            assert_eq!(simd_saturating_add(z, a), a);
-            assert_eq!(simd_saturating_add(b, z), b);
-            assert_eq!(simd_saturating_add(a, a), b);
-            assert_eq!(simd_saturating_add(a, m), m);
-            assert_eq!(simd_saturating_add(m, b), m);
-            assert_eq!(simd_saturating_add(m1, a), m);
-
-            assert_eq!(simd_saturating_sub(b, z), b);
-            assert_eq!(simd_saturating_sub(b, a), a);
-            assert_eq!(simd_saturating_sub(a, a), z);
-            assert_eq!(simd_saturating_sub(a, b), z);
-            assert_eq!(simd_saturating_sub(a, m1), z);
-            assert_eq!(simd_saturating_sub(b, m1), z);
-        }
-    }
-
-    // signed
-    {
-        const MIN: i32 = i32::MIN;
-        const MAX: i32 = i32::MAX;
-
-        let a = I32::<4>([1, 2, 3, 4]);
-        let b = I32::<4>([2, 4, 6, 8]);
-        let c = I32::<4>([-1, -2, -3, -4]);
-        let d = I32::<4>([-2, -4, -6, -8]);
-
-        let max = I32::<4>([MAX, MAX, MAX, MAX]);
-        let max1 = I32::<4>([MAX - 1, MAX - 1, MAX - 1, MAX - 1]);
-        let min = I32::<4>([MIN, MIN, MIN, MIN]);
-        let min1 = I32::<4>([MIN + 1, MIN + 1, MIN + 1, MIN + 1]);
-
-        let z = I32::<4>([0, 0, 0, 0]);
-
-        unsafe {
-            assert_eq!(simd_saturating_add(z, z).0, z.0);
-            assert_eq!(simd_saturating_add(z, a).0, a.0);
-            assert_eq!(simd_saturating_add(b, z).0, b.0);
-            assert_eq!(simd_saturating_add(a, a).0, b.0);
-            assert_eq!(simd_saturating_add(a, max).0, max.0);
-            assert_eq!(simd_saturating_add(max, b).0, max.0);
-            assert_eq!(simd_saturating_add(max1, a).0, max.0);
-            assert_eq!(simd_saturating_add(min1, z).0, min1.0);
-            assert_eq!(simd_saturating_add(min, z).0, min.0);
-            assert_eq!(simd_saturating_add(min1, c).0, min.0);
-            assert_eq!(simd_saturating_add(min, c).0, min.0);
-            assert_eq!(simd_saturating_add(min1, d).0, min.0);
-            assert_eq!(simd_saturating_add(min, d).0, min.0);
-
-            assert_eq!(simd_saturating_sub(b, z).0, b.0);
-            assert_eq!(simd_saturating_sub(b, a).0, a.0);
-            assert_eq!(simd_saturating_sub(a, a).0, z.0);
-            assert_eq!(simd_saturating_sub(a, b).0, c.0);
-            assert_eq!(simd_saturating_sub(z, max).0, min1.0);
-            assert_eq!(simd_saturating_sub(min1, z).0, min1.0);
-            assert_eq!(simd_saturating_sub(min1, a).0, min.0);
-            assert_eq!(simd_saturating_sub(min1, b).0, min.0);
-        }
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs
deleted file mode 100644 (file)
index c507b8d..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// run-pass
-#![allow(non_camel_case_types)]
-
-// ignore-emscripten FIXME(#45351) hits an LLVM assert
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct U32<const N: usize>([u32; N]);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-macro_rules! all_eq {
-    ($a: expr, $b: expr) => {{
-        let a = $a;
-        let b = $b;
-        assert!(a.0 == b.0 && a.1 == b.1 && a.2 == b.2 && a.3 == b.3);
-    }}
-}
-
-macro_rules! all_eq_ {
-    ($a: expr, $b: expr) => {{
-        let a = $a;
-        let b = $b;
-        assert!(a.0 == b.0);
-    }}
-}
-
-
-extern "platform-intrinsic" {
-    fn simd_add<T>(x: T, y: T) -> T;
-    fn simd_sub<T>(x: T, y: T) -> T;
-    fn simd_mul<T>(x: T, y: T) -> T;
-    fn simd_div<T>(x: T, y: T) -> T;
-    fn simd_rem<T>(x: T, y: T) -> T;
-    fn simd_shl<T>(x: T, y: T) -> T;
-    fn simd_shr<T>(x: T, y: T) -> T;
-    fn simd_and<T>(x: T, y: T) -> T;
-    fn simd_or<T>(x: T, y: T) -> T;
-    fn simd_xor<T>(x: T, y: T) -> T;
-
-    fn simd_neg<T>(x: T) -> T;
-}
-
-fn main() {
-    let x1 = i32x4(1, 2, 3, 4);
-    let y1 = U32::<4>([1, 2, 3, 4]);
-    let z1 = f32x4(1.0, 2.0, 3.0, 4.0);
-    let x2 = i32x4(2, 3, 4, 5);
-    let y2 = U32::<4>([2, 3, 4, 5]);
-    let z2 = f32x4(2.0, 3.0, 4.0, 5.0);
-
-    unsafe {
-        all_eq!(simd_add(x1, x2), i32x4(3, 5, 7, 9));
-        all_eq!(simd_add(x2, x1), i32x4(3, 5, 7, 9));
-        all_eq_!(simd_add(y1, y2), U32::<4>([3, 5, 7, 9]));
-        all_eq_!(simd_add(y2, y1), U32::<4>([3, 5, 7, 9]));
-        all_eq!(simd_add(z1, z2), f32x4(3.0, 5.0, 7.0, 9.0));
-        all_eq!(simd_add(z2, z1), f32x4(3.0, 5.0, 7.0, 9.0));
-
-        all_eq!(simd_mul(x1, x2), i32x4(2, 6, 12, 20));
-        all_eq!(simd_mul(x2, x1), i32x4(2, 6, 12, 20));
-        all_eq_!(simd_mul(y1, y2), U32::<4>([2, 6, 12, 20]));
-        all_eq_!(simd_mul(y2, y1), U32::<4>([2, 6, 12, 20]));
-        all_eq!(simd_mul(z1, z2), f32x4(2.0, 6.0, 12.0, 20.0));
-        all_eq!(simd_mul(z2, z1), f32x4(2.0, 6.0, 12.0, 20.0));
-
-        all_eq!(simd_sub(x2, x1), i32x4(1, 1, 1, 1));
-        all_eq!(simd_sub(x1, x2), i32x4(-1, -1, -1, -1));
-        all_eq_!(simd_sub(y2, y1), U32::<4>([1, 1, 1, 1]));
-        all_eq_!(simd_sub(y1, y2), U32::<4>([!0, !0, !0, !0]));
-        all_eq!(simd_sub(z2, z1), f32x4(1.0, 1.0, 1.0, 1.0));
-        all_eq!(simd_sub(z1, z2), f32x4(-1.0, -1.0, -1.0, -1.0));
-
-        all_eq!(simd_div(x1, x1), i32x4(1, 1, 1, 1));
-        all_eq!(simd_div(i32x4(2, 4, 6, 8), i32x4(2, 2, 2, 2)), x1);
-        all_eq_!(simd_div(y1, y1), U32::<4>([1, 1, 1, 1]));
-        all_eq_!(simd_div(U32::<4>([2, 4, 6, 8]), U32::<4>([2, 2, 2, 2])), y1);
-        all_eq!(simd_div(z1, z1), f32x4(1.0, 1.0, 1.0, 1.0));
-        all_eq!(simd_div(z1, z2), f32x4(1.0/2.0, 2.0/3.0, 3.0/4.0, 4.0/5.0));
-        all_eq!(simd_div(z2, z1), f32x4(2.0/1.0, 3.0/2.0, 4.0/3.0, 5.0/4.0));
-
-        all_eq!(simd_rem(x1, x1), i32x4(0, 0, 0, 0));
-        all_eq!(simd_rem(x2, x1), i32x4(0, 1, 1, 1));
-        all_eq_!(simd_rem(y1, y1), U32::<4>([0, 0, 0, 0]));
-        all_eq_!(simd_rem(y2, y1), U32::<4>([0, 1, 1, 1]));
-        all_eq!(simd_rem(z1, z1), f32x4(0.0, 0.0, 0.0, 0.0));
-        all_eq!(simd_rem(z1, z2), z1);
-        all_eq!(simd_rem(z2, z1), f32x4(0.0, 1.0, 1.0, 1.0));
-
-        all_eq!(simd_shl(x1, x2), i32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5));
-        all_eq!(simd_shl(x2, x1), i32x4(2 << 1, 3 << 2, 4 << 3, 5 << 4));
-        all_eq_!(simd_shl(y1, y2), U32::<4>([1 << 2, 2 << 3, 3 << 4, 4 << 5]));
-        all_eq_!(simd_shl(y2, y1), U32::<4>([2 << 1, 3 << 2, 4 << 3, 5 << 4]));
-
-        // test right-shift by assuming left-shift is correct
-        all_eq!(simd_shr(simd_shl(x1, x2), x2), x1);
-        all_eq!(simd_shr(simd_shl(x2, x1), x1), x2);
-        all_eq_!(simd_shr(simd_shl(y1, y2), y2), y1);
-        all_eq_!(simd_shr(simd_shl(y2, y1), y1), y2);
-
-        // ensure we get logical vs. arithmetic shifts correct
-        let (a, b, c, d) = (-12, -123, -1234, -12345);
-        all_eq!(simd_shr(i32x4(a, b, c, d), x1), i32x4(a >> 1, b >> 2, c >> 3, d >> 4));
-        all_eq_!(simd_shr(U32::<4>([a as u32, b as u32, c as u32, d as u32]), y1),
-                U32::<4>([(a as u32) >> 1, (b as u32) >> 2, (c as u32) >> 3, (d as u32) >> 4]));
-
-        all_eq!(simd_and(x1, x2), i32x4(0, 2, 0, 4));
-        all_eq!(simd_and(x2, x1), i32x4(0, 2, 0, 4));
-        all_eq_!(simd_and(y1, y2), U32::<4>([0, 2, 0, 4]));
-        all_eq_!(simd_and(y2, y1), U32::<4>([0, 2, 0, 4]));
-
-        all_eq!(simd_or(x1, x2), i32x4(3, 3, 7, 5));
-        all_eq!(simd_or(x2, x1), i32x4(3, 3, 7, 5));
-        all_eq_!(simd_or(y1, y2), U32::<4>([3, 3, 7, 5]));
-        all_eq_!(simd_or(y2, y1), U32::<4>([3, 3, 7, 5]));
-
-        all_eq!(simd_xor(x1, x2), i32x4(3, 1, 7, 1));
-        all_eq!(simd_xor(x2, x1), i32x4(3, 1, 7, 1));
-        all_eq_!(simd_xor(y1, y2), U32::<4>([3, 1, 7, 1]));
-        all_eq_!(simd_xor(y2, y1), U32::<4>([3, 1, 7, 1]));
-
-        all_eq!(simd_neg(x1), i32x4(-1, -2, -3, -4));
-        all_eq!(simd_neg(x2), i32x4(-2, -3, -4, -5));
-        all_eq!(simd_neg(z1), f32x4(-1.0, -2.0, -3.0, -4.0));
-        all_eq!(simd_neg(z2), f32x4(-2.0, -3.0, -4.0, -5.0));
-
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs
deleted file mode 100644 (file)
index 8c43684..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// run-pass
-#![allow(non_camel_case_types)]
-
-// ignore-emscripten
-// ignore-endian-big behavior of simd_bitmask is endian-specific
-
-// Test that the simd_bitmask intrinsic produces correct results.
-
-#![feature(repr_simd, platform_intrinsics)]
-#[allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct u8x4(pub u8, pub u8, pub u8, pub u8);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct Tx4<T>(pub T, pub T, pub T, pub T);
-
-extern "platform-intrinsic" {
-    fn simd_bitmask<T, U>(x: T) -> U;
-}
-
-fn main() {
-    let z = u32x4(0, 0, 0, 0);
-    let ez = 0_u8;
-
-    let o = u32x4(!0, !0, !0, !0);
-    let eo = 0b_1111_u8;
-
-    let m0 = u32x4(!0, 0, !0, 0);
-    let e0 = 0b_0000_0101_u8;
-
-    // Check that the MSB is extracted:
-    let m = u8x4(0b_1000_0000, 0b_0100_0001, 0b_1100_0001, 0b_1111_1111);
-    let e = 0b_1101;
-
-    // Check usize / isize
-    let msize: Tx4<usize> = Tx4(usize::MAX, 0, usize::MAX, usize::MAX);
-
-    unsafe {
-        let r: u8 = simd_bitmask(z);
-        assert_eq!(r, ez);
-
-        let r: u8 = simd_bitmask(o);
-        assert_eq!(r, eo);
-
-        let r: u8 = simd_bitmask(m0);
-        assert_eq!(r, e0);
-
-        let r: u8 = simd_bitmask(m);
-        assert_eq!(r, e);
-
-        let r: u8 = simd_bitmask(msize);
-        assert_eq!(r, e);
-
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-cast.rs b/src/test/ui/simd/simd-intrinsic-generic-cast.rs
deleted file mode 100644 (file)
index 15f232e..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// run-pass
-#![allow(unused_must_use)]
-// ignore-emscripten FIXME(#45351) hits an LLVM assert
-
-#![feature(repr_simd, platform_intrinsics, concat_idents, test)]
-#![allow(non_camel_case_types)]
-
-extern crate test;
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct i8x4(i8, i8, i8, i8);
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct u32x4(u32, u32, u32, u32);
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct u8x4(u8, u8, u8, u8);
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct f32x4(f32, f32, f32, f32);
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct f64x4(f64, f64, f64, f64);
-
-
-extern "platform-intrinsic" {
-    fn simd_cast<T, U>(x: T) -> U;
-}
-
-const A: i32 = -1234567;
-const B: i32 = 12345678;
-const C: i32 = -123456789;
-const D: i32 = 1234567890;
-
-trait Foo {
-    fn is_float() -> bool { false }
-    fn in_range(x: i32) -> bool;
-}
-impl Foo for i32 {
-    fn in_range(_: i32) -> bool { true }
-}
-impl Foo for i8 {
-    fn in_range(x: i32) -> bool { -128 <= x && x < 128 }
-}
-impl Foo for u32 {
-    fn in_range(x: i32) -> bool { 0 <= x }
-}
-impl Foo for u8 {
-    fn in_range(x: i32) -> bool { 0 <= x && x < 128 }
-}
-impl Foo for f32 {
-    fn is_float() -> bool { true }
-    fn in_range(_: i32) -> bool { true }
-}
-impl Foo for f64 {
-    fn is_float() -> bool { true }
-    fn in_range(_: i32) -> bool { true }
-}
-
-fn main() {
-    macro_rules! test {
-        ($from: ident, $to: ident) => {{
-            // force the casts to actually happen, or else LLVM/rustc
-            // may fold them and get slightly different results.
-            let (a, b, c, d) = test::black_box((A as $from, B as $from, C as $from, D as $from));
-            // the SIMD vectors are all FOOx4, so we can concat_idents
-            // so we don't have to pass in the extra args to the macro
-            let mut from = simd_cast(concat_idents!($from, x4)(a, b, c, d));
-            let mut to = concat_idents!($to, x4)(a as $to,
-                                                 b as $to,
-                                                 c as $to,
-                                                 d as $to);
-            // assist type inference, it needs to know what `from` is
-            // for the `if` statements.
-            to == from;
-
-            // there are platform differences for some out of range
-            // casts, so we just normalize such things: it's OK for
-            // "invalid" calculations to result in nonsense answers.
-            // (e.g., negative float to unsigned integer goes through a
-            // library routine on the default i686 platforms, and the
-            // implementation of that routine differs on e.g., Linux
-            // vs. macOS, resulting in different answers.)
-            if $from::is_float() {
-                if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; }
-                if !$to::in_range(B) { from.1 = 0 as $to; to.1 = 0 as $to; }
-                if !$to::in_range(C) { from.2 = 0 as $to; to.2 = 0 as $to; }
-                if !$to::in_range(D) { from.3 = 0 as $to; to.3 = 0 as $to; }
-            }
-
-            assert!(to == from,
-                    "{} -> {} ({:?} != {:?})", stringify!($from), stringify!($to),
-                    from, to);
-        }}
-    }
-    macro_rules! tests {
-        (: $($to: ident),*) => { () };
-        // repeating the list twice is easier than writing a cartesian
-        // product macro
-        ($from: ident $(, $from_: ident)*: $($to: ident),*) => {
-            fn $from() { unsafe { $( test!($from, $to); )* } }
-            tests!($($from_),*: $($to),*)
-        };
-        ($($types: ident),*) => {{
-            tests!($($types),* : $($types),*);
-            $($types();)*
-        }}
-    }
-
-    // test various combinations, including truncation,
-    // signed/unsigned extension, and floating point casts.
-    tests!(i32, i8, u32, u8, f32);
-    tests!(i32, u32, f32, f64)
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-comparison.rs b/src/test/ui/simd/simd-intrinsic-generic-comparison.rs
deleted file mode 100644 (file)
index da5c42a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// run-pass
-// ignore-emscripten FIXME(#45351) hits an LLVM assert
-// revisions: mir thir
-// [thir]compile-flags: -Zthir-unsafeck
-
-#![feature(repr_simd, platform_intrinsics, concat_idents)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-extern "platform-intrinsic" {
-    fn simd_eq<T, U>(x: T, y: T) -> U;
-    fn simd_ne<T, U>(x: T, y: T) -> U;
-    fn simd_lt<T, U>(x: T, y: T) -> U;
-    fn simd_le<T, U>(x: T, y: T) -> U;
-    fn simd_gt<T, U>(x: T, y: T) -> U;
-    fn simd_ge<T, U>(x: T, y: T) -> U;
-}
-
-macro_rules! cmp {
-    ($method: ident($lhs: expr, $rhs: expr)) => {{
-        let lhs = $lhs;
-        let rhs = $rhs;
-        let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs);
-        // assume the scalar version is correct/the behaviour we want.
-        assert!((e.0 != 0) == lhs.0 .$method(&rhs.0));
-        assert!((e.1 != 0) == lhs.1 .$method(&rhs.1));
-        assert!((e.2 != 0) == lhs.2 .$method(&rhs.2));
-        assert!((e.3 != 0) == lhs.3 .$method(&rhs.3));
-    }}
-}
-macro_rules! tests {
-    ($($lhs: ident, $rhs: ident;)*) => {{
-        $(
-            (|| {
-                cmp!(eq($lhs, $rhs));
-                cmp!(ne($lhs, $rhs));
-
-                // test both directions
-                cmp!(lt($lhs, $rhs));
-                cmp!(lt($rhs, $lhs));
-
-                cmp!(le($lhs, $rhs));
-                cmp!(le($rhs, $lhs));
-
-                cmp!(gt($lhs, $rhs));
-                cmp!(gt($rhs, $lhs));
-
-                cmp!(ge($lhs, $rhs));
-                cmp!(ge($rhs, $lhs));
-            })();
-            )*
-    }}
-}
-fn main() {
-    // 13 vs. -100 tests that we get signed vs. unsigned comparisons
-    // correct (i32: 13 > -100, u32: 13 < -100).    let i1 = i32x4(10, -11, 12, 13);
-    let i1 = i32x4(10, -11, 12, 13);
-    let i2 = i32x4(5, -5, 20, -100);
-    let i3 = i32x4(10, -11, 20, -100);
-
-    let u1 = u32x4(10, !11+1, 12, 13);
-    let u2 = u32x4(5, !5+1, 20, !100+1);
-    let u3 = u32x4(10, !11+1, 20, !100+1);
-
-    let f1 = f32x4(10.0, -11.0, 12.0, 13.0);
-    let f2 = f32x4(5.0, -5.0, 20.0, -100.0);
-    let f3 = f32x4(10.0, -11.0, 20.0, -100.0);
-
-    unsafe {
-        tests! {
-            i1, i1;
-            u1, u1;
-            f1, f1;
-
-            i1, i2;
-            u1, u2;
-            f1, f2;
-
-            i1, i3;
-            u1, u3;
-            f1, f3;
-        }
-    }
-
-    // NAN comparisons are special:
-    // -11 (*)    13
-    // -5        -100 (*)
-    let f4 = f32x4(f32::NAN, f1.1, f32::NAN, f2.3);
-
-    unsafe {
-        tests! {
-            f1, f4;
-            f2, f4;
-            f4, f4;
-        }
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-elements.rs b/src/test/ui/simd/simd-intrinsic-generic-elements.rs
deleted file mode 100644 (file)
index 08544bc..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// run-pass
-// ignore-emscripten FIXME(#45351) hits an LLVM assert
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(incomplete_features)]
-#![feature(inline_const)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug, PartialEq)]
-#[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone, Debug, PartialEq)]
-#[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(Copy, Clone, Debug, PartialEq)]
-#[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32,
-             i32, i32, i32, i32);
-
-extern "platform-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
-
-    fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
-    fn simd_shuffle4<T, U>(x: T, y: T, idx: [u32; 4]) -> U;
-    fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
-}
-
-macro_rules! all_eq {
-    ($a: expr, $b: expr) => {{
-        let a = $a;
-        let b = $b;
-        // type inference works better with the concrete type on the
-        // left, but humans work better with the expected on the
-        // right.
-        assert!(b == a,
-                "{:?} != {:?}", a, b);
-    }}
-}
-
-fn main() {
-    let x2 = i32x2(20, 21);
-    let x4 = i32x4(40, 41, 42, 43);
-    let x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87);
-    unsafe {
-        all_eq!(simd_insert(x2, 0, 100), i32x2(100, 21));
-        all_eq!(simd_insert(x2, 1, 100), i32x2(20, 100));
-
-        all_eq!(simd_insert(x4, 0, 100), i32x4(100, 41, 42, 43));
-        all_eq!(simd_insert(x4, 1, 100), i32x4(40, 100, 42, 43));
-        all_eq!(simd_insert(x4, 2, 100), i32x4(40, 41, 100, 43));
-        all_eq!(simd_insert(x4, 3, 100), i32x4(40, 41, 42, 100));
-
-        all_eq!(simd_insert(x8, 0, 100), i32x8(100, 81, 82, 83, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 1, 100), i32x8(80, 100, 82, 83, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 2, 100), i32x8(80, 81, 100, 83, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 3, 100), i32x8(80, 81, 82, 100, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 4, 100), i32x8(80, 81, 82, 83, 100, 85, 86, 87));
-        all_eq!(simd_insert(x8, 5, 100), i32x8(80, 81, 82, 83, 84, 100, 86, 87));
-        all_eq!(simd_insert(x8, 6, 100), i32x8(80, 81, 82, 83, 84, 85, 100, 87));
-        all_eq!(simd_insert(x8, 7, 100), i32x8(80, 81, 82, 83, 84, 85, 86, 100));
-
-        all_eq!(simd_extract(x2, 0), 20);
-        all_eq!(simd_extract(x2, 1), 21);
-
-        all_eq!(simd_extract(x4, 0), 40);
-        all_eq!(simd_extract(x4, 1), 41);
-        all_eq!(simd_extract(x4, 2), 42);
-        all_eq!(simd_extract(x4, 3), 43);
-
-        all_eq!(simd_extract(x8, 0), 80);
-        all_eq!(simd_extract(x8, 1), 81);
-        all_eq!(simd_extract(x8, 2), 82);
-        all_eq!(simd_extract(x8, 3), 83);
-        all_eq!(simd_extract(x8, 4), 84);
-        all_eq!(simd_extract(x8, 5), 85);
-        all_eq!(simd_extract(x8, 6), 86);
-        all_eq!(simd_extract(x8, 7), 87);
-    }
-
-    let y2 = i32x2(120, 121);
-    let y4 = i32x4(140, 141, 142, 143);
-    let y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187);
-    unsafe {
-        all_eq!(simd_shuffle2(x2, y2, const { [3u32, 0] }), i32x2(121, 20));
-        all_eq!(simd_shuffle4(x2, y2, const { [3u32, 0, 1, 2] }), i32x4(121, 20, 21, 120));
-        all_eq!(simd_shuffle8(x2, y2, const { [3u32, 0, 1, 2, 1, 2, 3, 0] }),
-                i32x8(121, 20, 21, 120, 21, 120, 121, 20));
-
-        all_eq!(simd_shuffle2(x4, y4, const { [7u32, 2] }), i32x2(143, 42));
-        all_eq!(simd_shuffle4(x4, y4, const { [7u32, 2, 5, 0] }), i32x4(143, 42, 141, 40));
-        all_eq!(simd_shuffle8(x4, y4, const { [7u32, 2, 5, 0, 3, 6, 4, 1] }),
-                i32x8(143, 42, 141, 40, 43, 142, 140, 41));
-
-        all_eq!(simd_shuffle2(x8, y8, const { [11u32, 5] }), i32x2(183, 85));
-        all_eq!(simd_shuffle4(x8, y8, const { [11u32, 5, 15, 0] }), i32x4(183, 85, 187, 80));
-        all_eq!(simd_shuffle8(x8, y8, const { [11u32, 5, 15, 0, 3, 8, 12, 1] }),
-                i32x8(183, 85, 187, 80, 83, 180, 184, 81));
-    }
-
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-gather.rs b/src/test/ui/simd/simd-intrinsic-generic-gather.rs
deleted file mode 100644 (file)
index 805caeb..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-// run-pass
-// ignore-emscripten
-
-// Test that the simd_{gather,scatter} intrinsics produce the correct results.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct x4<T>(pub T, pub T, pub T, pub T);
-
-extern "platform-intrinsic" {
-    fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
-    fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
-}
-
-fn main() {
-    let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.];
-
-    let default = x4(-3_f32, -3., -3., -3.);
-    let s_strided = x4(0_f32, 2., -3., 6.);
-    let mask = x4(-1_i32, -1, 0, -1);
-
-    // reading from *const
-    unsafe {
-        let pointer = &x[0] as *const f32;
-        let pointers =  x4(
-            pointer.offset(0) as *const f32,
-            pointer.offset(2),
-            pointer.offset(4),
-            pointer.offset(6)
-        );
-
-        let r_strided = simd_gather(default, pointers, mask);
-
-        assert_eq!(r_strided, s_strided);
-    }
-
-    // reading from *mut
-    unsafe {
-        let pointer = &mut x[0] as *mut f32;
-        let pointers = x4(
-            pointer.offset(0) as *mut f32,
-            pointer.offset(2),
-            pointer.offset(4),
-            pointer.offset(6)
-        );
-
-        let r_strided = simd_gather(default, pointers, mask);
-
-        assert_eq!(r_strided, s_strided);
-    }
-
-    // writing to *mut
-    unsafe {
-        let pointer = &mut x[0] as *mut f32;
-        let pointers = x4(
-            pointer.offset(0) as *mut f32,
-            pointer.offset(2),
-            pointer.offset(4),
-            pointer.offset(6)
-        );
-
-        let values = x4(42_f32, 43_f32, 44_f32, 45_f32);
-        simd_scatter(values, pointers, mask);
-
-        assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]);
-    }
-
-    // test modifying array of *const f32
-    let mut y = [
-        &x[0] as *const f32,
-        &x[1] as *const f32,
-        &x[2] as *const f32,
-        &x[3] as *const f32,
-        &x[4] as *const f32,
-        &x[5] as *const f32,
-        &x[6] as *const f32,
-        &x[7] as *const f32
-    ];
-
-    let default = x4(y[0], y[0], y[0], y[0]);
-    let s_strided = x4(y[0], y[2], y[0], y[6]);
-
-    // reading from *const
-    unsafe {
-        let pointer = &y[0] as *const *const f32;
-        let pointers = x4(
-            pointer.offset(0) as *const *const f32,
-            pointer.offset(2),
-            pointer.offset(4),
-            pointer.offset(6)
-        );
-
-        let r_strided = simd_gather(default, pointers, mask);
-
-        assert_eq!(r_strided, s_strided);
-    }
-
-    // reading from *mut
-    unsafe {
-        let pointer = &mut y[0] as *mut *const f32;
-        let pointers = x4(
-            pointer.offset(0) as *mut *const f32,
-            pointer.offset(2),
-            pointer.offset(4),
-            pointer.offset(6)
-        );
-
-        let r_strided = simd_gather(default, pointers, mask);
-
-        assert_eq!(r_strided, s_strided);
-    }
-
-    // writing to *mut
-    unsafe {
-        let pointer = &mut y[0] as *mut *const f32;
-        let pointers = x4(
-            pointer.offset(0) as *mut *const f32,
-            pointer.offset(2),
-            pointer.offset(4),
-            pointer.offset(6)
-        );
-
-        let values = x4(y[7], y[6], y[5], y[1]);
-        simd_scatter(values, pointers, mask);
-
-        let s = [
-            &x[7] as *const f32,
-            &x[1] as *const f32,
-            &x[6] as *const f32,
-            &x[3] as *const f32,
-            &x[4] as *const f32,
-            &x[5] as *const f32,
-            &x[1] as *const f32,
-            &x[7] as *const f32
-        ];
-        assert_eq!(y, s);
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs
deleted file mode 100644 (file)
index 7193fb3..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-// run-pass
-#![allow(non_camel_case_types)]
-
-// ignore-emscripten
-
-// Test that the simd_reduce_{op} intrinsics produce the correct results.
-
-#![feature(repr_simd, platform_intrinsics)]
-#[allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct b8x4(pub i8, pub i8, pub i8, pub i8);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct b8x16(
-    pub i8, pub i8, pub i8, pub i8,
-    pub i8, pub i8, pub i8, pub i8,
-    pub i8, pub i8, pub i8, pub i8,
-    pub i8, pub i8, pub i8, pub i8
-);
-
-extern "platform-intrinsic" {
-    fn simd_reduce_add_unordered<T, U>(x: T) -> U;
-    fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
-    fn simd_reduce_add_ordered<T, U>(x: T, acc: U) -> U;
-    fn simd_reduce_mul_ordered<T, U>(x: T, acc: U) -> U;
-    fn simd_reduce_min<T, U>(x: T) -> U;
-    fn simd_reduce_max<T, U>(x: T) -> U;
-    fn simd_reduce_min_nanless<T, U>(x: T) -> U;
-    fn simd_reduce_max_nanless<T, U>(x: T) -> U;
-    fn simd_reduce_and<T, U>(x: T) -> U;
-    fn simd_reduce_or<T, U>(x: T) -> U;
-    fn simd_reduce_xor<T, U>(x: T) -> U;
-    fn simd_reduce_all<T>(x: T) -> bool;
-    fn simd_reduce_any<T>(x: T) -> bool;
-}
-
-fn main() {
-    unsafe {
-        let x = i32x4(1, -2, 3, 4);
-        let r: i32 = simd_reduce_add_unordered(x);
-        assert_eq!(r, 6_i32);
-        let r: i32 = simd_reduce_mul_unordered(x);
-        assert_eq!(r, -24_i32);
-        let r: i32 = simd_reduce_add_ordered(x, -1);
-        assert_eq!(r, 5_i32);
-        let r: i32 = simd_reduce_mul_ordered(x, -1);
-        assert_eq!(r, 24_i32);
-
-        let r: i32 = simd_reduce_min(x);
-        assert_eq!(r, -2_i32);
-        let r: i32 = simd_reduce_max(x);
-        assert_eq!(r, 4_i32);
-
-        let x = i32x4(-1, -1, -1, -1);
-        let r: i32 = simd_reduce_and(x);
-        assert_eq!(r, -1_i32);
-        let r: i32 = simd_reduce_or(x);
-        assert_eq!(r, -1_i32);
-        let r: i32 = simd_reduce_xor(x);
-        assert_eq!(r, 0_i32);
-
-        let x = i32x4(-1, -1, 0, -1);
-        let r: i32 = simd_reduce_and(x);
-        assert_eq!(r, 0_i32);
-        let r: i32 = simd_reduce_or(x);
-        assert_eq!(r, -1_i32);
-        let r: i32 = simd_reduce_xor(x);
-        assert_eq!(r, -1_i32);
-    }
-
-    unsafe {
-        let x = u32x4(1, 2, 3, 4);
-        let r: u32 = simd_reduce_add_unordered(x);
-        assert_eq!(r, 10_u32);
-        let r: u32 = simd_reduce_mul_unordered(x);
-        assert_eq!(r, 24_u32);
-        let r: u32 = simd_reduce_add_ordered(x, 1);
-        assert_eq!(r, 11_u32);
-        let r: u32 = simd_reduce_mul_ordered(x, 2);
-        assert_eq!(r, 48_u32);
-
-        let r: u32 = simd_reduce_min(x);
-        assert_eq!(r, 1_u32);
-        let r: u32 = simd_reduce_max(x);
-        assert_eq!(r, 4_u32);
-
-        let t = u32::MAX;
-        let x = u32x4(t, t, t, t);
-        let r: u32 = simd_reduce_and(x);
-        assert_eq!(r, t);
-        let r: u32 = simd_reduce_or(x);
-        assert_eq!(r, t);
-        let r: u32 = simd_reduce_xor(x);
-        assert_eq!(r, 0_u32);
-
-        let x = u32x4(t, t, 0, t);
-        let r: u32 = simd_reduce_and(x);
-        assert_eq!(r, 0_u32);
-        let r: u32 = simd_reduce_or(x);
-        assert_eq!(r, t);
-        let r: u32 = simd_reduce_xor(x);
-        assert_eq!(r, t);
-    }
-
-    unsafe {
-        let x = f32x4(1., -2., 3., 4.);
-        let r: f32 = simd_reduce_add_unordered(x);
-        assert_eq!(r, 6_f32);
-        let r: f32 = simd_reduce_mul_unordered(x);
-        assert_eq!(r, -24_f32);
-        let r: f32 = simd_reduce_add_ordered(x, 0.);
-        assert_eq!(r, 6_f32);
-        let r: f32 = simd_reduce_mul_ordered(x, 1.);
-        assert_eq!(r, -24_f32);
-        let r: f32 = simd_reduce_add_ordered(x, 1.);
-        assert_eq!(r, 7_f32);
-        let r: f32 = simd_reduce_mul_ordered(x, 2.);
-        assert_eq!(r, -48_f32);
-
-        let r: f32 = simd_reduce_min(x);
-        assert_eq!(r, -2_f32);
-        let r: f32 = simd_reduce_max(x);
-        assert_eq!(r, 4_f32);
-        let r: f32 = simd_reduce_min_nanless(x);
-        assert_eq!(r, -2_f32);
-        let r: f32 = simd_reduce_max_nanless(x);
-        assert_eq!(r, 4_f32);
-    }
-
-    unsafe {
-        let x = b8x4(!0, !0, !0, !0);
-        let r: bool = simd_reduce_all(x);
-        assert_eq!(r, true);
-        let r: bool = simd_reduce_any(x);
-        assert_eq!(r, true);
-
-        let x = b8x4(!0, !0, 0, !0);
-        let r: bool = simd_reduce_all(x);
-        assert_eq!(r, false);
-        let r: bool = simd_reduce_any(x);
-        assert_eq!(r, true);
-
-        let x = b8x4(0, 0, 0, 0);
-        let r: bool = simd_reduce_all(x);
-        assert_eq!(r, false);
-        let r: bool = simd_reduce_any(x);
-        assert_eq!(r, false);
-    }
-}
diff --git a/src/test/ui/simd/simd-intrinsic-generic-select.rs b/src/test/ui/simd/simd-intrinsic-generic-select.rs
deleted file mode 100644 (file)
index b850cf9..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-// run-pass
-#![allow(non_camel_case_types)]
-
-// ignore-emscripten
-// ignore-endian-big behavior of simd_select_bitmask is endian-specific
-
-// Test that the simd_select intrinsics produces correct results.
-
-#![feature(repr_simd, platform_intrinsics)]
-#[allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, PartialEq, Debug)]
-struct b8x4(pub i8, pub i8, pub i8, pub i8);
-
-extern "platform-intrinsic" {
-    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
-    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
-}
-
-fn main() {
-    let m0 = b8x4(!0, !0, !0, !0);
-    let m1 = b8x4(0, 0, 0, 0);
-    let m2 = b8x4(!0, !0, 0, 0);
-    let m3 = b8x4(0, 0, !0, !0);
-    let m4 = b8x4(!0, 0, !0, 0);
-
-    unsafe {
-        let a = i32x4(1, -2, 3, 4);
-        let b = i32x4(5, 6, -7, 8);
-
-        let r: i32x4 = simd_select(m0, a, b);
-        let e = a;
-        assert_eq!(r, e);
-
-        let r: i32x4 = simd_select(m1, a, b);
-        let e = b;
-        assert_eq!(r, e);
-
-        let r: i32x4 = simd_select(m2, a, b);
-        let e = i32x4(1, -2, -7, 8);
-        assert_eq!(r, e);
-
-        let r: i32x4 = simd_select(m3, a, b);
-        let e = i32x4(5, 6, 3, 4);
-        assert_eq!(r, e);
-
-        let r: i32x4 = simd_select(m4, a, b);
-        let e = i32x4(1, 6, 3, 8);
-        assert_eq!(r, e);
-    }
-
-    unsafe {
-        let a = u32x4(1, 2, 3, 4);
-        let b = u32x4(5, 6, 7, 8);
-
-        let r: u32x4 = simd_select(m0, a, b);
-        let e = a;
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select(m1, a, b);
-        let e = b;
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select(m2, a, b);
-        let e = u32x4(1, 2, 7, 8);
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select(m3, a, b);
-        let e = u32x4(5, 6, 3, 4);
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select(m4, a, b);
-        let e = u32x4(1, 6, 3, 8);
-        assert_eq!(r, e);
-    }
-
-    unsafe {
-        let a = f32x4(1., 2., 3., 4.);
-        let b = f32x4(5., 6., 7., 8.);
-
-        let r: f32x4 = simd_select(m0, a, b);
-        let e = a;
-        assert_eq!(r, e);
-
-        let r: f32x4 = simd_select(m1, a, b);
-        let e = b;
-        assert_eq!(r, e);
-
-        let r: f32x4 = simd_select(m2, a, b);
-        let e = f32x4(1., 2., 7., 8.);
-        assert_eq!(r, e);
-
-        let r: f32x4 = simd_select(m3, a, b);
-        let e = f32x4(5., 6., 3., 4.);
-        assert_eq!(r, e);
-
-        let r: f32x4 = simd_select(m4, a, b);
-        let e = f32x4(1., 6., 3., 8.);
-        assert_eq!(r, e);
-    }
-
-    unsafe {
-        let t = !0 as i8;
-        let f = 0 as i8;
-        let a = b8x4(t, f, t, f);
-        let b = b8x4(f, f, f, t);
-
-        let r: b8x4 = simd_select(m0, a, b);
-        let e = a;
-        assert_eq!(r, e);
-
-        let r: b8x4 = simd_select(m1, a, b);
-        let e = b;
-        assert_eq!(r, e);
-
-        let r: b8x4 = simd_select(m2, a, b);
-        let e = b8x4(t, f, f, t);
-        assert_eq!(r, e);
-
-        let r: b8x4 = simd_select(m3, a, b);
-        let e = b8x4(f, f, t, f);
-        assert_eq!(r, e);
-
-        let r: b8x4 = simd_select(m4, a, b);
-        let e = b8x4(t, f, t, t);
-        assert_eq!(r, e);
-    }
-
-    unsafe {
-        let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7);
-        let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15);
-
-        let r: u32x8 = simd_select_bitmask(0u8, a, b);
-        let e = b;
-        assert_eq!(r, e);
-
-        let r: u32x8 = simd_select_bitmask(0xffu8, a, b);
-        let e = a;
-        assert_eq!(r, e);
-
-        let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b);
-        let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15);
-        assert_eq!(r, e);
-
-        let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b);
-        let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7);
-        assert_eq!(r, e);
-
-        let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b);
-        let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7);
-        assert_eq!(r, e);
-    }
-
-    unsafe {
-        let a = u32x4(0, 1, 2, 3);
-        let b = u32x4(4, 5, 6, 7);
-
-        let r: u32x4 = simd_select_bitmask(0u8, a, b);
-        let e = b;
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select_bitmask(0xfu8, a, b);
-        let e = a;
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select_bitmask(0b0101u8, a, b);
-        let e = u32x4(0, 5, 2, 7);
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select_bitmask(0b1010u8, a, b);
-        let e = u32x4(4, 1, 6, 3);
-        assert_eq!(r, e);
-
-        let r: u32x4 = simd_select_bitmask(0b1100u8, a, b);
-        let e = u32x4(4, 5, 2, 3);
-        assert_eq!(r, e);
-    }
-}
diff --git a/src/test/ui/simd/simd-size-align.rs b/src/test/ui/simd/simd-size-align.rs
deleted file mode 100644 (file)
index 0afa494..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// run-pass
-#![allow(deprecated)]
-
-
-#![feature(repr_simd)]
-#![allow(non_camel_case_types)]
-
-use std::mem;
-
-/// `T` should satisfy `size_of T (mod min_align_of T) === 0` to be stored at `Vec<T>` properly
-/// Please consult the issue #20460
-fn check<T>() {
-    assert_eq!(mem::size_of::<T>() % mem::min_align_of::<T>(), 0);
-    assert_eq!(mem::size_of::<T>() % mem::min_align_of::<T>(), 0);
-    assert_eq!(mem::size_of::<T>() % mem::min_align_of::<T>(), 0);
-}
-
-#[repr(simd)]
-struct U8<const N: usize>([u8; N]);
-
-#[repr(simd)]
-struct I16<const N: usize>([i16; N]);
-
-#[repr(simd)]
-struct F32<const N: usize>([f32; N]);
-
-#[repr(simd)]
-struct Usize<const N: usize>([usize; N]);
-
-#[repr(simd)]
-struct Isize<const N: usize>([isize; N]);
-
-fn main() {
-    check::<U8<2>>();
-    check::<U8<4>>();
-    check::<U8<8>>();
-
-    check::<I16<2>>();
-    check::<I16<4>>();
-    check::<I16<8>>();
-
-    check::<F32<2>>();
-    check::<F32<4>>();
-    check::<F32<8>>();
-
-    check::<Usize<2>>();
-    check::<Usize<4>>();
-    check::<Usize<8>>();
-
-    check::<Isize<2>>();
-    check::<Isize<4>>();
-    check::<Isize<8>>();
-}
diff --git a/src/test/ui/simd/simd-target-feature-mixup.rs b/src/test/ui/simd/simd-target-feature-mixup.rs
deleted file mode 100644 (file)
index 6d76881..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-// run-pass
-#![allow(unused_variables)]
-#![allow(stable_features)]
-#![allow(overflowing_literals)]
-
-// ignore-emscripten
-// ignore-sgx no processes
-
-#![feature(repr_simd, target_feature, cfg_target_feature)]
-#![feature(avx512_target_feature)]
-
-use std::process::{Command, ExitStatus};
-use std::env;
-
-fn main() {
-    if let Some(level) = env::args().nth(1) {
-        return test::main(&level)
-    }
-
-    let me = env::current_exe().unwrap();
-    for level in ["sse", "avx", "avx512"].iter() {
-        let status = Command::new(&me).arg(level).status().unwrap();
-        if status.success() {
-            println!("success with {}", level);
-            continue
-        }
-
-        // We don't actually know if our computer has the requisite target features
-        // for the test below. Testing for that will get added to libstd later so
-        // for now just assume sigill means this is a machine that can't run this test.
-        if is_sigill(status) {
-            println!("sigill with {}, assuming spurious", level);
-            continue
-        }
-        panic!("invalid status at {}: {}", level, status);
-    }
-}
-
-#[cfg(unix)]
-fn is_sigill(status: ExitStatus) -> bool {
-    use std::os::unix::prelude::*;
-    status.signal() == Some(4)
-}
-
-#[cfg(windows)]
-fn is_sigill(status: ExitStatus) -> bool {
-    status.code() == Some(0xc000001d)
-}
-
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-#[allow(nonstandard_style)]
-mod test {
-    // An SSE type
-    #[repr(simd)]
-    #[derive(PartialEq, Debug, Clone, Copy)]
-    struct __m128i(u64, u64);
-
-    // An AVX type
-    #[repr(simd)]
-    #[derive(PartialEq, Debug, Clone, Copy)]
-    struct __m256i(u64, u64, u64, u64);
-
-    // An AVX-512 type
-    #[repr(simd)]
-    #[derive(PartialEq, Debug, Clone, Copy)]
-    struct __m512i(u64, u64, u64, u64, u64, u64, u64, u64);
-
-    pub fn main(level: &str) {
-        unsafe {
-            main_normal(level);
-            main_sse(level);
-            if level == "sse" {
-                return
-            }
-            main_avx(level);
-            if level == "avx" {
-                return
-            }
-            main_avx512(level);
-        }
-    }
-
-    macro_rules! mains {
-        ($(
-            $(#[$attr:meta])*
-            unsafe fn $main:ident(level: &str) {
-                ...
-            }
-        )*) => ($(
-            $(#[$attr])*
-            unsafe fn $main(level: &str) {
-                let m128 = __m128i(1, 2);
-                let m256 = __m256i(3, 4, 5, 6);
-                let m512 = __m512i(7, 8, 9, 10, 11, 12, 13, 14);
-                assert_eq!(id_sse_128(m128), m128);
-                assert_eq!(id_sse_256(m256), m256);
-                assert_eq!(id_sse_512(m512), m512);
-
-                if level == "sse" {
-                    return
-                }
-                assert_eq!(id_avx_128(m128), m128);
-                assert_eq!(id_avx_256(m256), m256);
-                assert_eq!(id_avx_512(m512), m512);
-
-                if level == "avx" {
-                    return
-                }
-                assert_eq!(id_avx512_128(m128), m128);
-                assert_eq!(id_avx512_256(m256), m256);
-                assert_eq!(id_avx512_512(m512), m512);
-            }
-        )*)
-    }
-
-    mains! {
-        unsafe fn main_normal(level: &str) { ... }
-        #[target_feature(enable = "sse2")]
-        unsafe fn main_sse(level: &str) { ... }
-        #[target_feature(enable = "avx")]
-        unsafe fn main_avx(level: &str) { ... }
-        #[target_feature(enable = "avx512bw")]
-        unsafe fn main_avx512(level: &str) { ... }
-    }
-
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn id_sse_128(a: __m128i) -> __m128i {
-        assert_eq!(a, __m128i(1, 2));
-        a.clone()
-    }
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn id_sse_256(a: __m256i) -> __m256i {
-        assert_eq!(a, __m256i(3, 4, 5, 6));
-        a.clone()
-    }
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn id_sse_512(a: __m512i) -> __m512i {
-        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
-        a.clone()
-    }
-
-    #[target_feature(enable = "avx")]
-    unsafe fn id_avx_128(a: __m128i) -> __m128i {
-        assert_eq!(a, __m128i(1, 2));
-        a.clone()
-    }
-
-    #[target_feature(enable = "avx")]
-    unsafe fn id_avx_256(a: __m256i) -> __m256i {
-        assert_eq!(a, __m256i(3, 4, 5, 6));
-        a.clone()
-    }
-
-    #[target_feature(enable = "avx")]
-    unsafe fn id_avx_512(a: __m512i) -> __m512i {
-        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
-        a.clone()
-    }
-
-    #[target_feature(enable = "avx512bw")]
-    unsafe fn id_avx512_128(a: __m128i) -> __m128i {
-        assert_eq!(a, __m128i(1, 2));
-        a.clone()
-    }
-
-    #[target_feature(enable = "avx512bw")]
-    unsafe fn id_avx512_256(a: __m256i) -> __m256i {
-        assert_eq!(a, __m256i(3, 4, 5, 6));
-        a.clone()
-    }
-
-    #[target_feature(enable = "avx512bw")]
-    unsafe fn id_avx512_512(a: __m512i) -> __m512i {
-        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
-        a.clone()
-    }
-}
-
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-mod test {
-    pub fn main(level: &str) {}
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-empty.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-empty.rs
deleted file mode 100644 (file)
index 0121404..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics)]
-
-// error-pattern:monomorphising SIMD type `Simd<0_usize>` of zero length
-
-#[repr(simd)]
-struct Simd<const N: usize>([f32; N]);
-
-fn main() {
-    let _ = Simd::<0>([]);
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-empty.stderr b/src/test/ui/simd/simd-type-generic-monomorphisation-empty.stderr
deleted file mode 100644 (file)
index 00fde19..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: monomorphising SIMD type `Simd<0_usize>` of zero length
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-extern-nonnull-ptr.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-extern-nonnull-ptr.rs
deleted file mode 100644 (file)
index ae321c9..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// run-pass
-// ignore-emscripten
-
-#![feature(extern_types)]
-#![feature(repr_simd)]
-
-use std::ptr::NonNull;
-
-extern {
-    type Extern;
-}
-
-#[repr(simd)]
-struct S<T>(T);
-
-#[inline(never)]
-fn identity<T>(v: T) -> T {
-    v
-}
-
-fn main() {
-    let _v: S<[Option<NonNull<Extern>>; 4]> = identity(S([None; 4]));
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs
deleted file mode 100644 (file)
index 0bc73b1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// build-fail
-
-#![feature(repr_simd)]
-
-struct E;
-
-// error-pattern:monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
-
-#[repr(simd)]
-struct S<T>([T; 4]);
-
-fn main() {
-    let _v: Option<S<E>> = None;
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr b/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr
deleted file mode 100644 (file)
index 9e8f06b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.rs
deleted file mode 100644 (file)
index bd0d457..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics)]
-
-// error-pattern:monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768
-
-#[repr(simd)]
-struct Simd<const N: usize>([f32; N]);
-
-fn main() {
-    let _ = Simd::<65536>([0.; 65536]);
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.stderr b/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.stderr
deleted file mode 100644 (file)
index f441835..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-power-of-two.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-power-of-two.rs
deleted file mode 100644 (file)
index 9b645d3..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// run-pass
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-struct Simd<const N: usize>([f32; N]);
-
-fn main() {
-    let _ = Simd::<3>([0.; 3]);
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.rs
deleted file mode 100644 (file)
index 3e02b08..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// build-fail
-
-#![feature(repr_simd)]
-
-// error-pattern:monomorphising SIMD type `S<[*mut [u8]; 4]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
-#[repr(simd)]
-struct S<T>(T);
-
-fn main() {
-    let _v: Option<S<[*mut [u8]; 4]>> = None;
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.stderr b/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.stderr
deleted file mode 100644 (file)
index 3888e7a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: monomorphising SIMD type `S<[*mut [u8]; 4]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation.rs b/src/test/ui/simd/simd-type-generic-monomorphisation.rs
deleted file mode 100644 (file)
index 12f9d65..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// build-fail
-
-#![feature(repr_simd, platform_intrinsics)]
-
-
-// error-pattern:monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
-
-struct X(Vec<i32>);
-#[repr(simd)]
-struct Simd2<T>(T, T);
-
-fn main() {
-    let _ = Simd2(X(vec![]), X(vec![]));
-}
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation.stderr b/src/test/ui/simd/simd-type-generic-monomorphisation.stderr
deleted file mode 100644 (file)
index 7f23893..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-type-wide-ptr.rs b/src/test/ui/simd/simd-type-wide-ptr.rs
deleted file mode 100644 (file)
index 88f62a0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// build-fail
-
-#![feature(repr_simd)]
-
-// error-pattern:monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
-#[repr(simd)]
-struct S([*mut [u8]; 4]);
-
-fn main() {
-    let _v: Option<S> = None;
-}
diff --git a/src/test/ui/simd/simd-type-wide-ptr.stderr b/src/test/ui/simd/simd-type-wide-ptr.stderr
deleted file mode 100644 (file)
index 51d3c00..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-error: monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/simd/simd-type.rs b/src/test/ui/simd/simd-type.rs
deleted file mode 100644 (file)
index d82c70b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#![feature(repr_simd)]
-#![allow(non_camel_case_types)]
-
-
-#[repr(simd)]
-struct empty; //~ ERROR SIMD vector cannot be empty
-
-#[repr(simd)]
-struct empty2([f32; 0]); //~ ERROR SIMD vector cannot be empty
-
-#[repr(simd)]
-struct pow2([f32; 7]);
-
-#[repr(simd)]
-struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous
-
-struct Foo;
-
-#[repr(simd)]
-struct FooV(Foo, Foo); //~ ERROR SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-
-#[repr(simd)]
-struct FooV2([Foo; 2]); //~ ERROR SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-
-#[repr(simd)]
-struct TooBig([f32; 65536]); //~ ERROR SIMD vector cannot have more than 32768 elements
-
-#[repr(simd)]
-struct JustRight([u128; 32768]);
-
-#[repr(simd)]
-struct RGBA {
-    r: f32,
-    g: f32,
-    b: f32,
-    a: f32
-}
-
-fn main() {}
diff --git a/src/test/ui/simd/simd-type.stderr b/src/test/ui/simd/simd-type.stderr
deleted file mode 100644 (file)
index 4e4a19e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-error[E0075]: SIMD vector cannot be empty
-  --> $DIR/simd-type.rs:6:1
-   |
-LL | struct empty;
-   | ^^^^^^^^^^^^^
-
-error[E0075]: SIMD vector cannot be empty
-  --> $DIR/simd-type.rs:9:1
-   |
-LL | struct empty2([f32; 0]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0076]: SIMD vector should be homogeneous
-  --> $DIR/simd-type.rs:15:1
-   |
-LL | struct i64f64(i64, f64);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type
-
-error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/simd-type.rs:20:1
-   |
-LL | struct FooV(Foo, Foo);
-   | ^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/simd-type.rs:23:1
-   |
-LL | struct FooV2([Foo; 2]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0075]: SIMD vector cannot have more than 32768 elements
-  --> $DIR/simd-type.rs:26:1
-   |
-LL | struct TooBig([f32; 65536]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 6 previous errors
-
-Some errors have detailed explanations: E0075, E0076, E0077.
-For more information about an error, try `rustc --explain E0075`.
diff --git a/src/test/ui/simd/size-align.rs b/src/test/ui/simd/size-align.rs
new file mode 100644 (file)
index 0000000..0afa494
--- /dev/null
@@ -0,0 +1,53 @@
+// run-pass
+#![allow(deprecated)]
+
+
+#![feature(repr_simd)]
+#![allow(non_camel_case_types)]
+
+use std::mem;
+
+/// `T` should satisfy `size_of T (mod min_align_of T) === 0` to be stored at `Vec<T>` properly
+/// Please consult the issue #20460
+fn check<T>() {
+    assert_eq!(mem::size_of::<T>() % mem::min_align_of::<T>(), 0);
+    assert_eq!(mem::size_of::<T>() % mem::min_align_of::<T>(), 0);
+    assert_eq!(mem::size_of::<T>() % mem::min_align_of::<T>(), 0);
+}
+
+#[repr(simd)]
+struct U8<const N: usize>([u8; N]);
+
+#[repr(simd)]
+struct I16<const N: usize>([i16; N]);
+
+#[repr(simd)]
+struct F32<const N: usize>([f32; N]);
+
+#[repr(simd)]
+struct Usize<const N: usize>([usize; N]);
+
+#[repr(simd)]
+struct Isize<const N: usize>([isize; N]);
+
+fn main() {
+    check::<U8<2>>();
+    check::<U8<4>>();
+    check::<U8<8>>();
+
+    check::<I16<2>>();
+    check::<I16<4>>();
+    check::<I16<8>>();
+
+    check::<F32<2>>();
+    check::<F32<4>>();
+    check::<F32<8>>();
+
+    check::<Usize<2>>();
+    check::<Usize<4>>();
+    check::<Usize<8>>();
+
+    check::<Isize<2>>();
+    check::<Isize<4>>();
+    check::<Isize<8>>();
+}
diff --git a/src/test/ui/simd/target-feature-mixup.rs b/src/test/ui/simd/target-feature-mixup.rs
new file mode 100644 (file)
index 0000000..6d76881
--- /dev/null
@@ -0,0 +1,185 @@
+// run-pass
+#![allow(unused_variables)]
+#![allow(stable_features)]
+#![allow(overflowing_literals)]
+
+// ignore-emscripten
+// ignore-sgx no processes
+
+#![feature(repr_simd, target_feature, cfg_target_feature)]
+#![feature(avx512_target_feature)]
+
+use std::process::{Command, ExitStatus};
+use std::env;
+
+fn main() {
+    if let Some(level) = env::args().nth(1) {
+        return test::main(&level)
+    }
+
+    let me = env::current_exe().unwrap();
+    for level in ["sse", "avx", "avx512"].iter() {
+        let status = Command::new(&me).arg(level).status().unwrap();
+        if status.success() {
+            println!("success with {}", level);
+            continue
+        }
+
+        // We don't actually know if our computer has the requisite target features
+        // for the test below. Testing for that will get added to libstd later so
+        // for now just assume sigill means this is a machine that can't run this test.
+        if is_sigill(status) {
+            println!("sigill with {}, assuming spurious", level);
+            continue
+        }
+        panic!("invalid status at {}: {}", level, status);
+    }
+}
+
+#[cfg(unix)]
+fn is_sigill(status: ExitStatus) -> bool {
+    use std::os::unix::prelude::*;
+    status.signal() == Some(4)
+}
+
+#[cfg(windows)]
+fn is_sigill(status: ExitStatus) -> bool {
+    status.code() == Some(0xc000001d)
+}
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+#[allow(nonstandard_style)]
+mod test {
+    // An SSE type
+    #[repr(simd)]
+    #[derive(PartialEq, Debug, Clone, Copy)]
+    struct __m128i(u64, u64);
+
+    // An AVX type
+    #[repr(simd)]
+    #[derive(PartialEq, Debug, Clone, Copy)]
+    struct __m256i(u64, u64, u64, u64);
+
+    // An AVX-512 type
+    #[repr(simd)]
+    #[derive(PartialEq, Debug, Clone, Copy)]
+    struct __m512i(u64, u64, u64, u64, u64, u64, u64, u64);
+
+    pub fn main(level: &str) {
+        unsafe {
+            main_normal(level);
+            main_sse(level);
+            if level == "sse" {
+                return
+            }
+            main_avx(level);
+            if level == "avx" {
+                return
+            }
+            main_avx512(level);
+        }
+    }
+
+    macro_rules! mains {
+        ($(
+            $(#[$attr:meta])*
+            unsafe fn $main:ident(level: &str) {
+                ...
+            }
+        )*) => ($(
+            $(#[$attr])*
+            unsafe fn $main(level: &str) {
+                let m128 = __m128i(1, 2);
+                let m256 = __m256i(3, 4, 5, 6);
+                let m512 = __m512i(7, 8, 9, 10, 11, 12, 13, 14);
+                assert_eq!(id_sse_128(m128), m128);
+                assert_eq!(id_sse_256(m256), m256);
+                assert_eq!(id_sse_512(m512), m512);
+
+                if level == "sse" {
+                    return
+                }
+                assert_eq!(id_avx_128(m128), m128);
+                assert_eq!(id_avx_256(m256), m256);
+                assert_eq!(id_avx_512(m512), m512);
+
+                if level == "avx" {
+                    return
+                }
+                assert_eq!(id_avx512_128(m128), m128);
+                assert_eq!(id_avx512_256(m256), m256);
+                assert_eq!(id_avx512_512(m512), m512);
+            }
+        )*)
+    }
+
+    mains! {
+        unsafe fn main_normal(level: &str) { ... }
+        #[target_feature(enable = "sse2")]
+        unsafe fn main_sse(level: &str) { ... }
+        #[target_feature(enable = "avx")]
+        unsafe fn main_avx(level: &str) { ... }
+        #[target_feature(enable = "avx512bw")]
+        unsafe fn main_avx512(level: &str) { ... }
+    }
+
+
+    #[target_feature(enable = "sse2")]
+    unsafe fn id_sse_128(a: __m128i) -> __m128i {
+        assert_eq!(a, __m128i(1, 2));
+        a.clone()
+    }
+
+    #[target_feature(enable = "sse2")]
+    unsafe fn id_sse_256(a: __m256i) -> __m256i {
+        assert_eq!(a, __m256i(3, 4, 5, 6));
+        a.clone()
+    }
+
+    #[target_feature(enable = "sse2")]
+    unsafe fn id_sse_512(a: __m512i) -> __m512i {
+        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+        a.clone()
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn id_avx_128(a: __m128i) -> __m128i {
+        assert_eq!(a, __m128i(1, 2));
+        a.clone()
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn id_avx_256(a: __m256i) -> __m256i {
+        assert_eq!(a, __m256i(3, 4, 5, 6));
+        a.clone()
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn id_avx_512(a: __m512i) -> __m512i {
+        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+        a.clone()
+    }
+
+    #[target_feature(enable = "avx512bw")]
+    unsafe fn id_avx512_128(a: __m128i) -> __m128i {
+        assert_eq!(a, __m128i(1, 2));
+        a.clone()
+    }
+
+    #[target_feature(enable = "avx512bw")]
+    unsafe fn id_avx512_256(a: __m256i) -> __m256i {
+        assert_eq!(a, __m256i(3, 4, 5, 6));
+        a.clone()
+    }
+
+    #[target_feature(enable = "avx512bw")]
+    unsafe fn id_avx512_512(a: __m512i) -> __m512i {
+        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+        a.clone()
+    }
+}
+
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+mod test {
+    pub fn main(level: &str) {}
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-empty.rs b/src/test/ui/simd/type-generic-monomorphisation-empty.rs
new file mode 100644 (file)
index 0000000..0121404
--- /dev/null
@@ -0,0 +1,12 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics)]
+
+// error-pattern:monomorphising SIMD type `Simd<0_usize>` of zero length
+
+#[repr(simd)]
+struct Simd<const N: usize>([f32; N]);
+
+fn main() {
+    let _ = Simd::<0>([]);
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-empty.stderr b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr
new file mode 100644 (file)
index 0000000..00fde19
--- /dev/null
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `Simd<0_usize>` of zero length
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs b/src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
new file mode 100644 (file)
index 0000000..ae321c9
--- /dev/null
@@ -0,0 +1,23 @@
+// run-pass
+// ignore-emscripten
+
+#![feature(extern_types)]
+#![feature(repr_simd)]
+
+use std::ptr::NonNull;
+
+extern {
+    type Extern;
+}
+
+#[repr(simd)]
+struct S<T>(T);
+
+#[inline(never)]
+fn identity<T>(v: T) -> T {
+    v
+}
+
+fn main() {
+    let _v: S<[Option<NonNull<Extern>>; 4]> = identity(S([None; 4]));
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-non-primitive.rs b/src/test/ui/simd/type-generic-monomorphisation-non-primitive.rs
new file mode 100644 (file)
index 0000000..0bc73b1
--- /dev/null
@@ -0,0 +1,14 @@
+// build-fail
+
+#![feature(repr_simd)]
+
+struct E;
+
+// error-pattern:monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
+
+#[repr(simd)]
+struct S<T>([T; 4]);
+
+fn main() {
+    let _v: Option<S<E>> = None;
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-non-primitive.stderr b/src/test/ui/simd/type-generic-monomorphisation-non-primitive.stderr
new file mode 100644 (file)
index 0000000..9e8f06b
--- /dev/null
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/simd/type-generic-monomorphisation-oversized.rs b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs
new file mode 100644 (file)
index 0000000..bd0d457
--- /dev/null
@@ -0,0 +1,12 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics)]
+
+// error-pattern:monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768
+
+#[repr(simd)]
+struct Simd<const N: usize>([f32; N]);
+
+fn main() {
+    let _ = Simd::<65536>([0.; 65536]);
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr
new file mode 100644 (file)
index 0000000..f441835
--- /dev/null
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/simd/type-generic-monomorphisation-power-of-two.rs b/src/test/ui/simd/type-generic-monomorphisation-power-of-two.rs
new file mode 100644 (file)
index 0000000..9b645d3
--- /dev/null
@@ -0,0 +1,10 @@
+// run-pass
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+struct Simd<const N: usize>([f32; N]);
+
+fn main() {
+    let _ = Simd::<3>([0.; 3]);
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.rs b/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.rs
new file mode 100644 (file)
index 0000000..3e02b08
--- /dev/null
@@ -0,0 +1,12 @@
+// build-fail
+
+#![feature(repr_simd)]
+
+// error-pattern:monomorphising SIMD type `S<[*mut [u8]; 4]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+
+#[repr(simd)]
+struct S<T>(T);
+
+fn main() {
+    let _v: Option<S<[*mut [u8]; 4]>> = None;
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.stderr b/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.stderr
new file mode 100644 (file)
index 0000000..3888e7a
--- /dev/null
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `S<[*mut [u8]; 4]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/simd/type-generic-monomorphisation.rs b/src/test/ui/simd/type-generic-monomorphisation.rs
new file mode 100644 (file)
index 0000000..12f9d65
--- /dev/null
@@ -0,0 +1,14 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics)]
+
+
+// error-pattern:monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
+
+struct X(Vec<i32>);
+#[repr(simd)]
+struct Simd2<T>(T, T);
+
+fn main() {
+    let _ = Simd2(X(vec![]), X(vec![]));
+}
diff --git a/src/test/ui/simd/type-generic-monomorphisation.stderr b/src/test/ui/simd/type-generic-monomorphisation.stderr
new file mode 100644 (file)
index 0000000..7f23893
--- /dev/null
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/simd/type-len.rs b/src/test/ui/simd/type-len.rs
new file mode 100644 (file)
index 0000000..d82c70b
--- /dev/null
@@ -0,0 +1,39 @@
+#![feature(repr_simd)]
+#![allow(non_camel_case_types)]
+
+
+#[repr(simd)]
+struct empty; //~ ERROR SIMD vector cannot be empty
+
+#[repr(simd)]
+struct empty2([f32; 0]); //~ ERROR SIMD vector cannot be empty
+
+#[repr(simd)]
+struct pow2([f32; 7]);
+
+#[repr(simd)]
+struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous
+
+struct Foo;
+
+#[repr(simd)]
+struct FooV(Foo, Foo); //~ ERROR SIMD vector element type should be a primitive scalar (integer/float/pointer) type
+
+#[repr(simd)]
+struct FooV2([Foo; 2]); //~ ERROR SIMD vector element type should be a primitive scalar (integer/float/pointer) type
+
+#[repr(simd)]
+struct TooBig([f32; 65536]); //~ ERROR SIMD vector cannot have more than 32768 elements
+
+#[repr(simd)]
+struct JustRight([u128; 32768]);
+
+#[repr(simd)]
+struct RGBA {
+    r: f32,
+    g: f32,
+    b: f32,
+    a: f32
+}
+
+fn main() {}
diff --git a/src/test/ui/simd/type-len.stderr b/src/test/ui/simd/type-len.stderr
new file mode 100644 (file)
index 0000000..f122d8b
--- /dev/null
@@ -0,0 +1,40 @@
+error[E0075]: SIMD vector cannot be empty
+  --> $DIR/type-len.rs:6:1
+   |
+LL | struct empty;
+   | ^^^^^^^^^^^^^
+
+error[E0075]: SIMD vector cannot be empty
+  --> $DIR/type-len.rs:9:1
+   |
+LL | struct empty2([f32; 0]);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0076]: SIMD vector should be homogeneous
+  --> $DIR/type-len.rs:15:1
+   |
+LL | struct i64f64(i64, f64);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type
+
+error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
+  --> $DIR/type-len.rs:20:1
+   |
+LL | struct FooV(Foo, Foo);
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
+  --> $DIR/type-len.rs:23:1
+   |
+LL | struct FooV2([Foo; 2]);
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0075]: SIMD vector cannot have more than 32768 elements
+  --> $DIR/type-len.rs:26:1
+   |
+LL | struct TooBig([f32; 65536]);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0075, E0076, E0077.
+For more information about an error, try `rustc --explain E0075`.
diff --git a/src/test/ui/simd/type-wide-ptr.rs b/src/test/ui/simd/type-wide-ptr.rs
new file mode 100644 (file)
index 0000000..88f62a0
--- /dev/null
@@ -0,0 +1,12 @@
+// build-fail
+
+#![feature(repr_simd)]
+
+// error-pattern:monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+
+#[repr(simd)]
+struct S([*mut [u8]; 4]);
+
+fn main() {
+    let _v: Option<S> = None;
+}
diff --git a/src/test/ui/simd/type-wide-ptr.stderr b/src/test/ui/simd/type-wide-ptr.stderr
new file mode 100644 (file)
index 0000000..51d3c00
--- /dev/null
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+
+error: aborting due to previous error
+
index e35aec4c0ce27a9b10ae2f0a93d72e89ea8ae287..9455162732b735036f4df9d53f6066844f694d23 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'min G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'min G as Get>`
+              found type `<&'max G as Get>`
 note: the lifetime `'min` as defined on the function body at 10:21...
   --> $DIR/variance-contravariant-self-trait-match.rs:10:21
    |
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'max G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'max G as Get>`
+              found type `<&'min G as Get>`
 note: the lifetime `'min` as defined on the function body at 16:21...
   --> $DIR/variance-contravariant-self-trait-match.rs:16:21
    |
index a25d1044d42565b80019b18b9b1908cee387e13b..3f3a69dde52105a09c4a565016dc6682be270f49 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'min G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'min G as Get>`
+              found type `<&'max G as Get>`
 note: the lifetime `'min` as defined on the function body at 10:21...
   --> $DIR/variance-covariant-self-trait-match.rs:10:21
    |
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'max G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'max G as Get>`
+              found type `<&'min G as Get>`
 note: the lifetime `'min` as defined on the function body at 17:21...
   --> $DIR/variance-covariant-self-trait-match.rs:17:21
    |
index 4a1d4d28b4805ae356b48264edc9d028f51b6212..a80a5e41d03147d13cf7b7d077b46e154797e078 100644 (file)
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'min G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'min G as Get>`
+              found type `<&'max G as Get>`
 note: the lifetime `'min` as defined on the function body at 7:21...
   --> $DIR/variance-invariant-self-trait-match.rs:7:21
    |
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'max G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'max G as Get>`
+              found type `<&'min G as Get>`
 note: the lifetime `'min` as defined on the function body at 13:21...
   --> $DIR/variance-invariant-self-trait-match.rs:13:21
    |
diff --git a/src/test/ui/wasm/simd-to-array-80108.rs b/src/test/ui/wasm/simd-to-array-80108.rs
new file mode 100644 (file)
index 0000000..0576c2e
--- /dev/null
@@ -0,0 +1,15 @@
+// only-wasm32
+// compile-flags: --crate-type=lib -Copt-level=2
+// build-pass
+#![feature(repr_simd)]
+
+// Regression test for #80108
+
+#[repr(simd)]
+pub struct Vector([i32; 4]);
+
+impl Vector {
+    pub const fn to_array(self) -> [i32; 4] {
+        self.0
+    }
+}
index 934839bbd605b0202a7fadf64ec20393d746f953..4470272a9f86672adcf1fbf168723040f89bd8e8 100644 (file)
@@ -38,6 +38,9 @@
 use crate::extract_gdb_version;
 use crate::is_android_gdb_target;
 
+mod debugger;
+use debugger::{check_debugger_output, DebuggerCommands};
+
 #[cfg(test)]
 mod tests;
 
@@ -200,12 +203,6 @@ struct TestCx<'test> {
     revision: Option<&'test str>,
 }
 
-struct DebuggerCommands {
-    commands: Vec<String>,
-    check_lines: Vec<String>,
-    breakpoint_lines: Vec<usize>,
-}
-
 enum ReadFrom {
     Path,
     Stdin(String),
@@ -235,10 +232,8 @@ impl<'test> TestCx<'test> {
     /// Code executed for each revision in turn (or, if there are no
     /// revisions, exactly once, with revision == None).
     fn run_revision(&self) {
-        if self.props.should_ice {
-            if self.config.mode != Incremental {
-                self.fatal("cannot use should-ice in a test that is not cfail");
-            }
+        if self.props.should_ice && self.config.mode != Incremental {
+            self.fatal("cannot use should-ice in a test that is not cfail");
         }
         match self.config.mode {
             RunPassValgrind => self.run_valgrind_test(),
@@ -674,7 +669,10 @@ fn run_debuginfo_cdb_test_no_opt(&self) {
 
         // Parse debugger commands etc from test files
         let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
-            self.parse_debugger_commands(prefixes);
+            match DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) {
+                Ok(cmds) => cmds,
+                Err(e) => self.fatal(&e),
+            };
 
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
         let mut script_str = String::with_capacity(2048);
@@ -726,7 +724,9 @@ fn run_debuginfo_cdb_test_no_opt(&self) {
             self.fatal_proc_rec("Error while running CDB", &debugger_run_result);
         }
 
-        self.check_debugger_output(&debugger_run_result, &check_lines);
+        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
     }
 
     fn run_debuginfo_gdb_test(&self) {
@@ -757,7 +757,10 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
         };
 
         let DebuggerCommands { commands, check_lines, breakpoint_lines } =
-            self.parse_debugger_commands(prefixes);
+            match DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) {
+                Ok(cmds) => cmds,
+                Err(e) => self.fatal(&e),
+            };
         let mut cmds = commands.join("\n");
 
         // compile test file (it should have 'compile-flags:-g' in the header)
@@ -960,7 +963,9 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
             self.fatal_proc_rec("gdb failed to execute", &debugger_run_result);
         }
 
-        self.check_debugger_output(&debugger_run_result, &check_lines);
+        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
     }
 
     fn run_debuginfo_lldb_test(&self) {
@@ -1018,7 +1023,10 @@ fn run_debuginfo_lldb_test_no_opt(&self) {
 
         // Parse debugger commands etc from test files
         let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
-            self.parse_debugger_commands(prefixes);
+            match DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) {
+                Ok(cmds) => cmds,
+                Err(e) => self.fatal(&e),
+            };
 
         // Write debugger script:
         // We don't want to hang when calling `quit` while the process is still running
@@ -1094,7 +1102,9 @@ fn run_debuginfo_lldb_test_no_opt(&self) {
             self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
         }
 
-        self.check_debugger_output(&debugger_run_result, &check_lines);
+        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
     }
 
     fn run_lldb(
@@ -1131,45 +1141,6 @@ fn cmd2procres(&self, cmd: &mut Command) -> ProcRes {
         ProcRes { status, stdout: out, stderr: err, cmdline: format!("{:?}", cmd) }
     }
 
-    fn parse_debugger_commands(&self, debugger_prefixes: &[&str]) -> DebuggerCommands {
-        let directives = debugger_prefixes
-            .iter()
-            .map(|prefix| (format!("{}-command", prefix), format!("{}-check", prefix)))
-            .collect::<Vec<_>>();
-
-        let mut breakpoint_lines = vec![];
-        let mut commands = vec![];
-        let mut check_lines = vec![];
-        let mut counter = 1;
-        let reader = BufReader::new(File::open(&self.testpaths.file).unwrap());
-        for line in reader.lines() {
-            match line {
-                Ok(line) => {
-                    let line =
-                        if line.starts_with("//") { line[2..].trim_start() } else { line.as_str() };
-
-                    if line.contains("#break") {
-                        breakpoint_lines.push(counter);
-                    }
-
-                    for &(ref command_directive, ref check_directive) in &directives {
-                        self.config
-                            .parse_name_value_directive(&line, command_directive)
-                            .map(|cmd| commands.push(cmd));
-
-                        self.config
-                            .parse_name_value_directive(&line, check_directive)
-                            .map(|cmd| check_lines.push(cmd));
-                    }
-                }
-                Err(e) => self.fatal(&format!("Error while parsing debugger commands: {}", e)),
-            }
-            counter += 1;
-        }
-
-        DebuggerCommands { commands, check_lines, breakpoint_lines }
-    }
-
     fn cleanup_debug_info_options(&self, options: &Option<String>) -> Option<String> {
         if options.is_none() {
             return None;
@@ -1216,66 +1187,6 @@ fn maybe_add_external_args(&self, cmd: &mut Command, args: Vec<String>) {
         }
     }
 
-    fn check_debugger_output(&self, debugger_run_result: &ProcRes, check_lines: &[String]) {
-        let num_check_lines = check_lines.len();
-
-        let mut check_line_index = 0;
-        for line in debugger_run_result.stdout.lines() {
-            if check_line_index >= num_check_lines {
-                break;
-            }
-
-            if check_single_line(line, &(check_lines[check_line_index])[..]) {
-                check_line_index += 1;
-            }
-        }
-        if check_line_index != num_check_lines && num_check_lines > 0 {
-            self.fatal_proc_rec(
-                &format!("line not found in debugger output: {}", check_lines[check_line_index]),
-                debugger_run_result,
-            );
-        }
-
-        fn check_single_line(line: &str, check_line: &str) -> bool {
-            // Allow check lines to leave parts unspecified (e.g., uninitialized
-            // bits in the  wrong case of an enum) with the notation "[...]".
-            let line = line.trim();
-            let check_line = check_line.trim();
-            let can_start_anywhere = check_line.starts_with("[...]");
-            let can_end_anywhere = check_line.ends_with("[...]");
-
-            let check_fragments: Vec<&str> =
-                check_line.split("[...]").filter(|frag| !frag.is_empty()).collect();
-            if check_fragments.is_empty() {
-                return true;
-            }
-
-            let (mut rest, first_fragment) = if can_start_anywhere {
-                match line.find(check_fragments[0]) {
-                    Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
-                    None => return false,
-                }
-            } else {
-                (line, 0)
-            };
-
-            for current_fragment in &check_fragments[first_fragment..] {
-                match rest.find(current_fragment) {
-                    Some(pos) => {
-                        rest = &rest[pos + current_fragment.len()..];
-                    }
-                    None => return false,
-                }
-            }
-
-            if !can_end_anywhere && !rest.is_empty() {
-                return false;
-            }
-
-            true
-        }
-    }
-
     fn check_error_patterns(
         &self,
         output_to_check: &str,
@@ -2154,9 +2065,9 @@ fn output_base_name(&self) -> PathBuf {
 
     fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
         if self.config.verbose {
-            println!("------{}------------------------------", "stdout");
+            println!("------stdout------------------------------");
             println!("{}", out);
-            println!("------{}------------------------------", "stderr");
+            println!("------stderr------------------------------");
             println!("{}", err);
             println!("------------------------------------------");
         }
@@ -3249,11 +3160,10 @@ fn run_ui_test(&self) {
                 if !proc_res.status.success() {
                     self.fatal_proc_rec("test run failed!", &proc_res);
                 }
-            } else {
-                if proc_res.status.success() {
-                    self.fatal_proc_rec("test run succeeded!", &proc_res);
-                }
+            } else if proc_res.status.success() {
+                self.fatal_proc_rec("test run succeeded!", &proc_res);
             }
+
             if !self.props.error_patterns.is_empty() {
                 // "// error-pattern" comments
                 self.check_error_patterns(&proc_res.stderr, &proc_res, pm);
@@ -3300,10 +3210,11 @@ fn run_ui_test(&self) {
             if !res.status.success() {
                 self.fatal_proc_rec("failed to compile fixed code", &res);
             }
-            if !res.stderr.is_empty() && !self.props.rustfix_only_machine_applicable {
-                if !json::rustfix_diagnostics_only(&res.stderr).is_empty() {
-                    self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
-                }
+            if !res.stderr.is_empty()
+                && !self.props.rustfix_only_machine_applicable
+                && !json::rustfix_diagnostics_only(&res.stderr).is_empty()
+            {
+                self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
             }
         }
     }
diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs
new file mode 100644 (file)
index 0000000..cbd5e4c
--- /dev/null
@@ -0,0 +1,115 @@
+use crate::common::Config;
+use crate::runtest::ProcRes;
+
+use std::fs::File;
+use std::io::{BufRead, BufReader};
+use std::path::Path;
+
+pub(super) struct DebuggerCommands {
+    pub commands: Vec<String>,
+    pub check_lines: Vec<String>,
+    pub breakpoint_lines: Vec<usize>,
+}
+
+impl DebuggerCommands {
+    pub(super) fn parse_from(
+        file: &Path,
+        config: &Config,
+        debugger_prefixes: &[&str],
+    ) -> Result<Self, String> {
+        let directives = debugger_prefixes
+            .iter()
+            .map(|prefix| (format!("{}-command", prefix), format!("{}-check", prefix)))
+            .collect::<Vec<_>>();
+
+        let mut breakpoint_lines = vec![];
+        let mut commands = vec![];
+        let mut check_lines = vec![];
+        let mut counter = 1;
+        let reader = BufReader::new(File::open(file).unwrap());
+        for line in reader.lines() {
+            match line {
+                Ok(line) => {
+                    let line =
+                        if line.starts_with("//") { line[2..].trim_start() } else { line.as_str() };
+
+                    if line.contains("#break") {
+                        breakpoint_lines.push(counter);
+                    }
+
+                    for &(ref command_directive, ref check_directive) in &directives {
+                        config
+                            .parse_name_value_directive(&line, command_directive)
+                            .map(|cmd| commands.push(cmd));
+
+                        config
+                            .parse_name_value_directive(&line, check_directive)
+                            .map(|cmd| check_lines.push(cmd));
+                    }
+                }
+                Err(e) => return Err(format!("Error while parsing debugger commands: {}", e)),
+            }
+            counter += 1;
+        }
+
+        Ok(Self { commands, check_lines, breakpoint_lines })
+    }
+}
+
+pub(super) fn check_debugger_output(
+    debugger_run_result: &ProcRes,
+    check_lines: &[String],
+) -> Result<(), String> {
+    let num_check_lines = check_lines.len();
+
+    let mut check_line_index = 0;
+    for line in debugger_run_result.stdout.lines() {
+        if check_line_index >= num_check_lines {
+            break;
+        }
+
+        if check_single_line(line, &(check_lines[check_line_index])[..]) {
+            check_line_index += 1;
+        }
+    }
+    if check_line_index != num_check_lines && num_check_lines > 0 {
+        Err(format!("line not found in debugger output: {}", check_lines[check_line_index]))
+    } else {
+        Ok(())
+    }
+}
+
+fn check_single_line(line: &str, check_line: &str) -> bool {
+    // Allow check lines to leave parts unspecified (e.g., uninitialized
+    // bits in the  wrong case of an enum) with the notation "[...]".
+    let line = line.trim();
+    let check_line = check_line.trim();
+    let can_start_anywhere = check_line.starts_with("[...]");
+    let can_end_anywhere = check_line.ends_with("[...]");
+
+    let check_fragments: Vec<&str> =
+        check_line.split("[...]").filter(|frag| !frag.is_empty()).collect();
+    if check_fragments.is_empty() {
+        return true;
+    }
+
+    let (mut rest, first_fragment) = if can_start_anywhere {
+        match line.find(check_fragments[0]) {
+            Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
+            None => return false,
+        }
+    } else {
+        (line, 0)
+    };
+
+    for current_fragment in &check_fragments[first_fragment..] {
+        match rest.find(current_fragment) {
+            Some(pos) => {
+                rest = &rest[pos + current_fragment.len()..];
+            }
+            None => return false,
+        }
+    }
+
+    if !can_end_anywhere && !rest.is_empty() { false } else { true }
+}
index 01f199c213e02441bf3d15393b80dacbafff1a2e..992aac1f857a5b528e5b8f140ac6a6d0380607d2 100644 (file)
@@ -41,18 +41,26 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-static HEADER: &str = "
+static HEADER: &str = r"
 pub fn to_lower(c: char) -> [char; 3] {
-    match bsearch_case_table(c, LOWERCASE_TABLE) {
-        None => [c, '\\0', '\\0'],
-        Some(index) => LOWERCASE_TABLE[index].1,
+    if c.is_ascii() {
+        [(c as u8).to_ascii_lowercase() as char, '\0', '\0']
+    } else {
+        match bsearch_case_table(c, LOWERCASE_TABLE) {
+            None => [c, '\0', '\0'],
+            Some(index) => LOWERCASE_TABLE[index].1,
+        }
     }
 }
 
 pub fn to_upper(c: char) -> [char; 3] {
-    match bsearch_case_table(c, UPPERCASE_TABLE) {
-        None => [c, '\\0', '\\0'],
-        Some(index) => UPPERCASE_TABLE[index].1,
+    if c.is_ascii() {
+        [(c as u8).to_ascii_uppercase() as char, '\0', '\0']
+    } else {
+        match bsearch_case_table(c, UPPERCASE_TABLE) {
+            None => [c, '\0', '\0'],
+            Some(index) => UPPERCASE_TABLE[index].1,
+        }
     }
 }
 
index 42e7e5fb406051303305f3d059a422ed4898ef85..ab8eaee9541a2891bd3c163b61b3fd7b147b406c 100644 (file)
@@ -23,7 +23,7 @@ fn blank_line(&mut self) {
         writeln!(&mut self.file).unwrap();
     }
 
-    fn emit_bitset(&mut self, ranges: &[Range<u32>]) {
+    fn emit_bitset(&mut self, ranges: &[Range<u32>]) -> Result<(), String> {
         let last_code_point = ranges.last().unwrap().end;
         // bitset for every bit in the codepoint range
         //
@@ -44,7 +44,7 @@ fn emit_bitset(&mut self, ranges: &[Range<u32>]) {
         let unique_words =
             words.iter().cloned().collect::<BTreeSet<_>>().into_iter().collect::<Vec<_>>();
         if unique_words.len() > u8::MAX as usize {
-            panic!("cannot pack {} into 8 bits", unique_words.len());
+            return Err(format!("cannot pack {} into 8 bits", unique_words.len()));
         }
         // needed for the chunk mapping to work
         assert_eq!(unique_words[0], 0, "has a zero word");
@@ -105,6 +105,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         writeln!(&mut self.file, "        &BITSET_MAPPING,").unwrap();
         writeln!(&mut self.file, "    )").unwrap();
         writeln!(&mut self.file, "}}").unwrap();
+
+        Ok(())
     }
 
     fn emit_chunk_map(&mut self, zero_at: u8, compressed_words: &[u8], chunk_length: usize) {
@@ -154,12 +156,12 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
     emitter.blank_line();
 
     let mut bitset = emitter.clone();
-    bitset.emit_bitset(&ranges);
+    let bitset_ok = bitset.emit_bitset(&ranges).is_ok();
 
     let mut skiplist = emitter.clone();
     skiplist.emit_skiplist(&ranges);
 
-    if bitset.bytes_used <= skiplist.bytes_used {
+    if bitset_ok && bitset.bytes_used <= skiplist.bytes_used {
         *emitter = bitset;
         emitter.desc = String::from("bitset");
     } else {