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;
}
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)
}
// 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);
}
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,
};
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};
}
}
+/// 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;
}
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),
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(
}
}
+/// 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 {
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
}
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.
///
/// 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
// -------------------------------------------------------------------------
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,
+ }
}
}
}
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! {
/// 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,
}
}
};
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;
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
nomem,
non_ascii_idents,
non_exhaustive,
+ non_exhaustive_omitted_patterns_lint,
non_modrs_mods,
none_error,
nontemporal_store,
--- /dev/null
+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
+ },
+ }
+}
("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`.
) -> 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: {:?}, {:?}",
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)
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),
}
self.infcx.report_overflow_error(error_obligation, true);
}
TraitQueryMode::Canonical => {
- return Err(OverflowError::Cannonical);
+ return Err(OverflowError::Canonical);
}
}
}
/// from the stack into it.
///
/// # Examples
+ ///
/// ```rust
/// let x = 5;
/// let boxed = Box::new(5);
#[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 {
/// and performs a copy of `s`.
///
/// # Examples
+ ///
/// ```rust
/// let boxed: Box<str> = Box::from("hello");
/// println!("{}", boxed);
#[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 {
/// This conversion moves the array to newly heap-allocated memory.
///
/// # Examples
+ ///
/// ```rust
/// let boxed: Box<[u8]> = Box::from([4, 2]);
/// println!("{:?}", boxed);
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]) })
///
/// 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 }
/// 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()
/// 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() }
/// 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() }
/// }
/// 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()
#[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();
}
}
/// 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
/// 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
/// 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
not(test),
not(any(test, bootstrap)),
any(not(feature = "miri-test-libstd"), test, doctest),
+ no_global_oom_handling,
target_has_atomic = "ptr"
))
)]
///
/// [`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();
/// 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()
/// 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
/// ```
#[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();
///
/// 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
/// 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())
/// 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 _) }
///
/// [`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();
#[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] {
///
/// 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);
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.
///
/// 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;
// 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));
}
}
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
/// ```
/// 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 {
/// ```
/// 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 {
/// ```
/// 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 {
/// // 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 {
/// assert!(!'中'.is_lowercase());
/// assert!(!' '.is_lowercase());
/// ```
+ #[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
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 {
///
/// assert!(!'越'.is_whitespace());
/// ```
+ #[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
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 {
/// assert!('\9c'.is_control());
/// assert!(!'q'.is_control());
/// ```
+ #[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
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)
/// assert!(!'و'.is_numeric());
/// assert!(!'藏'.is_numeric());
/// ```
+ #[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_numeric(self) -> bool {
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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 {
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",
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
///
/// 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 {
///
/// 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 {
/// * 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
/// 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]
/// 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]
/// 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]
/// }
/// );
/// ```
+ #[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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
!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]
/// 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]
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]
///
/// 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 {
///
/// 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 {
/// * 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
/// 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]
/// 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]
/// 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]
/// }
/// );
/// ```
+ #[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]
#[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() }
/// ```
#[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()
/// ```
#[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()
/// ```
#[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()
/// ```
#[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()
/// ```
#[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()
/// ```
#[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
/// ```
#[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
}
/// ```
#[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")]
/// ```
#[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")]
/// ```
#[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();
/// ```
#[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() {
#[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)
#[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() {
/// ```
#[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)
/// ```
#[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 {
/// ```
#[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
#[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) {
/// ```
#[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)
}
}
- /// 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`
/// # 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
///
/// ```
#[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]
}
}
- /// 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
///
/// ```
#[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]
}
}
- /// 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
///
/// ```
#[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]
}
}
- /// 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.
///
/// ```
#[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 {
}
}
- /// 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.
///
/// ```
#[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 {
}
}
- /// 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.
///
/// ```
#[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)
#[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 {
#[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 {
/// ```
#[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 {
#[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)]
#[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)]
/// ```
#[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()
/// ```
#[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()
#[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
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// 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]
/// ```
#[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
/// ```
#[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
/// # }
/// ```
#[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) {
/// # }
/// ```
#[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
/// # }
/// ```
#[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.
/// # }
/// ```
#[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() {
/// # }
/// ```
#[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.
/// # }
/// ```
#[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() {
/// # }
/// ```
#[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();
/// # }
/// ```
#[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.
/// # }
/// ```
#[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.
/// # }
/// ```
#[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.
/// # }
/// ```
#[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()) {
/// # }
/// ```
#[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
/// # }
/// ```
#[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.
/// # }
/// ```
#[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) {
/// # }
/// ```
#[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
#[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 {
#[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()
#[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()
/// 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()
/// 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))
/// 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))
/// 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())
/// 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())
}
/// ```
#[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())
}
/// ```
#[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())
}
/// ```
#[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))
}
/// ```
#[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()
}
/// ```
#[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())
}
/// ```
#[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())
}
#[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 {
#[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 {
/// ```
#[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()
}
#[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 {
#[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
/// ```
#[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()
/// ```
#[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
/// ```
#[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
/// ```
#[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()
/// ```
#[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()
/// ```
#[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
/// ```
#[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
}
/// ```
#[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")]
/// ```
#[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")]
}
}
- /// 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`
/// # 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
///
/// ```
#[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]
}
}
- /// 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
///
/// ```
#[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]
}
}
- /// 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
///
/// ```
#[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]
}
}
- /// 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.
///
/// ```
#[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 {
}
}
- /// 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.
///
/// ```
#[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 {
}
}
- /// 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.
///
/// ```
#[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)
/// ```
#[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();
#[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)
/// ```
#[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)
#[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 {
#[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)
}
#[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 {
#[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 {
#[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 {
#[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)]
/// 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
/// ```
#[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 {
#[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)
}
#[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)
}
/// ```
#[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()
/// ```
#[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()
/// ```
#[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]
#[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()
#[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()
/// 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()
/// 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))
/// 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))
/// 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())
/// ```
#[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())
}
/// }
/// ```
#[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())
/// }
/// ```
#[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())
/// 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))
/// 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()
/// 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())
#[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())
#[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 {
#[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 {
/// 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()
#[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 {
#[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 {
/// 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)
/// 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())
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> {
/// 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
/// 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 {
/// 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
/// 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
}
/// 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
}
/// 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
/// // 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
/// 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
/// 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
/// 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
/// // 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 {
#[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
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
/// 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]
/// 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> {
/// 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 {
/// 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> {
/// 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 {
/// 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> {
/// 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 {
/// 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> {
/// 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 {
/// 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 {
/// 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 {
/// 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 {
/// 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 {
/// 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 {
} 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 {
(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),
(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),
(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)] = &[
(0x01, 1),
(0x03, 1),
(0x04, 2),
+ (0x05, 7),
+ (0x07, 2),
(0x08, 8),
(0x09, 2),
(0x0a, 5),
(0x1c, 5),
(0x1d, 8),
(0x24, 1),
- (0x6a, 3),
+ (0x6a, 4),
(0x6b, 2),
+ (0xaf, 3),
(0xbc, 2),
+ (0xcf, 2),
(0xd1, 2),
(0xd4, 12),
(0xd5, 9),
(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] = &[
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,
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,
0x1a, 0x06,
0x82, 0xfd, 0x03,
0x59, 0x07,
- 0x15, 0x0b,
- 0x17, 0x09,
+ 0x16, 0x09,
+ 0x18, 0x09,
0x14, 0x0c,
0x14, 0x0c,
0x6a, 0x06,
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,
0x18, 0x08,
0x2f, 0x11,
0x2d, 0x03,
- 0x20, 0x10,
+ 0x21, 0x0f,
0x21, 0x0f,
0x80, 0x8c, 0x04,
0x82, 0x97, 0x19,
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,
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,
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,
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,
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,
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,
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,
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,
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,
];
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(
#[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(
#[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(
#[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(
#[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,
0b0101010110101010101010101010101010101010101010101010101010101010,
0b0100000011011111000000001111111100000000111111110000000011111111,
0b0011111111111111000000001111111100000000111111110000000000111111,
- 0b0011111111011010000101010110001001111111111111111111111111111111,
+ 0b0011111111011010000101010110001011111111111111111111111111111111,
0b0011111100000000000000000000000000000000000000000000000000000000,
0b0011110010001010000000000000000000000000000000000000000000100000,
0b0011001000010000100000000000000000000000000010001100010000000000,
+ 0b0001101111111011111111111111101111111111100000000000000000000000,
0b0001100100101111101010101010101010101010111000110111111111111111,
- 0b0000011101000000000000000000000000000000000000000000010100001000,
+ 0b0000011111111101111111111111111111111111111111111111111110111001,
+ 0b0000011101000000000000000000000000000010101010100000010100001010,
0b0000010000100000000001000000000000000000000000000000000000000000,
0b0000000111111111111111111111111111111111111011111111111111111111,
0b0000000011111111000000001111111100000000001111110000000011111111,
0b0000000000000000001000001011111111111111111111111111111111111111,
0b0000000000000000000000001111111111111111110111111100000000000000,
0b0000000000000000000000000001111100000000000000000000000000000011,
+ 0b0000000000000000000000000000000001111111111111111111101111111111,
0b0000000000000000000000000000000000111010101010101010101010101010,
0b0000000000000000000000000000000000000000111110000000000001111111,
0b0000000000000000000000000000000000000000000000000000101111110111,
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,
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(
#[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,
0b0000000000000000111111110000000010101010000000000011111100000000,
0b0000000000000000000011111111101111111111111111101101011101000000,
0b0000000000000000000000000000000001111111011111111111111111111111,
+ 0b0000000000000000000000000000000000000000001101111111011111111111,
0b0000000000000000000000000000000000000000000000000101010101111010,
0b0000000000000000000000000000000000000000000000000010000010111111,
0b1010101001010101010101010101010101010101010101010101010101010101,
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),
];
('\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}']),
('\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}']),
('\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}']),
('\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}']),
use core::array;
use core::convert::TryFrom;
+use core::sync::atomic::{AtomicUsize, Ordering};
#[test]
fn array_from_ref() {
#[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 {
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
+}
#![feature(extern_types)]
#![feature(flt2dec)]
#![feature(fmt_internals)]
+#![feature(array_from_fn)]
#![feature(hashmap_internals)]
#![feature(try_find)]
#![feature(is_sorted)]
/// 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()
}
/// 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()
/// 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()
/// 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()
///
/// 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
}
/// }
/// ```
#[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
/// 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 {
/// 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();
/// 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()
/// 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) }
/// 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
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
///
/// 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;
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)
}
}
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
/// }
/// ```
#[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 {
/// 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()
/// 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 }
/// 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 {
/// 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
/// 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;
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};
/// # 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()
}
/// # Examples
///
/// ```
- /// # #![feature(command_access)]
/// use std::ffi::OsStr;
/// use std::process::Command;
///
/// 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() }
}
/// # Examples
///
/// ```
- /// # #![feature(command_access)]
/// use std::ffi::OsStr;
/// use std::process::Command;
///
/// (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()
}
/// # Examples
///
/// ```
- /// # #![feature(command_access)]
/// use std::path::Path;
/// use std::process::Command;
///
/// 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()
}
///
/// 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> {
}
}
-#[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()
#[link(name = "zircon")]
#[link(name = "fdio")]
extern "C" {}
+ } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] {
+ #[link(name = "dl")]
+ extern "C" {}
}
}
}
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());
}
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
impl FromInner<Handle> for File {
fn from_inner(handle: Handle) -> File {
- File { handle: handle }
+ File { handle }
}
}
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()
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
}
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;
/// 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> {
}
}
-#[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()
// 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")
))]
#[cfg(all(
target_os = "linux",
- target_env = "gnu",
+ any(target_env = "gnu", target_env = "uclibc"),
not(feature = "llvm-libunwind"),
feature = "system-llvm-libunwind"
))]
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(
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());
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.
# 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
# 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
# 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
# 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
`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` | ? | |
--- /dev/null
+# 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
+```
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:
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,
.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>,
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,
));
}
.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,
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();
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)
{
// 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,
};
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),
}
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,
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,
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)
}
}
}
}
-// 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>,
);
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;
.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
),
};
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;
}
}
}
}
- 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,
item.ident.name,
clean::ImportSource {
path: clean::Path {
- global: false,
res,
segments: vec![clean::PathSegment {
name: prim_ty.as_sym(),
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,
});
}
}
}
- 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
}
}
-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) {
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)
}
}
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_,
}
}
}
}
}
-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
}
}
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 => {}
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) => {
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"),
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);
}
}
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)
}
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) }
}
}
// 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);
}
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,
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 {
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,
}
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,
)
}
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;
}
}
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 {
/// 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>),
}
}
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,
}
}
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),
}
}
-/// 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,
#[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
}
}
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.
_ => 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)]
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,
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()
}
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;
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,
}
}
-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()
})
.collect();
- Path { global: path.global, res: path.res, segments }
+ Path { res: path.res, segments }
}
crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
// 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;
// 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() });
}
}
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
}
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
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
}
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())
}
}
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;
0 => String::new(),
_ if f.alternate() => {
format!(
- "for<{:#}> ",
+ "for<{:#}> ",
comma_sep(bound_params.iter().map(|lt| lt.print()))
)
}
}
}
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))?
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(())
}
}
}
}
}
+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,
) -> 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<{}> ",
+ comma_sep(self.generic_params.iter().map(|g| g.print(cx)))
+ )
} else {
Ok(())
}
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),
}
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() {
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;
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,
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
&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 {
};
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
mod context;
mod print_item;
mod span_map;
+mod templates;
mod write_shared;
crate use context::*;
// 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() };
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 {
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>) =
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>");
+ }
}
}
}
) {
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
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);
}
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);
}
}
}
}
- 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(|| {
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)> {
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() {
}
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());
}
}
clean::Type::QPath { self_type, trait_, .. } => {
work.push_back(*self_type);
- work.push_back(*trait_);
+ process_path(trait_.def_id());
}
_ => {}
}
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 "
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\">−</span>]\
- </a>\
- </span>",
- );
+ let stability_since_raw: String = stability_since_raw.into_inner();
// Write `src` tag
//
// [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),
--- /dev/null
+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)
+}
.item-table {
display: table-row;
- /* align content left */
- justify-items: start;
}
.item-row {
display: table-row;
.docblock {
margin-left: 12px;
}
+
+ .docblock code {
+ overflow-wrap: anywhere;
+ }
}
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
--- /dev/null
+<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">−</span>] {#- -#}
+ </a> {#- -#}
+ </span> {#- -#}
+ {%- if src_href -%}
+ <a class="srclink" href="{{src_href | safe}}" title="goto source code">[src]</a>
+ {%- endif -%}
+ </span> {#- -#}
+</h1> {#- -#}
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),
}
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))),
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_),
+ }
+ }
}
}
}
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),
.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,
// 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 {
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
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;
--- /dev/null
+// 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)
+}
+++ /dev/null
-// 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;
-}
--- /dev/null
+// 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"})
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 {}
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
|
--- /dev/null
+#![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
+}
--- /dev/null
+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`.
|
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
--- /dev/null
+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() {}
--- /dev/null
+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`.
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
|
// no-prefer-dynamic
#![crate_type = "proc-macro"]
-#![feature(proc_macro_is_available)]
extern crate proc_macro;
// run-pass
-#![feature(proc_macro_is_available)]
-
extern crate proc_macro;
// aux-build:is-available.rs
// Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly.
+#![feature(non_exhaustive_omitted_patterns_lint)]
+
// aux-build:enums.rs
extern crate enums;
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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+++ /dev/null
-// 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
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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`
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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`
-
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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`
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- }
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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)
-}
+++ /dev/null
-// 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)
-}
--- /dev/null
+// 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));
+ }
+ }
+}
--- /dev/null
+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
+
--- /dev/null
+// 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));
+ }
+ }
+}
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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`
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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));
+
+ }
+}
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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);
+ }
+ }
+}
--- /dev/null
+// 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);
+
+ }
+}
--- /dev/null
+// 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`
+
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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)
+}
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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;
+ }
+ }
+}
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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));
+ }
+
+}
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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`
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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)
+}
--- /dev/null
+// 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)
+}
--- /dev/null
+// 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
+}
--- /dev/null
+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`.
#[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] = {
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)
};
}
// 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);
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);
| ^^^^^^^^^^^^^^^^^^^^^
+++ /dev/null
-// 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));
- }
- }
-}
+++ /dev/null
-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
-
+++ /dev/null
-// 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));
- }
- }
-}
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-// 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);
- }
- }
-}
+++ /dev/null
-// 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));
-
- }
-}
+++ /dev/null
-// 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);
-
- }
-}
+++ /dev/null
-// 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)
-}
+++ /dev/null
-// 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;
- }
- }
-}
+++ /dev/null
-// 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));
- }
-
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-// 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>>();
-}
+++ /dev/null
-// 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) {}
-}
+++ /dev/null
-// 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>([]);
-}
+++ /dev/null
-error: monomorphising SIMD type `Simd<0_usize>` of zero length
-
-error: aborting due to previous error
-
+++ /dev/null
-// 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]));
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
-
-error: aborting due to previous error
-
+++ /dev/null
-// 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]);
-}
+++ /dev/null
-error: monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768
-
-error: aborting due to previous error
-
+++ /dev/null
-// run-pass
-
-#![feature(repr_simd, platform_intrinsics)]
-
-#[repr(simd)]
-struct Simd<const N: usize>([f32; N]);
-
-fn main() {
- let _ = Simd::<3>([0.; 3]);
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-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
-
+++ /dev/null
-// 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![]));
-}
+++ /dev/null
-error: monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
-
-error: aborting due to previous error
-
+++ /dev/null
-// 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;
-}
+++ /dev/null
-error: monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
-
-error: aborting due to previous error
-
+++ /dev/null
-#![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() {}
+++ /dev/null
-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`.
--- /dev/null
+// 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>>();
+}
--- /dev/null
+// 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) {}
+}
--- /dev/null
+// 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>([]);
+}
--- /dev/null
+error: monomorphising SIMD type `Simd<0_usize>` of zero length
+
+error: aborting due to previous error
+
--- /dev/null
+// 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]));
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
+
+error: aborting due to previous error
+
--- /dev/null
+// 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]);
+}
--- /dev/null
+error: monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768
+
+error: aborting due to previous error
+
--- /dev/null
+// run-pass
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+struct Simd<const N: usize>([f32; N]);
+
+fn main() {
+ let _ = Simd::<3>([0.; 3]);
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+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
+
--- /dev/null
+// 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![]));
+}
--- /dev/null
+error: monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
+
+error: aborting due to previous error
+
--- /dev/null
+#![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() {}
--- /dev/null
+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`.
--- /dev/null
+// 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;
+}
--- /dev/null
+error: monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+
+error: aborting due to previous error
+
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
|
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
|
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
|
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
|
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
|
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
|
--- /dev/null
+// 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
+ }
+}
use crate::extract_gdb_version;
use crate::is_android_gdb_target;
+mod debugger;
+use debugger::{check_debugger_output, DebuggerCommands};
+
#[cfg(test)]
mod tests;
revision: Option<&'test str>,
}
-struct DebuggerCommands {
- commands: Vec<String>,
- check_lines: Vec<String>,
- breakpoint_lines: Vec<usize>,
-}
-
enum ReadFrom {
Path,
Stdin(String),
/// 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(),
// 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);
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) {
};
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)
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) {
// 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
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(
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;
}
}
- 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,
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!("------------------------------------------");
}
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);
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);
}
}
}
--- /dev/null
+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 }
+}
}
}
-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,
+ }
}
}
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
//
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");
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) {
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 {