Auto merge of #148692 - matthiaskrgr:rollup-hryk71f, r=matthiaskrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#145656 (Stabilize s390x `vector` target feature and `is_s390x_feature_detected!` macro)
 - rust-lang/rust#147024 (std_detect: Support run-time detection on OpenBSD using elf_aux_info)
 - rust-lang/rust#147534 (Implement SIMD funnel shifts in const-eval/Miri)
 - rust-lang/rust#147540 (Stabilise `as_array` in `[_]` and `*const [_]`; stabilise `as_mut_array` in `[_]` and `*mut [_]`.)
 - rust-lang/rust#147686 (update isolate_highest_one for NonZero<T>)
 - rust-lang/rust#148230 (rustdoc: Properly highlight shebang, frontmatter & weak keywords in source code pages and code blocks)
 - rust-lang/rust#148555 (Fix rust-by-example spanish translation)
 - rust-lang/rust#148556 (Fix suggestion for returning async closures)
 - rust-lang/rust#148585 ([rustdoc] Replace `print` methods with functions to improve code readability)
 - rust-lang/rust#148600 (re-use `self.get_all_attrs` result for pass indirectly attribute)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-11-09 01:40:19 +00:00
commit acda5e9f9a
57 changed files with 1370 additions and 919 deletions

View file

@ -5,6 +5,7 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(slice_as_array))]
#![feature(assert_matches)]
#![feature(extern_types)]
#![feature(file_buffered)]
@ -12,7 +13,6 @@
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(macro_derive)]
#![feature(slice_as_array)]
#![feature(trim_prefix_suffix)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -3,7 +3,7 @@ use rustc_abi::{BackendRepr, Endian};
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
use rustc_apfloat::{Float, Round};
use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo};
use rustc_middle::ty::{FloatTy, SimdAlign};
use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign};
use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty};
use rustc_span::{Symbol, sym};
use tracing::trace;
@ -744,6 +744,58 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_scalar(val, &dest)?;
}
}
sym::simd_funnel_shl | sym::simd_funnel_shr => {
let (left, _) = self.project_to_simd(&args[0])?;
let (right, _) = self.project_to_simd(&args[1])?;
let (shift, _) = self.project_to_simd(&args[2])?;
let (dest, _) = self.project_to_simd(&dest)?;
let (len, elem_ty) = args[0].layout.ty.simd_size_and_type(*self.tcx);
let (elem_size, _signed) = elem_ty.int_size_and_signed(*self.tcx);
let elem_size_bits = u128::from(elem_size.bits());
let is_left = intrinsic_name == sym::simd_funnel_shl;
for i in 0..len {
let left =
self.read_scalar(&self.project_index(&left, i)?)?.to_bits(elem_size)?;
let right =
self.read_scalar(&self.project_index(&right, i)?)?.to_bits(elem_size)?;
let shift_bits =
self.read_scalar(&self.project_index(&shift, i)?)?.to_bits(elem_size)?;
if shift_bits >= elem_size_bits {
throw_ub_format!(
"overflowing shift by {shift_bits} in `{intrinsic_name}` in lane {i}"
);
}
let inv_shift_bits = u32::try_from(elem_size_bits - shift_bits).unwrap();
// A funnel shift left by S can be implemented as `(x << S) | y.unbounded_shr(SIZE - S)`.
// The `unbounded_shr` is needed because otherwise if `S = 0`, it would be `x | y`
// when it should be `x`.
//
// This selects the least-significant `SIZE - S` bits of `x`, followed by the `S` most
// significant bits of `y`. As `left` and `right` both occupy the lower `SIZE` bits,
// we can treat the lower `SIZE` bits as an integer of the right width and use
// the same implementation, but on a zero-extended `x` and `y`. This works because
// `x << S` just pushes the `SIZE-S` MSBs out, and `y >> (SIZE - S)` shifts in
// zeros, as it is zero-extended. To the lower `SIZE` bits, this looks just like a
// funnel shift left.
//
// Note that the `unbounded_sh{l,r}`s are needed only in case we are using this on
// `u128xN` and `inv_shift_bits == 128`.
let result_bits = if is_left {
(left << shift_bits) | right.unbounded_shr(inv_shift_bits)
} else {
left.unbounded_shl(inv_shift_bits) | (right >> shift_bits)
};
let (result, _overflow) = ScalarInt::truncate_from_uint(result_bits, elem_size);
let dest = self.project_index(&dest, i)?;
self.write_scalar(result, &dest)?;
}
}
// Unsupported intrinsic: skip the return_to_block below.
_ => return interp_ok(false),

View file

@ -387,6 +387,8 @@ declare_features! (
(accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611)),
/// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
(accepted, rvalue_static_promotion, "1.21.0", Some(38865)),
/// Allows use of the `vector` and related s390x target features.
(accepted, s390x_target_feature_vector, "CURRENT_RUSTC_VERSION", Some(145649)),
/// Allows `Self` in type definitions (RFC 2300).
(accepted, self_in_typedefs, "1.32.0", Some(49303)),
/// Allows `Self` struct constructor (RFC 2302).

View file

@ -1264,6 +1264,21 @@ pub fn suggest_impl_trait<'tcx>(
infcx.tcx.lang_items().future_output(),
format_as_assoc,
),
(
infcx.tcx.lang_items().async_fn_trait(),
infcx.tcx.lang_items().async_fn_once_output(),
format_as_parenthesized,
),
(
infcx.tcx.lang_items().async_fn_mut_trait(),
infcx.tcx.lang_items().async_fn_once_output(),
format_as_parenthesized,
),
(
infcx.tcx.lang_items().async_fn_once_trait(),
infcx.tcx.lang_items().async_fn_once_output(),
format_as_parenthesized,
),
(
infcx.tcx.lang_items().fn_trait(),
infcx.tcx.lang_items().fn_once_output(),

View file

@ -1512,9 +1512,8 @@ impl<'tcx> TyCtxt<'tcx> {
field_shuffle_seed ^= user_seed;
}
if let Some(reprs) =
find_attr!(self.get_all_attrs(did), AttributeKind::Repr { reprs, .. } => reprs)
{
let attributes = self.get_all_attrs(did);
if let Some(reprs) = find_attr!(attributes, AttributeKind::Repr { reprs, .. } => reprs) {
for (r, _) in reprs {
flags.insert(match *r {
attr::ReprRust => ReprFlags::empty(),
@ -1574,10 +1573,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
// See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details.
if find_attr!(
self.get_all_attrs(did),
AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)
) {
if find_attr!(attributes, AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)) {
flags.insert(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS);
}

View file

@ -2006,6 +2006,7 @@ symbols! {
s,
s390x,
s390x_target_feature,
s390x_target_feature_vector,
safety,
sanitize,
sanitizer_cfi_generalize_pointers,

View file

@ -844,20 +844,20 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]),
("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]),
("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]),
("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature), &[]),
("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature), &[]),
("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature), &[]),
("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
("miscellaneous-extensions-2", Stable, &[]),
("miscellaneous-extensions-3", Stable, &[]),
("miscellaneous-extensions-4", Stable, &[]),
("nnp-assist", Stable, &["vector"]),
("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
("vector", Unstable(sym::s390x_target_feature), &[]),
("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]),
("vector-enhancements-3", Unstable(sym::s390x_target_feature), &["vector-enhancements-2"]),
("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]),
("vector-packed-decimal-enhancement", Unstable(sym::s390x_target_feature), &["vector-packed-decimal"]),
("vector-packed-decimal-enhancement-2", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement"]),
("vector-packed-decimal-enhancement-3", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement-2"]),
("vector", Stable, &[]),
("vector-enhancements-1", Stable, &["vector"]),
("vector-enhancements-2", Stable, &["vector-enhancements-1"]),
("vector-enhancements-3", Stable, &["vector-enhancements-2"]),
("vector-packed-decimal", Stable, &["vector"]),
("vector-packed-decimal-enhancement", Stable, &["vector-packed-decimal"]),
("vector-packed-decimal-enhancement-2", Stable, &["vector-packed-decimal-enhancement"]),
("vector-packed-decimal-enhancement-3", Stable, &["vector-packed-decimal-enhancement-2"]),
// tidy-alphabetical-end
];

View file

@ -850,7 +850,7 @@ impl<T> Box<[T]> {
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[unstable(feature = "alloc_slice_into_array", issue = "148082")]
#[inline]
#[must_use]
pub fn into_array<const N: usize>(self) -> Option<Box<[T; N]>> {

View file

@ -1166,7 +1166,7 @@ impl<T> Rc<[T]> {
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[unstable(feature = "alloc_slice_into_array", issue = "148082")]
#[inline]
#[must_use]
pub fn into_array<const N: usize>(self) -> Option<Rc<[T; N]>> {

View file

@ -1314,7 +1314,7 @@ impl<T> Arc<[T]> {
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[unstable(feature = "alloc_slice_into_array", issue = "148082")]
#[inline]
#[must_use]
pub fn into_array<const N: usize>(self) -> Option<Arc<[T; N]>> {

View file

@ -121,7 +121,6 @@
#![feature(ptr_alignment_type)]
#![feature(ptr_metadata)]
#![feature(set_ptr_value)]
#![feature(slice_as_array)]
#![feature(slice_ptr_get)]
#![feature(str_internals)]
#![feature(str_split_inclusive_remainder)]

View file

@ -660,12 +660,15 @@ macro_rules! nonzero_integer {
without modifying the original"]
#[inline(always)]
pub const fn isolate_highest_one(self) -> Self {
let n = self.get() & (((1 as $Int) << (<$Int>::BITS - 1)).wrapping_shr(self.leading_zeros()));
// SAFETY:
// `self` is non-zero, so masking to preserve only the most
// significant set bit will result in a non-zero `n`.
unsafe { NonZero::new_unchecked(n) }
// and self.leading_zeros() is always < $INT::BITS since
// at least one of the bits in the number is not zero
unsafe {
let bit = (((1 as $Uint) << (<$Uint>::BITS - 1)).unchecked_shr(self.leading_zeros()));
NonZero::new_unchecked(bit as $Int)
}
}
/// Returns `self` with only the least significant bit set.

View file

@ -1462,7 +1462,8 @@ impl<T> *const [T] {
/// Gets a raw pointer to the underlying array.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[must_use]
pub const fn as_array<const N: usize>(self) -> Option<*const [T; N]> {

View file

@ -1712,7 +1712,8 @@ impl<T> *mut [T] {
/// Gets a raw, mutable pointer to the underlying array.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[must_use]
pub const fn as_mut_array<const N: usize>(self) -> Option<*mut [T; N]> {

View file

@ -841,7 +841,8 @@ impl<T> [T] {
/// Gets a reference to the underlying array.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[must_use]
pub const fn as_array<const N: usize>(&self) -> Option<&[T; N]> {
@ -859,7 +860,8 @@ impl<T> [T] {
/// Gets a mutable reference to the slice's underlying array.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[must_use]
pub const fn as_mut_array<const N: usize>(&mut self) -> Option<&mut [T; N]> {

View file

@ -672,7 +672,7 @@ pub mod arch {
pub use std_detect::is_loongarch_feature_detected;
#[unstable(feature = "is_riscv_feature_detected", issue = "111192")]
pub use std_detect::is_riscv_feature_detected;
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
#[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")]
pub use std_detect::is_s390x_feature_detected;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub use std_detect::is_x86_feature_detected;

View file

@ -8,10 +8,6 @@
all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")),
feature(stdarch_aarch64_feature_detection)
)]
#![cfg_attr(
all(target_arch = "s390x", target_os = "linux"),
feature(stdarch_s390x_feature_detection)
)]
#![cfg_attr(
all(target_arch = "powerpc", target_os = "linux"),
feature(stdarch_powerpc_feature_detection)

View file

@ -66,10 +66,12 @@ crate from working on applications in which `std` is not available.
* FreeBSD:
* `arm32`, `powerpc64`: `std_detect` supports these on FreeBSD by querying ELF
auxiliary vectors using `sysctl`.
auxiliary vectors using `elf_aux_info`.
* `arm64`: run-time feature detection is implemented by directly querying `mrs`.
* OpenBSD:
* `powerpc64`: `std_detect` supports these on OpenBSD by querying ELF auxiliary
vectors using `elf_aux_info`.
* `arm64`: run-time feature detection is implemented by querying `sysctl`.
* Windows:

View file

@ -60,7 +60,7 @@ cfg_select! {
pub use loongarch::*;
}
target_arch = "s390x" => {
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
#[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")]
pub use s390x::*;
}
_ => {

View file

@ -9,76 +9,53 @@ features! {
///
/// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`)
/// the macro expands to `true`.
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] concurrent_functions: "concurrent-functions";
#[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")]
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] concurrent_functions: "concurrent-functions";
/// s390x concurrent-functions facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] deflate_conversion: "deflate-conversion";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] deflate_conversion: "deflate-conversion";
/// s390x deflate-conversion facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] enhanced_sort: "enhanced-sort";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] enhanced_sort: "enhanced-sort";
/// s390x enhanced-sort facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] guarded_storage: "guarded-storage";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] guarded_storage: "guarded-storage";
/// s390x guarded-storage facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] high_word: "high-word";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] high_word: "high-word";
/// s390x high-word facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension3: "message-security-assist-extension3";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension3: "message-security-assist-extension3";
/// s390x message-security-assist-extension3 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension4: "message-security-assist-extension4";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension4: "message-security-assist-extension4";
/// s390x message-security-assist-extension4 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension5: "message-security-assist-extension5";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension5: "message-security-assist-extension5";
/// s390x message-security-assist-extension5 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension8: "message-security-assist-extension8";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension8: "message-security-assist-extension8";
/// s390x message-security-assist-extension8 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension9: "message-security-assist-extension9";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension9: "message-security-assist-extension9";
/// s390x message-security-assist-extension9 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension12: "message-security-assist-extension12";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension12: "message-security-assist-extension12";
/// s390x message-security-assist-extension12 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_2: "miscellaneous-extensions-2";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_2: "miscellaneous-extensions-2";
/// s390x miscellaneous-extensions-2 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_3: "miscellaneous-extensions-3";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_3: "miscellaneous-extensions-3";
/// s390x miscellaneous-extensions-3 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_4: "miscellaneous-extensions-4";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_4: "miscellaneous-extensions-4";
/// s390x miscellaneous-extensions-4 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] nnp_assist: "nnp-assist";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] nnp_assist: "nnp-assist";
/// s390x nnp-assist facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] transactional_execution: "transactional-execution";
@FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] transactional_execution: "transactional-execution";
/// s390x transactional-execution facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector: "vector";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector: "vector";
/// s390x vector facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_1: "vector-enhancements-1";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_1: "vector-enhancements-1";
/// s390x vector-enhancements-1 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_2: "vector-enhancements-2";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_2: "vector-enhancements-2";
/// s390x vector-enhancements-2 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_3: "vector-enhancements-3";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_3: "vector-enhancements-3";
/// s390x vector-enhancements-3 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal: "vector-packed-decimal";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal: "vector-packed-decimal";
/// s390x vector-packed-decimal facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement";
/// s390x vector-packed-decimal-enhancement facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2";
/// s390x vector-packed-decimal-enhancement-2 facility
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
@FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3";
@FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3";
/// s390x vector-packed-decimal-enhancement-3 facility
}

View file

@ -61,11 +61,12 @@ cfg_select! {
#[path = "os/freebsd/mod.rs"]
mod os;
}
all(target_os = "openbsd", target_arch = "aarch64", feature = "libc") => {
all(target_os = "openbsd", feature = "libc") => {
#[allow(dead_code)] // we don't use code that calls the mrs instruction.
#[cfg(target_arch = "aarch64")]
#[path = "os/aarch64.rs"]
mod aarch64;
#[path = "os/openbsd/aarch64.rs"]
#[path = "os/openbsd/mod.rs"]
mod os;
}
all(target_os = "windows", any(target_arch = "aarch64", target_arch = "arm64ec")) => {

View file

@ -0,0 +1,54 @@
//! Parses ELF auxiliary vectors.
#![cfg_attr(
any(target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64"),
allow(dead_code)
)]
/// Cache HWCAP bitfields of the ELF Auxiliary Vector.
///
/// If an entry cannot be read all the bits in the bitfield are set to zero.
/// This should be interpreted as all the features being disabled.
#[derive(Debug, Copy, Clone)]
pub(crate) struct AuxVec {
pub hwcap: usize,
pub hwcap2: usize,
}
/// ELF Auxiliary Vector
///
/// The auxiliary vector is a memory region in a running ELF program's stack
/// composed of (key: usize, value: usize) pairs.
///
/// The keys used in the aux vector are platform dependent. For OpenBSD, they are
/// defined in [machine/elf.h][elfh]. The hardware capabilities of a given CPU
/// can be queried with the `AT_HWCAP` and `AT_HWCAP2` keys.
///
/// Note that run-time feature detection is not invoked for features that can
/// be detected at compile-time.
///
/// [elf.h]: https://github.com/openbsd/src/blob/master/sys/arch/arm64/include/elf.h
/// [elf.h]: https://github.com/openbsd/src/blob/master/sys/arch/powerpc64/include/elf.h
pub(crate) fn auxv() -> Result<AuxVec, ()> {
let hwcap = archauxv(libc::AT_HWCAP);
let hwcap2 = archauxv(libc::AT_HWCAP2);
// Zero could indicate that no features were detected, but it's also used to
// indicate an error. In particular, on many platforms AT_HWCAP2 will be
// legitimately zero, since it contains the most recent feature flags.
if hwcap != 0 || hwcap2 != 0 {
return Ok(AuxVec { hwcap, hwcap2 });
}
Err(())
}
/// Tries to read the `key` from the auxiliary vector.
fn archauxv(key: libc::c_int) -> usize {
const OUT_LEN: libc::c_int = core::mem::size_of::<libc::c_ulong>() as libc::c_int;
let mut out: libc::c_ulong = 0;
unsafe {
let res =
libc::elf_aux_info(key, &mut out as *mut libc::c_ulong as *mut libc::c_void, OUT_LEN);
// If elf_aux_info fails, `out` will be left at zero (which is the proper default value).
debug_assert!(res == 0 || out == 0);
}
out as usize
}

View file

@ -0,0 +1,21 @@
//! Run-time feature detection on OpenBSD
mod auxvec;
cfg_select! {
target_arch = "aarch64" => {
mod aarch64;
pub(crate) use self::aarch64::detect_features;
}
target_arch = "powerpc64" => {
mod powerpc;
pub(crate) use self::powerpc::detect_features;
}
_ => {
use crate::detect::cache;
/// Performs run-time feature detection.
pub(crate) fn detect_features() -> cache::Initializer {
cache::Initializer::default()
}
}
}

View file

@ -0,0 +1,21 @@
//! Run-time feature detection for PowerPC on OpenBSD.
use super::auxvec;
use crate::detect::{Feature, cache};
pub(crate) fn detect_features() -> cache::Initializer {
let mut value = cache::Initializer::default();
let enable_feature = |value: &mut cache::Initializer, f, enable| {
if enable {
value.set(f as u32);
}
};
if let Ok(auxv) = auxvec::auxv() {
enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0);
enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0);
enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0);
return value;
}
value
}

View file

@ -11,7 +11,6 @@
)]
#![cfg_attr(target_arch = "powerpc", feature(stdarch_powerpc_feature_detection))]
#![cfg_attr(target_arch = "powerpc64", feature(stdarch_powerpc_feature_detection))]
#![cfg_attr(target_arch = "s390x", feature(stdarch_s390x_feature_detection))]
#![allow(clippy::unwrap_used, clippy::use_debug, clippy::print_stdout)]
#[cfg_attr(
@ -320,8 +319,11 @@ fn powerpc_linux() {
}
#[test]
#[cfg(all(target_arch = "powerpc64", any(target_os = "linux", target_os = "freebsd"),))]
fn powerpc64_linux_or_freebsd() {
#[cfg(all(
target_arch = "powerpc64",
any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
))]
fn powerpc64_linux_or_bsd() {
println!("altivec: {}", is_powerpc64_feature_detected!("altivec"));
println!("vsx: {}", is_powerpc64_feature_detected!("vsx"));
println!("power8: {}", is_powerpc64_feature_detected!("power8"));

View file

@ -25,7 +25,6 @@
any(target_arch = "powerpc", target_arch = "powerpc64"),
feature(stdarch_powerpc_feature_detection)
)]
#![cfg_attr(target_arch = "s390x", feature(stdarch_s390x_feature_detection))]
#![cfg_attr(
any(target_arch = "riscv32", target_arch = "riscv64"),
feature(stdarch_riscv_feature_detection)

View file

@ -22,7 +22,6 @@
arm_target_feature,
mips_target_feature,
powerpc_target_feature,
s390x_target_feature,
loongarch_target_feature,
wasm_target_feature,
abi_unadjusted,
@ -64,11 +63,7 @@
)]
#![cfg_attr(
test,
feature(
stdarch_arm_feature_detection,
stdarch_powerpc_feature_detection,
stdarch_s390x_feature_detection
)
feature(stdarch_arm_feature_detection, stdarch_powerpc_feature_detection,)
)]
#[cfg(test)]

View file

@ -73,7 +73,7 @@ book!(
EditionGuide, "src/doc/edition-guide", "edition-guide", &[];
EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[];
Nomicon, "src/doc/nomicon", "nomicon", &[];
RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja", "zh"];
RustByExample, "src/doc/rust-by-example", "rust-by-example", &["es", "ja", "zh"];
RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
StyleGuide, "src/doc/style-guide", "style-guide", &[];
);

View file

@ -47,71 +47,69 @@ pub(crate) fn print_generic_bounds(
bounds
.iter()
.filter(move |b| bounds_dup.insert(*b))
.map(|bound| bound.print(cx))
.map(|bound| print_generic_bound(bound, cx))
.joined(" + ", f)
})
}
impl clean::GenericParamDef {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match &self.kind {
clean::GenericParamDefKind::Lifetime { outlives } => {
write!(f, "{}", self.name)?;
pub(crate) fn print_generic_param_def(
generic_param: &clean::GenericParamDef,
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| match &generic_param.kind {
clean::GenericParamDefKind::Lifetime { outlives } => {
write!(f, "{}", generic_param.name)?;
if !outlives.is_empty() {
f.write_str(": ")?;
outlives.iter().map(|lt| lt.print()).joined(" + ", f)?;
}
Ok(())
if !outlives.is_empty() {
f.write_str(": ")?;
outlives.iter().map(|lt| print_lifetime(lt)).joined(" + ", f)?;
}
clean::GenericParamDefKind::Type { bounds, default, .. } => {
f.write_str(self.name.as_str())?;
if !bounds.is_empty() {
f.write_str(": ")?;
print_generic_bounds(bounds, cx).fmt(f)?;
}
Ok(())
}
clean::GenericParamDefKind::Type { bounds, default, .. } => {
f.write_str(generic_param.name.as_str())?;
if let Some(ty) = default {
f.write_str(" = ")?;
ty.print(cx).fmt(f)?;
}
Ok(())
if !bounds.is_empty() {
f.write_str(": ")?;
print_generic_bounds(bounds, cx).fmt(f)?;
}
clean::GenericParamDefKind::Const { ty, default, .. } => {
write!(f, "const {}: ", self.name)?;
ty.print(cx).fmt(f)?;
if let Some(default) = default {
f.write_str(" = ")?;
if f.alternate() {
write!(f, "{default}")?;
} else {
write!(f, "{}", Escape(default))?;
}
}
Ok(())
if let Some(ty) = default {
f.write_str(" = ")?;
print_type(ty, cx).fmt(f)?;
}
})
}
Ok(())
}
clean::GenericParamDefKind::Const { ty, default, .. } => {
write!(f, "const {}: ", generic_param.name)?;
print_type(ty, cx).fmt(f)?;
if let Some(default) = default {
f.write_str(" = ")?;
if f.alternate() {
write!(f, "{default}")?;
} else {
write!(f, "{}", Escape(default))?;
}
}
Ok(())
}
})
}
impl clean::Generics {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
if real_params.peek().is_none() {
None
} else {
Some(
Wrapped::with_angle_brackets()
.wrap_fn(move |f| real_params.clone().map(|g| g.print(cx)).joined(", ", f)),
)
}
.maybe_display()
pub(crate) fn print_generics(generics: &clean::Generics, cx: &Context<'_>) -> impl Display {
let mut real_params = generics.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
if real_params.peek().is_none() {
None
} else {
Some(Wrapped::with_angle_brackets().wrap_fn(move |f| {
real_params.clone().map(|g| print_generic_param_def(g, cx)).joined(", ", f)
}))
}
.maybe_display()
}
#[derive(Clone, Copy, PartialEq, Eq)]
@ -125,7 +123,7 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) ->
match predicate {
clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
print_higher_ranked_params_with_space(bound_params, cx, "for").fmt(f)?;
ty.print(cx).fmt(f)?;
print_type(ty, cx).fmt(f)?;
f.write_str(":")?;
if !bounds.is_empty() {
f.write_str(" ")?;
@ -136,7 +134,7 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) ->
clean::WherePredicate::RegionPredicate { lifetime, bounds } => {
// We don't need to check `alternate` since we can be certain that neither
// the lifetime nor the bounds contain any characters which need escaping.
write!(f, "{}:", lifetime.print())?;
write!(f, "{}:", print_lifetime(lifetime))?;
if !bounds.is_empty() {
write!(f, " {}", print_generic_bounds(bounds, cx))?;
}
@ -144,7 +142,12 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) ->
}
clean::WherePredicate::EqPredicate { lhs, rhs } => {
let opts = WithOpts::from(f);
write!(f, "{} == {}", opts.display(lhs.print(cx)), opts.display(rhs.print(cx)))
write!(
f,
"{} == {}",
opts.display(print_qpath_data(lhs, cx)),
opts.display(print_term(rhs, cx)),
)
}
}
})
@ -229,92 +232,91 @@ pub(crate) fn print_where_clause(
}))
}
impl clean::Lifetime {
pub(crate) fn print(&self) -> impl Display {
self.0.as_str()
}
#[inline]
pub(crate) fn print_lifetime(lt: &clean::Lifetime) -> &str {
lt.0.as_str()
}
impl clean::ConstantKind {
pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display {
let expr = self.expr(tcx);
fmt::from_fn(move |f| {
pub(crate) fn print_constant_kind(
constant_kind: &clean::ConstantKind,
tcx: TyCtxt<'_>,
) -> impl Display {
let expr = constant_kind.expr(tcx);
fmt::from_fn(
move |f| {
if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
})
}
},
)
}
impl clean::PolyTrait {
fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
self.trait_.print(cx).fmt(f)
})
}
fn print_poly_trait(poly_trait: &clean::PolyTrait, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
print_higher_ranked_params_with_space(&poly_trait.generic_params, cx, "for").fmt(f)?;
print_path(&poly_trait.trait_, cx).fmt(f)
})
}
impl clean::GenericBound {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match self {
clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
clean::GenericBound::TraitBound(ty, modifiers) => {
// `const` and `[const]` trait bounds are experimental; don't render them.
let hir::TraitBoundModifiers { polarity, constness: _ } = modifiers;
f.write_str(match polarity {
hir::BoundPolarity::Positive => "",
hir::BoundPolarity::Maybe(_) => "?",
hir::BoundPolarity::Negative(_) => "!",
})?;
ty.print(cx).fmt(f)
}
clean::GenericBound::Use(args) => {
f.write_str("use")?;
Wrapped::with_angle_brackets()
.wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f))
.fmt(f)
}
})
}
pub(crate) fn print_generic_bound(
generic_bound: &clean::GenericBound,
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| match generic_bound {
clean::GenericBound::Outlives(lt) => f.write_str(print_lifetime(lt)),
clean::GenericBound::TraitBound(ty, modifiers) => {
// `const` and `[const]` trait bounds are experimental; don't render them.
let hir::TraitBoundModifiers { polarity, constness: _ } = modifiers;
f.write_str(match polarity {
hir::BoundPolarity::Positive => "",
hir::BoundPolarity::Maybe(_) => "?",
hir::BoundPolarity::Negative(_) => "!",
})?;
print_poly_trait(ty, cx).fmt(f)
}
clean::GenericBound::Use(args) => {
f.write_str("use")?;
Wrapped::with_angle_brackets()
.wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f))
.fmt(f)
}
})
}
impl clean::GenericArgs {
fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
match self {
clean::GenericArgs::AngleBracketed { args, constraints } => {
if !args.is_empty() || !constraints.is_empty() {
Wrapped::with_angle_brackets()
.wrap_fn(|f| {
[Either::Left(args), Either::Right(constraints)]
.into_iter()
.flat_map(Either::factor_into_iter)
.map(|either| {
either.map_either(
|arg| arg.print(cx),
|constraint| constraint.print(cx),
)
})
.joined(", ", f)
})
.fmt(f)?;
}
}
clean::GenericArgs::Parenthesized { inputs, output } => {
Wrapped::with_parens()
.wrap_fn(|f| inputs.iter().map(|ty| ty.print(cx)).joined(", ", f))
fn print_generic_args(generic_args: &clean::GenericArgs, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
match generic_args {
clean::GenericArgs::AngleBracketed { args, constraints } => {
if !args.is_empty() || !constraints.is_empty() {
Wrapped::with_angle_brackets()
.wrap_fn(|f| {
[Either::Left(args), Either::Right(constraints)]
.into_iter()
.flat_map(Either::factor_into_iter)
.map(|either| {
either.map_either(
|arg| print_generic_arg(arg, cx),
|constraint| print_assoc_item_constraint(constraint, cx),
)
})
.joined(", ", f)
})
.fmt(f)?;
if let Some(ref ty) = *output {
f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
ty.print(cx).fmt(f)?;
}
}
clean::GenericArgs::ReturnTypeNotation => {
f.write_str("(..)")?;
}
}
Ok(())
})
}
clean::GenericArgs::Parenthesized { inputs, output } => {
Wrapped::with_parens()
.wrap_fn(|f| inputs.iter().map(|ty| print_type(ty, cx)).joined(", ", f))
.fmt(f)?;
if let Some(ref ty) = *output {
f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
print_type(ty, cx).fmt(f)?;
}
}
clean::GenericArgs::ReturnTypeNotation => {
f.write_str("(..)")?;
}
}
Ok(())
})
}
// Possible errors when computing href link source for a `DefId`
@ -684,7 +686,7 @@ fn resolved_path(
}
}
if w.alternate() {
write!(w, "{}{:#}", last.name, last.args.print(cx))?;
write!(w, "{}{:#}", last.name, print_generic_args(&last.args, cx))?;
} else {
let path = fmt::from_fn(|f| {
if use_absolute {
@ -702,7 +704,7 @@ fn resolved_path(
write!(f, "{}", print_anchor(did, last.name, cx))
}
});
write!(w, "{path}{args}", args = last.args.print(cx))?;
write!(w, "{path}{args}", args = print_generic_args(&last.args, cx))?;
}
Ok(())
}
@ -791,11 +793,11 @@ fn print_tybounds(
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| {
bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?;
bounds.iter().map(|bound| print_poly_trait(bound, cx)).joined(" + ", f)?;
if let Some(lt) = lt {
// We don't need to check `alternate` since we can be certain that
// the lifetime doesn't contain any characters which need escaping.
write!(f, " + {}", lt.print())?;
write!(f, " + {}", print_lifetime(lt))?;
}
Ok(())
})
@ -810,7 +812,9 @@ fn print_higher_ranked_params_with_space(
if !params.is_empty() {
f.write_str(keyword)?;
Wrapped::with_angle_brackets()
.wrap_fn(|f| params.iter().map(|lt| lt.print(cx)).joined(", ", f))
.wrap_fn(|f| {
params.iter().map(|lt| print_generic_param_def(lt, cx)).joined(", ", f)
})
.fmt(f)?;
f.write_char(' ')?;
}
@ -868,11 +872,11 @@ fn fmt_type(
} else {
primitive_link(f, PrimitiveType::Fn, format_args!("fn"), cx)?;
}
decl.decl.print(cx).fmt(f)
print_fn_decl(&decl.decl, cx).fmt(f)
}
clean::UnsafeBinder(binder) => {
print_higher_ranked_params_with_space(&binder.generic_params, cx, "unsafe").fmt(f)?;
binder.ty.print(cx).fmt(f)
print_type(&binder.ty, cx).fmt(f)
}
clean::Tuple(typs) => match &typs[..] {
&[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx),
@ -881,7 +885,7 @@ fn fmt_type(
primitive_link(f, PrimitiveType::Tuple, format_args!("({name},)"), cx)
} else {
write!(f, "(")?;
one.print(cx).fmt(f)?;
print_type(one, cx).fmt(f)?;
write!(f, ",)")
}
}
@ -907,7 +911,7 @@ fn fmt_type(
)
} else {
Wrapped::with_parens()
.wrap_fn(|f| many.iter().map(|item| item.print(cx)).joined(", ", f))
.wrap_fn(|f| many.iter().map(|item| print_type(item, cx)).joined(", ", f))
.fmt(f)
}
}
@ -915,9 +919,9 @@ fn fmt_type(
clean::Slice(box clean::Generic(name)) => {
primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx)
}
clean::Slice(t) => Wrapped::with_square_brackets().wrap(t.print(cx)).fmt(f),
clean::Slice(t) => Wrapped::with_square_brackets().wrap(print_type(t, cx)).fmt(f),
clean::Type::Pat(t, pat) => {
fmt::Display::fmt(&t.print(cx), f)?;
fmt::Display::fmt(&print_type(t, cx), f)?;
write!(f, " is {pat}")
}
clean::Array(box clean::Generic(name), n) if !f.alternate() => primitive_link(
@ -928,7 +932,7 @@ fn fmt_type(
),
clean::Array(t, n) => Wrapped::with_square_brackets()
.wrap(fmt::from_fn(|f| {
t.print(cx).fmt(f)?;
print_type(t, cx).fmt(f)?;
f.write_str("; ")?;
if f.alternate() {
f.write_str(n)
@ -944,17 +948,17 @@ fn fmt_type(
primitive_link(
f,
clean::PrimitiveType::RawPointer,
format_args!("*{m} {ty}", ty = WithOpts::from(f).display(t.print(cx))),
format_args!("*{m} {ty}", ty = WithOpts::from(f).display(print_type(t, cx))),
cx,
)
} else {
primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?;
t.print(cx).fmt(f)
print_type(t, cx).fmt(f)
}
}
clean::BorrowedRef { lifetime: l, mutability, type_: ty } => {
let lt = fmt::from_fn(|f| match l {
Some(l) => write!(f, "{} ", l.print()),
Some(l) => write!(f, "{} ", print_lifetime(l)),
_ => Ok(()),
});
let m = mutability.print_with_space();
@ -989,133 +993,133 @@ fn fmt_type(
f.write_str("impl ")?;
print_generic_bounds(bounds, cx).fmt(f)
}
clean::QPath(qpath) => qpath.print(cx).fmt(f),
clean::QPath(qpath) => print_qpath_data(qpath, cx).fmt(f),
}
}
impl clean::Type {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| fmt_type(self, f, false, cx))
}
pub(crate) fn print_type(type_: &clean::Type, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| fmt_type(type_, f, false, cx))
}
impl clean::Path {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
}
pub(crate) fn print_path(path: &clean::Path, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| resolved_path(f, path.def_id(), path, false, false, cx))
}
impl clean::QPathData {
fn print(&self, cx: &Context<'_>) -> impl Display {
let Self { ref assoc, ref self_type, should_fully_qualify, ref trait_ } = *self;
fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Display {
let clean::QPathData { ref assoc, ref self_type, should_fully_qualify, ref trait_ } =
*qpath_data;
fmt::from_fn(move |f| {
// FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
// we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
fmt::from_fn(move |f| {
// FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
// we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
if let Some(trait_) = trait_
&& should_fully_qualify
{
let opts = WithOpts::from(f);
Wrapped::with_angle_brackets()
.wrap(format_args!(
"{} as {}",
opts.display(self_type.print(cx)),
opts.display(trait_.print(cx))
))
.fmt(f)?
} else {
self_type.print(cx).fmt(f)?;
}
f.write_str("::")?;
// 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).
if !f.alternate() {
// FIXME(inherent_associated_types): We always link to the very first associated
// type (in respect to source order) that bears the given name (`assoc.name`) and that is
// affiliated with the computed `DefId`. This is obviously incorrect when we have
// multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself
// through here and map it to the corresponding HTML ID that was generated by
// `render::Context::derive_id` when the impl blocks were rendered.
// There is no such mapping unfortunately.
// As a hack, we could badly imitate `derive_id` here by keeping *count* when looking
// for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()`
// considering privacy, `doc(hidden)`, etc.
// I don't feel like that right now :cold_sweat:.
if let Some(trait_) = trait_
&& should_fully_qualify
{
let opts = WithOpts::from(f);
Wrapped::with_angle_brackets()
.wrap(format_args!(
"{} as {}",
opts.display(print_type(self_type, cx)),
opts.display(print_path(trait_, cx))
))
.fmt(f)?
} else {
print_type(self_type, cx).fmt(f)?;
}
f.write_str("::")?;
// 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).
if !f.alternate() {
// FIXME(inherent_associated_types): We always link to the very first associated
// type (in respect to source order) that bears the given name (`assoc.name`) and that is
// affiliated with the computed `DefId`. This is obviously incorrect when we have
// multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself
// through here and map it to the corresponding HTML ID that was generated by
// `render::Context::derive_id` when the impl blocks were rendered.
// There is no such mapping unfortunately.
// As a hack, we could badly imitate `derive_id` here by keeping *count* when looking
// for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()`
// considering privacy, `doc(hidden)`, etc.
// I don't feel like that right now :cold_sweat:.
let parent_href = match trait_ {
Some(trait_) => href(trait_.def_id(), cx).ok(),
None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()),
};
let parent_href = match trait_ {
Some(trait_) => href(trait_.def_id(), cx).ok(),
None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()),
};
if let Some((url, _, path)) = parent_href {
write!(
f,
"<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
title=\"type {path}::{name}\">{name}</a>",
shortty = ItemType::AssocType,
name = assoc.name,
path = join_path_syms(path),
)
} else {
write!(f, "{}", assoc.name)
}
if let Some((url, _, path)) = parent_href {
write!(
f,
"<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
title=\"type {path}::{name}\">{name}</a>",
shortty = ItemType::AssocType,
name = assoc.name,
path = join_path_syms(path),
)
} else {
write!(f, "{}", assoc.name)
}?;
}
} else {
write!(f, "{}", assoc.name)
}?;
assoc.args.print(cx).fmt(f)
})
}
print_generic_args(&assoc.args, cx).fmt(f)
})
}
pub(crate) fn print_impl(
impl_: &clean::Impl,
use_absolute: bool,
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| {
f.write_str("impl")?;
print_generics(&impl_.generics, cx).fmt(f)?;
f.write_str(" ")?;
if let Some(ref ty) = impl_.trait_ {
if impl_.is_negative_trait_impl() {
f.write_char('!')?;
}
if impl_.kind.is_fake_variadic()
&& let Some(generics) = ty.generics()
&& let Ok(inner_type) = generics.exactly_one()
{
let last = ty.last();
if f.alternate() {
write!(f, "{last}")?;
} else {
write!(f, "{}", print_anchor(ty.def_id(), last, cx))?;
};
Wrapped::with_angle_brackets()
.wrap_fn(|f| impl_.print_type(inner_type, f, use_absolute, cx))
.fmt(f)?;
} else {
print_path(ty, cx).fmt(f)?;
}
f.write_str(" for ")?;
}
if let Some(ty) = impl_.kind.as_blanket_ty() {
fmt_type(ty, f, use_absolute, cx)?;
} else {
impl_.print_type(&impl_.for_, f, use_absolute, cx)?;
}
print_where_clause(&impl_.generics, cx, 0, Ending::Newline).maybe_display().fmt(f)
})
}
impl clean::Impl {
pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
f.write_str("impl")?;
self.generics.print(cx).fmt(f)?;
f.write_str(" ")?;
if let Some(ref ty) = self.trait_ {
if self.is_negative_trait_impl() {
f.write_char('!')?;
}
if self.kind.is_fake_variadic()
&& let Some(generics) = ty.generics()
&& let Ok(inner_type) = generics.exactly_one()
{
let last = ty.last();
if f.alternate() {
write!(f, "{last}")?;
} else {
write!(f, "{}", print_anchor(ty.def_id(), last, cx))?;
};
Wrapped::with_angle_brackets()
.wrap_fn(|f| self.print_type(inner_type, f, use_absolute, cx))
.fmt(f)?;
} else {
ty.print(cx).fmt(f)?;
}
f.write_str(" for ")?;
}
if let Some(ty) = self.kind.as_blanket_ty() {
fmt_type(ty, f, use_absolute, cx)?;
} else {
self.print_type(&self.for_, f, use_absolute, cx)?;
}
print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f)
})
}
fn print_type(
&self,
type_: &clean::Type,
@ -1191,7 +1195,7 @@ pub(crate) fn print_params(params: &[clean::Parameter], cx: &Context<'_>) -> imp
if let Some(name) = param.name {
write!(f, "{name}: ")?;
}
param.type_.print(cx).fmt(f)
print_type(&param.type_, cx).fmt(f)
})
})
.joined(", ", f)
@ -1221,76 +1225,73 @@ impl Display for Indent {
}
}
impl clean::Parameter {
fn print(&self, cx: &Context<'_>) -> impl fmt::Display {
fmt::from_fn(move |f| {
if let Some(self_ty) = self.to_receiver() {
match self_ty {
clean::SelfTy => f.write_str("self"),
clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
f.write_str(if f.alternate() { "&" } else { "&amp;" })?;
if let Some(lt) = lifetime {
write!(f, "{lt} ", lt = lt.print())?;
}
write!(f, "{mutability}self", mutability = mutability.print_with_space())
}
_ => {
f.write_str("self: ")?;
self_ty.print(cx).fmt(f)
fn print_parameter(parameter: &clean::Parameter, cx: &Context<'_>) -> impl fmt::Display {
fmt::from_fn(move |f| {
if let Some(self_ty) = parameter.to_receiver() {
match self_ty {
clean::SelfTy => f.write_str("self"),
clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
f.write_str(if f.alternate() { "&" } else { "&amp;" })?;
if let Some(lt) = lifetime {
write!(f, "{lt} ", lt = print_lifetime(lt))?;
}
write!(f, "{mutability}self", mutability = mutability.print_with_space())
}
} else {
if self.is_const {
write!(f, "const ")?;
_ => {
f.write_str("self: ")?;
print_type(self_ty, cx).fmt(f)
}
if let Some(name) = self.name {
write!(f, "{name}: ")?;
}
self.type_.print(cx).fmt(f)
}
})
}
} else {
if parameter.is_const {
write!(f, "const ")?;
}
if let Some(name) = parameter.name {
write!(f, "{name}: ")?;
}
print_type(&parameter.type_, cx).fmt(f)
}
})
}
fn print_fn_decl(fn_decl: &clean::FnDecl, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
let ellipsis = if fn_decl.c_variadic { ", ..." } else { "" };
Wrapped::with_parens()
.wrap_fn(|f| {
print_params(&fn_decl.inputs, cx).fmt(f)?;
f.write_str(ellipsis)
})
.fmt(f)?;
fn_decl.print_output(cx).fmt(f)
})
}
/// * `header_len`: The length of the function header and name. In other words, the number of
/// characters in the function declaration up to but not including the parentheses.
/// This is expected to go into a `<pre>`/`code-header` block, so indentation and newlines
/// are preserved.
/// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
/// necessary.
pub(crate) fn full_print_fn_decl(
fn_decl: &clean::FnDecl,
header_len: usize,
indent: usize,
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| {
// First, generate the text form of the declaration, with no line wrapping, and count the bytes.
let mut counter = WriteCounter(0);
write!(&mut counter, "{:#}", fmt::from_fn(|f| { fn_decl.inner_full_print(None, f, cx) }))?;
// If the text form was over 80 characters wide, we will line-wrap our output.
let line_wrapping_indent = if header_len + counter.0 > 80 { Some(indent) } else { None };
// Generate the final output. This happens to accept `{:#}` formatting to get textual
// output but in practice it is only formatted with `{}` to get HTML output.
fn_decl.inner_full_print(line_wrapping_indent, f, cx)
})
}
impl clean::FnDecl {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
let ellipsis = if self.c_variadic { ", ..." } else { "" };
Wrapped::with_parens()
.wrap_fn(|f| {
print_params(&self.inputs, cx).fmt(f)?;
f.write_str(ellipsis)
})
.fmt(f)?;
self.print_output(cx).fmt(f)
})
}
/// * `header_len`: The length of the function header and name. In other words, the number of
/// characters in the function declaration up to but not including the parentheses.
/// This is expected to go into a `<pre>`/`code-header` block, so indentation and newlines
/// are preserved.
/// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
/// necessary.
pub(crate) fn full_print(
&self,
header_len: usize,
indent: usize,
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| {
// First, generate the text form of the declaration, with no line wrapping, and count the bytes.
let mut counter = WriteCounter(0);
write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))?;
// If the text form was over 80 characters wide, we will line-wrap our output.
let line_wrapping_indent =
if header_len + counter.0 > 80 { Some(indent) } else { None };
// Generate the final output. This happens to accept `{:#}` formatting to get textual
// output but in practice it is only formatted with `{}` to get HTML output.
self.inner_full_print(line_wrapping_indent, f, cx)
})
}
fn inner_full_print(
&self,
// For None, the declaration will not be line-wrapped. For Some(n),
@ -1316,7 +1317,7 @@ impl clean::FnDecl {
}
});
self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
self.inputs.iter().map(|param| print_parameter(param, cx)).joined(sep, f)?;
if line_wrapping_indent.is_some() {
writeln!(f, ",")?
@ -1348,7 +1349,7 @@ impl clean::FnDecl {
}
f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
self.output.print(cx).fmt(f)
print_type(&self.output, cx).fmt(f)
})
}
}
@ -1461,67 +1462,68 @@ pub(crate) fn print_constness_with_space(
}
}
impl clean::Import {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match self.kind {
clean::ImportKind::Simple(name) => {
if name == self.source.path.last() {
write!(f, "use {};", self.source.print(cx))
} else {
write!(f, "use {source} as {name};", source = self.source.print(cx))
}
pub(crate) fn print_import(import: &clean::Import, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match import.kind {
clean::ImportKind::Simple(name) => {
if name == import.source.path.last() {
write!(f, "use {};", print_import_source(&import.source, cx))
} else {
write!(
f,
"use {source} as {name};",
source = print_import_source(&import.source, cx)
)
}
clean::ImportKind::Glob => {
if self.source.path.segments.is_empty() {
write!(f, "use *;")
} else {
write!(f, "use {}::*;", self.source.print(cx))
}
}
clean::ImportKind::Glob => {
if import.source.path.segments.is_empty() {
write!(f, "use *;")
} else {
write!(f, "use {}::*;", print_import_source(&import.source, cx))
}
})
}
}
})
}
impl clean::ImportSource {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match self.did {
Some(did) => resolved_path(f, did, &self.path, true, false, cx),
_ => {
for seg in &self.path.segments[..self.path.segments.len() - 1] {
write!(f, "{}::", seg.name)?;
}
let name = self.path.last();
if let hir::def::Res::PrimTy(p) = self.path.res {
primitive_link(f, PrimitiveType::from(p), format_args!("{name}"), cx)?;
} else {
f.write_str(name.as_str())?;
}
Ok(())
fn print_import_source(import_source: &clean::ImportSource, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match import_source.did {
Some(did) => resolved_path(f, did, &import_source.path, true, false, cx),
_ => {
for seg in &import_source.path.segments[..import_source.path.segments.len() - 1] {
write!(f, "{}::", seg.name)?;
}
})
}
}
impl clean::AssocItemConstraint {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
f.write_str(self.assoc.name.as_str())?;
self.assoc.args.print(cx).fmt(f)?;
match self.kind {
clean::AssocItemConstraintKind::Equality { ref term } => {
f.write_str(" = ")?;
term.print(cx).fmt(f)?;
}
clean::AssocItemConstraintKind::Bound { ref bounds } => {
if !bounds.is_empty() {
f.write_str(": ")?;
print_generic_bounds(bounds, cx).fmt(f)?;
}
}
let name = import_source.path.last();
if let hir::def::Res::PrimTy(p) = import_source.path.res {
primitive_link(f, PrimitiveType::from(p), format_args!("{name}"), cx)?;
} else {
f.write_str(name.as_str())?;
}
Ok(())
})
}
}
})
}
fn print_assoc_item_constraint(
assoc_item_constraint: &clean::AssocItemConstraint,
cx: &Context<'_>,
) -> impl Display {
fmt::from_fn(move |f| {
f.write_str(assoc_item_constraint.assoc.name.as_str())?;
print_generic_args(&assoc_item_constraint.assoc.args, cx).fmt(f)?;
match assoc_item_constraint.kind {
clean::AssocItemConstraintKind::Equality { ref term } => {
f.write_str(" = ")?;
print_term(term, cx).fmt(f)?;
}
clean::AssocItemConstraintKind::Bound { ref bounds } => {
if !bounds.is_empty() {
f.write_str(": ")?;
print_generic_bounds(bounds, cx).fmt(f)?;
}
}
}
Ok(())
})
}
pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
@ -1538,22 +1540,18 @@ pub(crate) fn print_default_space(v: bool) -> &'static str {
if v { "default " } else { "" }
}
impl clean::GenericArg {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match self {
clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
clean::GenericArg::Const(ct) => ct.print(cx.tcx()).fmt(f),
clean::GenericArg::Infer => Display::fmt("_", f),
})
}
fn print_generic_arg(generic_arg: &clean::GenericArg, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match generic_arg {
clean::GenericArg::Lifetime(lt) => f.write_str(print_lifetime(lt)),
clean::GenericArg::Type(ty) => print_type(ty, cx).fmt(f),
clean::GenericArg::Const(ct) => print_constant_kind(ct, cx.tcx()).fmt(f),
clean::GenericArg::Infer => f.write_char('_'),
})
}
impl clean::Term {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match self {
clean::Term::Type(ty) => ty.print(cx).fmt(f),
clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),
})
}
fn print_term(term: &clean::Term, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| match term {
clean::Term::Type(ty) => print_type(ty, cx).fmt(f),
clean::Term::Constant(ct) => print_constant_kind(ct, cx.tcx()).fmt(f),
})
}

View file

@ -601,52 +601,52 @@ pub(super) fn write_code(
};
let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, file_span);
Classifier::new(
classify(
&src,
token_handler.href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP),
token_handler.href_context.as_ref().map_or(DUMMY_SP, |c| c.file_span),
decoration_info,
)
.highlight(&mut |span, highlight| match highlight {
Highlight::Token { text, class } => {
token_handler.push_token(class, Cow::Borrowed(text));
&mut |span, highlight| match highlight {
Highlight::Token { text, class } => {
token_handler.push_token(class, Cow::Borrowed(text));
if text == "\n" {
if current_expansion.is_none() {
current_expansion = get_expansion(&mut token_handler, expanded_codes, span);
}
if let Some(ref current_expansion) = current_expansion
&& current_expansion.span.lo() == span.hi()
{
token_handler.add_expanded_code(current_expansion);
}
} else {
let mut need_end = false;
if let Some(ref current_expansion) = current_expansion {
if current_expansion.span.lo() == span.hi() {
token_handler.add_expanded_code(current_expansion);
} else if current_expansion.end_line == token_handler.line
&& span.hi() >= current_expansion.span.hi()
if text == "\n" {
if current_expansion.is_none() {
current_expansion = get_expansion(&mut token_handler, expanded_codes, span);
}
if let Some(ref current_expansion) = current_expansion
&& current_expansion.span.lo() == span.hi()
{
need_end = true;
token_handler.add_expanded_code(current_expansion);
}
} else {
let mut need_end = false;
if let Some(ref current_expansion) = current_expansion {
if current_expansion.span.lo() == span.hi() {
token_handler.add_expanded_code(current_expansion);
} else if current_expansion.end_line == token_handler.line
&& span.hi() >= current_expansion.span.hi()
{
need_end = true;
}
}
if need_end {
current_expansion = end_expansion(&mut token_handler, expanded_codes, span);
}
}
if need_end {
current_expansion = end_expansion(&mut token_handler, expanded_codes, span);
}
}
}
Highlight::EnterSpan { class } => {
token_handler.class_stack.enter_elem(
token_handler.out,
&token_handler.href_context,
class,
None,
);
}
Highlight::ExitSpan => {
token_handler.class_stack.exit_elem();
}
});
Highlight::EnterSpan { class } => {
token_handler.class_stack.enter_elem(
token_handler.out,
&token_handler.href_context,
class,
None,
);
}
Highlight::ExitSpan => {
token_handler.class_stack.exit_elem();
}
},
);
}
fn write_footer(playground_button: Option<&str>) -> impl Display {
@ -770,6 +770,12 @@ struct TokenIter<'a> {
cursor: Cursor<'a>,
}
impl<'a> TokenIter<'a> {
fn new(src: &'a str) -> Self {
Self { src, cursor: Cursor::new(src, FrontmatterAllowed::Yes) }
}
}
impl<'a> Iterator for TokenIter<'a> {
type Item = (TokenKind, &'a str);
fn next(&mut self) -> Option<(TokenKind, &'a str)> {
@ -783,21 +789,6 @@ impl<'a> Iterator for TokenIter<'a> {
}
}
/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option<Class> {
let ignore: &[&str] =
if allow_path_keywords { &["self", "Self", "super", "crate"] } else { &["self", "Self"] };
if ignore.contains(&text) {
return None;
}
Some(match text {
"ref" | "mut" => Class::RefKeyWord,
"false" | "true" => Class::Bool,
_ if Symbol::intern(text).is_reserved(|| Edition::Edition2021) => Class::KeyWord,
_ => return None,
})
}
/// This iterator comes from the same idea than "Peekable" except that it allows to "peek" more than
/// just the next item by using `peek_next`. The `peek` method always returns the next item after
/// the current one whereas `peek_next` will return the next item after the last one peeked.
@ -815,16 +806,16 @@ impl<'a> PeekIter<'a> {
Self { stored: VecDeque::new(), peek_pos: 0, iter }
}
/// Returns the next item after the current one. It doesn't interfere with `peek_next` output.
fn peek(&mut self) -> Option<&(TokenKind, &'a str)> {
fn peek(&mut self) -> Option<(TokenKind, &'a str)> {
if self.stored.is_empty()
&& let Some(next) = self.iter.next()
{
self.stored.push_back(next);
}
self.stored.front()
self.stored.front().copied()
}
/// Returns the next item after the last one peeked. It doesn't interfere with `peek` output.
fn peek_next(&mut self) -> Option<&(TokenKind, &'a str)> {
fn peek_next(&mut self) -> Option<(TokenKind, &'a str)> {
self.peek_pos += 1;
if self.peek_pos - 1 < self.stored.len() {
self.stored.get(self.peek_pos - 1)
@ -834,6 +825,7 @@ impl<'a> PeekIter<'a> {
} else {
None
}
.copied()
}
fn stop_peeking(&mut self) {
@ -878,6 +870,54 @@ fn new_span(lo: u32, text: &str, file_span: Span) -> Span {
file_span.with_lo(file_lo + BytePos(lo)).with_hi(file_lo + BytePos(hi))
}
fn classify<'src>(
src: &'src str,
file_span: Span,
decoration_info: Option<&DecorationInfo>,
sink: &mut dyn FnMut(Span, Highlight<'src>),
) {
let offset = rustc_lexer::strip_shebang(src);
if let Some(offset) = offset {
sink(DUMMY_SP, Highlight::Token { text: &src[..offset], class: Some(Class::Comment) });
}
let mut classifier =
Classifier::new(src, offset.unwrap_or_default(), file_span, decoration_info);
loop {
if let Some(decs) = classifier.decorations.as_mut() {
let byte_pos = classifier.byte_pos;
let n_starts = decs.starts.iter().filter(|(i, _)| byte_pos >= *i).count();
for (_, kind) in decs.starts.drain(0..n_starts) {
sink(DUMMY_SP, Highlight::EnterSpan { class: Class::Decoration(kind) });
}
let n_ends = decs.ends.iter().filter(|i| byte_pos >= **i).count();
for _ in decs.ends.drain(0..n_ends) {
sink(DUMMY_SP, Highlight::ExitSpan);
}
}
if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() {
let tokens = classifier.get_full_ident_path();
for &(token, start, end) in &tokens {
let text = &classifier.src[start..end];
classifier.advance(token, text, sink, start as u32);
classifier.byte_pos += text.len() as u32;
}
if !tokens.is_empty() {
continue;
}
}
if let Some((token, text, before)) = classifier.next() {
classifier.advance(token, text, sink, before);
} else {
break;
}
}
}
/// Processes program tokens, classifying strings of text by highlighting
/// category (`Class`).
struct Classifier<'src> {
@ -892,21 +932,23 @@ struct Classifier<'src> {
}
impl<'src> Classifier<'src> {
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
/// file span which will be used later on by the `span_correspondence_map`.
fn new(src: &'src str, file_span: Span, decoration_info: Option<&DecorationInfo>) -> Self {
let tokens =
PeekIter::new(TokenIter { src, cursor: Cursor::new(src, FrontmatterAllowed::Yes) });
let decorations = decoration_info.map(Decorations::new);
/// Takes as argument the source code to HTML-ify and the source code file span
/// which will be used later on by the `span_correspondence_map`.
fn new(
src: &'src str,
byte_pos: usize,
file_span: Span,
decoration_info: Option<&DecorationInfo>,
) -> Self {
Classifier {
tokens,
tokens: PeekIter::new(TokenIter::new(&src[byte_pos..])),
in_attribute: false,
in_macro: false,
in_macro_nonterminal: false,
byte_pos: 0,
byte_pos: byte_pos as u32,
file_span,
src,
decorations,
decorations: decoration_info.map(Decorations::new),
}
}
@ -934,15 +976,10 @@ impl<'src> Classifier<'src> {
}
}
if let Some((None, text)) = self.tokens.peek().map(|(token, text)| {
if *token == TokenKind::Ident {
let class = get_real_ident_class(text, true);
(class, text)
} else {
// Doesn't matter which Class we put in here...
(Some(Class::Comment), text)
}
}) {
if let Some((TokenKind::Ident, text)) = self.tokens.peek()
&& let symbol = Symbol::intern(text)
&& (symbol.is_path_segment_keyword() || !is_keyword(symbol))
{
// We only "add" the colon if there is an ident behind.
pos += text.len() + nb;
has_ident = true;
@ -973,50 +1010,6 @@ impl<'src> Classifier<'src> {
}
}
/// Exhausts the `Classifier` writing the output into `sink`.
///
/// The general structure for this method is to iterate over each token,
/// possibly giving it an HTML span with a class specifying what flavor of
/// token is used.
fn highlight(mut self, sink: &mut dyn FnMut(Span, Highlight<'src>)) {
loop {
if let Some(decs) = self.decorations.as_mut() {
let byte_pos = self.byte_pos;
let n_starts = decs.starts.iter().filter(|(i, _)| byte_pos >= *i).count();
for (_, kind) in decs.starts.drain(0..n_starts) {
sink(DUMMY_SP, Highlight::EnterSpan { class: Class::Decoration(kind) });
}
let n_ends = decs.ends.iter().filter(|i| byte_pos >= **i).count();
for _ in decs.ends.drain(0..n_ends) {
sink(DUMMY_SP, Highlight::ExitSpan);
}
}
if self
.tokens
.peek()
.map(|t| matches!(t.0, TokenKind::Colon | TokenKind::Ident))
.unwrap_or(false)
{
let tokens = self.get_full_ident_path();
for (token, start, end) in &tokens {
let text = &self.src[*start..*end];
self.advance(*token, text, sink, *start as u32);
self.byte_pos += text.len() as u32;
}
if !tokens.is_empty() {
continue;
}
}
if let Some((token, text, before)) = self.next() {
self.advance(token, text, sink, before);
} else {
break;
}
}
}
/// Single step of highlighting. This will classify `token`, but maybe also a couple of
/// following ones as well.
///
@ -1054,6 +1047,7 @@ impl<'src> Classifier<'src> {
Class::Comment
}
}
TokenKind::Frontmatter { .. } => Class::Comment,
// Consider this as part of a macro invocation if there was a
// leading identifier.
TokenKind::Bang if self.in_macro => {
@ -1152,7 +1146,6 @@ impl<'src> Classifier<'src> {
| TokenKind::At
| TokenKind::Tilde
| TokenKind::Colon
| TokenKind::Frontmatter { .. }
| TokenKind::Unknown => return no_highlight(sink),
TokenKind::Question => Class::QuestionMark,
@ -1224,7 +1217,7 @@ impl<'src> Classifier<'src> {
},
TokenKind::GuardedStrPrefix => return no_highlight(sink),
TokenKind::Ident | TokenKind::RawIdent
if self.peek_non_whitespace() == Some(TokenKind::Bang) =>
if let Some((TokenKind::Bang, _)) = self.peek_non_trivia() =>
{
self.in_macro = true;
let span = new_span(before, text, file_span);
@ -1232,26 +1225,7 @@ impl<'src> Classifier<'src> {
sink(span, Highlight::Token { text, class: None });
return;
}
TokenKind::Ident => {
match get_real_ident_class(text, false) {
None => match text {
"Option" | "Result" => Class::PreludeTy(new_span(before, text, file_span)),
"Some" | "None" | "Ok" | "Err" => {
Class::PreludeVal(new_span(before, text, file_span))
}
// "union" is a weak keyword and is only considered as a keyword when declaring
// a union type.
"union" if self.check_if_is_union_keyword() => Class::KeyWord,
_ if self.in_macro_nonterminal => {
self.in_macro_nonterminal = false;
Class::MacroNonTerminal
}
"self" | "Self" => Class::Self_(new_span(before, text, file_span)),
_ => Class::Ident(new_span(before, text, file_span)),
},
Some(c) => c,
}
}
TokenKind::Ident => self.classify_ident(before, text),
TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => {
Class::Ident(new_span(before, text, file_span))
}
@ -1272,25 +1246,66 @@ impl<'src> Classifier<'src> {
}
}
fn peek(&mut self) -> Option<TokenKind> {
self.tokens.peek().map(|(token_kind, _text)| *token_kind)
fn classify_ident(&mut self, before: u32, text: &'src str) -> Class {
// Macro non-terminals (meta vars) take precedence.
if self.in_macro_nonterminal {
self.in_macro_nonterminal = false;
return Class::MacroNonTerminal;
}
let file_span = self.file_span;
let span = || new_span(before, text, file_span);
match text {
"ref" | "mut" => Class::RefKeyWord,
"false" | "true" => Class::Bool,
"self" | "Self" => Class::Self_(span()),
"Option" | "Result" => Class::PreludeTy(span()),
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal(span()),
_ if self.is_weak_keyword(text) || is_keyword(Symbol::intern(text)) => Class::KeyWord,
_ => Class::Ident(span()),
}
}
fn peek_non_whitespace(&mut self) -> Option<TokenKind> {
while let Some((token_kind, _)) = self.tokens.peek_next() {
if *token_kind != TokenKind::Whitespace {
let token_kind = *token_kind;
self.tokens.stop_peeking();
return Some(token_kind);
fn is_weak_keyword(&mut self, text: &str) -> bool {
// NOTE: `yeet` (`do yeet $expr`), `catch` (`do catch $block`), `default` (specialization),
// `contract_{ensures,requires}`, `builtin` (builtin_syntax) & `reuse` (fn_delegation) are
// too difficult or annoying to properly detect under this simple scheme.
let matches = match text {
"auto" => |text| text == "trait", // `auto trait Trait {}` (`auto_traits`)
"pin" => |text| text == "const" || text == "mut", // `&pin mut Type` (`pin_ergonomics`)
"raw" => |text| text == "const" || text == "mut", // `&raw const local`
"safe" => |text| text == "fn" || text == "extern", // `unsafe extern { safe fn f(); }`
"union" => |_| true, // `union Untagged { field: () }`
_ => return false,
};
matches!(self.peek_non_trivia(), Some((TokenKind::Ident, text)) if matches(text))
}
fn peek(&mut self) -> Option<TokenKind> {
self.tokens.peek().map(|(kind, _)| kind)
}
fn peek_non_trivia(&mut self) -> Option<(TokenKind, &str)> {
while let Some(token @ (kind, _)) = self.tokens.peek_next() {
if let TokenKind::Whitespace
| TokenKind::LineComment { doc_style: None }
| TokenKind::BlockComment { doc_style: None, .. } = kind
{
continue;
}
self.tokens.stop_peeking();
return Some(token);
}
self.tokens.stop_peeking();
None
}
}
fn check_if_is_union_keyword(&mut self) -> bool {
self.peek_non_whitespace().is_some_and(|kind| kind == TokenKind::Ident)
}
fn is_keyword(symbol: Symbol) -> bool {
// FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument.
symbol.is_reserved(|| Edition::Edition2024)
}
fn generate_link_to_def(

View file

@ -74,8 +74,9 @@ use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::html::escape::Escape;
use crate::html::format::{
Ending, HrefError, PrintWithSpace, href, print_abi_with_space, print_constness_with_space,
print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
Ending, HrefError, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space,
print_constness_with_space, print_default_space, print_generic_bounds, print_generics,
print_impl, print_path, print_type, print_where_clause, visibility_print_with_space,
};
use crate::html::markdown::{
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
@ -1044,8 +1045,8 @@ fn assoc_const(
vis = visibility_print_with_space(it, cx),
href = assoc_href_attr(it, link, cx).maybe_display(),
name = it.name.as_ref().unwrap(),
generics = generics.print(cx),
ty = ty.print(cx),
generics = print_generics(generics, cx),
ty = print_type(ty, cx),
)?;
if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value {
// FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
@ -1083,14 +1084,14 @@ fn assoc_type(
vis = visibility_print_with_space(it, cx),
href = assoc_href_attr(it, link, cx).maybe_display(),
name = it.name.as_ref().unwrap(),
generics = generics.print(cx),
generics = print_generics(generics, cx),
)?;
if !bounds.is_empty() {
write!(w, ": {}", print_generic_bounds(bounds, cx))?;
}
// Render the default before the where-clause which aligns with the new recommended style. See #89122.
if let Some(default) = default {
write!(w, " = {}", default.print(cx))?;
write!(w, " = {}", print_type(default, cx))?;
}
write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline).maybe_display())
})
@ -1128,7 +1129,7 @@ fn assoc_method(
let href = assoc_href_attr(meth, link, cx).maybe_display();
// NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
let generics_len = format!("{:#}", g.print(cx)).len();
let generics_len = format!("{:#}", print_generics(g, cx)).len();
let mut header_len = "fn ".len()
+ vis.len()
+ defaultness.len()
@ -1155,8 +1156,8 @@ fn assoc_method(
"{indent}{vis}{defaultness}{constness}{asyncness}{safety}{abi}fn \
<a{href} class=\"fn\">{name}</a>{generics}{decl}{notable_traits}{where_clause}",
indent = indent_str,
generics = g.print(cx),
decl = d.full_print(header_len, indent, cx),
generics = print_generics(g, cx),
decl = full_print_fn_decl(d, header_len, indent, cx),
where_clause = print_where_clause(g, cx, indent, end_newline).maybe_display(),
)
})
@ -1441,8 +1442,10 @@ fn render_assoc_items_inner(
Cow::Borrowed("implementations-list"),
),
AssocItemRender::DerefFor { trait_, type_, .. } => {
let id =
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
let id = cx.derive_id(small_url_encode(format!(
"deref-methods-{:#}",
print_type(type_, cx)
)));
// the `impls.get` above only looks at the outermost type,
// and the Deref impl may only be implemented for certain
// values of generic parameters.
@ -1466,8 +1469,8 @@ fn render_assoc_items_inner(
fmt::from_fn(|f| write!(
f,
"<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
trait_ = trait_.print(cx),
type_ = type_.print(cx),
trait_ = print_path(trait_, cx),
type_ = print_type(type_, cx),
)),
&id,
)
@ -1645,7 +1648,7 @@ fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<impl fmt:
write!(
f,
" <a href=\"#\" class=\"tooltip\" data-notable-ty=\"{ty}\">ⓘ</a>",
ty = Escape(&format!("{:#}", ty.print(cx))),
ty = Escape(&format!("{:#}", print_type(ty, cx))),
)
})
})
@ -1683,7 +1686,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
f,
"<h3>Notable traits for <code>{}</code></h3>\
<pre><code>",
impl_.for_.print(cx)
print_type(&impl_.for_, cx),
)?;
true
} else {
@ -1691,7 +1694,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
};
for (impl_, trait_did) in notable_impls {
write!(f, "<div class=\"where\">{}</div>", impl_.print(false, cx))?;
write!(f, "<div class=\"where\">{}</div>", print_impl(impl_, false, cx))?;
for it in &impl_.items {
let clean::AssocTypeItem(tydef, ..) = &it.kind else {
continue;
@ -1724,7 +1727,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
})
.to_string();
(format!("{:#}", ty.print(cx)), out)
(format!("{:#}", print_type(ty, cx)), out)
}
fn notable_traits_json<'a>(tys: impl Iterator<Item = &'a clean::Type>, cx: &Context<'_>) -> String {
@ -2284,7 +2287,7 @@ fn render_impl_summary(
)?;
if let Some(use_absolute) = use_absolute {
write!(w, "{}", inner_impl.print(use_absolute, cx))?;
write!(w, "{}", print_impl(inner_impl, use_absolute, cx))?;
if show_def_docs {
for it in &inner_impl.items {
if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind {
@ -2305,7 +2308,7 @@ fn render_impl_summary(
}
}
} else {
write!(w, "{}", inner_impl.print(false, cx))?;
write!(w, "{}", print_impl(inner_impl, false, cx))?;
}
w.write_str("</h3>")?;
@ -2423,7 +2426,10 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String
clean::ItemKind::ImplItem(ref i) if i.trait_.is_some() => {
// Alternative format produces no URLs,
// so this parameter does nothing.
Some((format!("{:#}", i.for_.print(cx)), get_id_for_impl(cx.tcx(), item.item_id)))
Some((
format!("{:#}", print_type(&i.for_, cx)),
get_id_for_impl(cx.tcx(), item.item_id),
))
}
_ => None,
}

View file

@ -31,7 +31,8 @@ use crate::formats::Impl;
use crate::formats::item_type::ItemType;
use crate::html::escape::{Escape, EscapeBodyTextWithWbr};
use crate::html::format::{
Ending, PrintWithSpace, print_abi_with_space, print_constness_with_space, print_where_clause,
Ending, PrintWithSpace, full_print_fn_decl, print_abi_with_space, print_constness_with_space,
print_generic_bound, print_generics, print_impl, print_import, print_type, print_where_clause,
visibility_print_with_space,
};
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
@ -462,7 +463,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
"{vis}{imp}</code>{stab_tags}\
</dt>",
vis = visibility_print_with_space(myitem, cx),
imp = import.print(cx)
imp = print_import(import, cx),
)?;
}
_ => {
@ -611,7 +612,7 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp
let visibility = visibility_print_with_space(it, cx).to_string();
let name = it.name.unwrap();
let generics_len = format!("{:#}", f.generics.print(cx)).len();
let generics_len = format!("{:#}", print_generics(&f.generics, cx)).len();
let header_len = "fn ".len()
+ visibility.len()
+ constness.len()
@ -635,10 +636,10 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp
safety = safety,
abi = abi,
name = name,
generics = f.generics.print(cx),
generics = print_generics(&f.generics, cx),
where_clause =
print_where_clause(&f.generics, cx, 0, Ending::Newline).maybe_display(),
decl = f.decl.full_print(header_len, 0, cx),
decl = full_print_fn_decl(&f.decl, header_len, 0, cx),
)
})?;
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))
@ -673,7 +674,7 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
safety = t.safety(tcx).print_with_space(),
is_auto = if t.is_auto(tcx) { "auto " } else { "" },
name = it.name.unwrap(),
generics = t.generics.print(cx),
generics = print_generics(&t.generics, cx),
)?;
if !t.generics.where_predicates.is_empty() {
@ -1244,7 +1245,7 @@ fn item_trait_alias(
w,
"trait {name}{generics} = {bounds}{where_clause};",
name = it.name.unwrap(),
generics = t.generics.print(cx),
generics = print_generics(&t.generics, cx),
bounds = print_bounds(&t.bounds, true, cx),
where_clause =
print_where_clause(&t.generics, cx, 0, Ending::NoNewline).maybe_display(),
@ -1273,10 +1274,10 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) ->
"{vis}type {name}{generics}{where_clause} = {type_};",
vis = visibility_print_with_space(it, cx),
name = it.name.unwrap(),
generics = t.generics.print(cx),
generics = print_generics(&t.generics, cx),
where_clause =
print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(),
type_ = t.type_.print(cx),
type_ = print_type(&t.type_, cx),
)
})?;
@ -1477,7 +1478,7 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
}
fn print_ty(&self, ty: &'a clean::Type) -> impl Display {
ty.print(self.cx)
print_type(ty, self.cx)
}
// FIXME (GuillaumeGomez): When <https://github.com/askama-rs/askama/issues/452> is implemented,
@ -1523,7 +1524,7 @@ fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Displa
.map(|ty| {
fmt::from_fn(|f| match ty.kind {
clean::StrippedItem(box clean::StructFieldItem(_)) => f.write_str("_"),
clean::StructFieldItem(ref ty) => write!(f, "{}", ty.print(cx)),
clean::StructFieldItem(ref ty) => write!(f, "{}", print_type(ty, cx)),
_ => unreachable!(),
})
})
@ -1562,7 +1563,7 @@ impl<'clean> DisplayEnum<'clean> {
"{}enum {}{}{}",
visibility_print_with_space(it, cx),
it.name.unwrap(),
self.generics.print(cx),
print_generics(&self.generics, cx),
render_enum_fields(
cx,
Some(self.generics),
@ -1862,7 +1863,7 @@ fn item_variants(
{doc}\
</div>",
f = field.name.unwrap(),
t = ty.print(cx),
t = print_type(ty, cx),
doc = document(cx, field, Some(variant), HeadingOffset::H5),
)?;
}
@ -1956,8 +1957,8 @@ fn item_constant(
"{vis}const {name}{generics}: {typ}{where_clause}",
vis = visibility_print_with_space(it, cx),
name = it.name.unwrap(),
generics = generics.print(cx),
typ = ty.print(cx),
generics = print_generics(generics, cx),
typ = print_type(ty, cx),
where_clause =
print_where_clause(generics, cx, 0, Ending::NoNewline).maybe_display(),
)?;
@ -2102,7 +2103,7 @@ fn item_fields(
"{field_name}: {ty}</code>\
</span>\
{doc}",
ty = ty.print(cx),
ty = print_type(ty, cx),
doc = document(cx, field, Some(it), HeadingOffset::H3),
)?;
}
@ -2127,7 +2128,7 @@ fn item_static(
safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""),
mutability = s.mutability.print_with_space(),
name = it.name.unwrap(),
typ = s.type_.print(cx)
typ = print_type(&s.type_, cx)
)
})?;
@ -2286,7 +2287,7 @@ fn print_bounds(
}
}
bounds.iter().map(|p| p.print(cx)).joined(inter_str, f)
bounds.iter().map(|p| print_generic_bound(p, cx)).joined(inter_str, f)
}))
.maybe_display()
}
@ -2307,7 +2308,7 @@ struct ImplString(String);
impl ImplString {
fn new(i: &Impl, cx: &Context<'_>) -> ImplString {
ImplString(format!("{}", i.inner_impl().print(false, cx)))
ImplString(format!("{}", print_impl(i.inner_impl(), false, cx)))
}
}
@ -2376,7 +2377,7 @@ fn render_union(
write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
let where_displayed = if let Some(generics) = g {
write!(f, "{}", generics.print(cx))?;
write!(f, "{}", print_generics(generics, cx))?;
if let Some(where_clause) = print_where_clause(generics, cx, 0, Ending::Newline) {
write!(f, "{where_clause}")?;
true
@ -2408,7 +2409,7 @@ fn render_union(
" {}{}: {},",
visibility_print_with_space(field, cx),
field.name.unwrap(),
ty.print(cx)
print_type(ty, cx)
)?;
}
}
@ -2442,7 +2443,7 @@ fn render_struct(
it.name.unwrap()
)?;
if let Some(g) = g {
write!(w, "{}", g.print(cx))?;
write!(w, "{}", print_generics(g, cx))?;
}
write!(
w,
@ -2505,7 +2506,7 @@ fn render_struct_fields(
"{tab} {vis}{name}: {ty},",
vis = visibility_print_with_space(field, cx),
name = field.name.unwrap(),
ty = ty.print(cx)
ty = print_type(ty, cx)
)?;
}
}
@ -2548,7 +2549,7 @@ fn render_struct_fields(
w,
"{}{}",
visibility_print_with_space(field, cx),
ty.print(cx)
print_type(ty, cx),
)?;
}
_ => unreachable!(),

View file

@ -13,6 +13,7 @@ use super::{Context, ItemSection, item_ty_to_section};
use crate::clean;
use crate::formats::Impl;
use crate::formats::item_type::ItemType;
use crate::html::format::{print_path, print_type};
use crate::html::markdown::{IdMap, MarkdownWithToc};
use crate::html::render::print_item::compare_names;
@ -558,8 +559,8 @@ fn sidebar_deref_methods<'a>(
};
let title = format!(
"Methods from {:#}<Target={:#}>",
impl_.inner_impl().trait_.as_ref().unwrap().print(cx),
real_target.print(cx),
print_path(impl_.inner_impl().trait_.as_ref().unwrap(), cx),
print_type(real_target, cx),
);
// We want links' order to be reproducible so we don't use unstable sort.
ret.sort();
@ -690,7 +691,7 @@ fn sidebar_render_assoc_items(
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
ty::ImplPolarity::Negative => "!",
};
let generated = Link::new(encoded, format!("{prefix}{:#}", trait_.print(cx)));
let generated = Link::new(encoded, format!("{prefix}{:#}", print_path(trait_, cx)));
if links.insert(generated.clone()) { Some(generated) } else { None }
})
.collect::<Vec<Link<'static>>>();

View file

@ -44,6 +44,7 @@ use crate::docfs::PathError;
use crate::error::Error;
use crate::formats::Impl;
use crate::formats::item_type::ItemType;
use crate::html::format::{print_impl, print_path};
use crate::html::layout;
use crate::html::render::ordered_json::{EscapedJson, OrderedJson};
use crate::html::render::search_index::{SerializedSearchIndex, build_index};
@ -605,7 +606,7 @@ impl TypeAliasPart {
.inner_impl()
.trait_
.as_ref()
.map(|trait_| format!("{:#}", trait_.print(cx)));
.map(|trait_| format!("{:#}", print_path(trait_, cx)));
ret = Some(AliasSerializableImpl {
text,
trait_,
@ -704,7 +705,7 @@ impl TraitAliasPart {
None
} else {
Some(Implementor {
text: imp.inner_impl().print(false, cx).to_string(),
text: print_impl(imp.inner_impl(), false, cx).to_string(),
synthetic: imp.inner_impl().kind.is_auto(),
types: collect_paths_for_type(&imp.inner_impl().for_, cache),
})

View file

@ -0,0 +1,12 @@
#![feature(core_intrinsics, portable_simd)]
use std::intrinsics::simd::simd_funnel_shl;
use std::simd::*;
fn main() {
unsafe {
let x = i32x2::from_array([1, 1]);
let y = i32x2::from_array([100, 0]);
simd_funnel_shl(x, x, y); //~ERROR: overflowing shift by 100 in `simd_funnel_shl` in lane 0
}
}

View file

@ -0,0 +1,13 @@
error: Undefined Behavior: overflowing shift by 100 in `simd_funnel_shl` in lane 0
--> tests/fail/intrinsics/simd-funnel_shl-too-far.rs:LL:CC
|
LL | simd_funnel_shl(x, x, y);
| ^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error

View file

@ -0,0 +1,12 @@
#![feature(core_intrinsics, portable_simd)]
use std::intrinsics::simd::simd_funnel_shr;
use std::simd::*;
fn main() {
unsafe {
let x = i32x2::from_array([1, 1]);
let y = i32x2::from_array([20, 40]);
simd_funnel_shr(x, x, y); //~ERROR: overflowing shift by 40 in `simd_funnel_shr` in lane 1
}
}

View file

@ -0,0 +1,13 @@
error: Undefined Behavior: overflowing shift by 40 in `simd_funnel_shr` in lane 1
--> tests/fail/intrinsics/simd-funnel_shr-too-far.rs:LL:CC
|
LL | simd_funnel_shr(x, x, y);
| ^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error

View file

@ -62,7 +62,7 @@ impl<T: Copy, const N: usize> PackedSimd<T, N> {
#[rustc_nounwind]
pub unsafe fn simd_shuffle_const_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
pub fn simd_ops_f16() {
fn simd_ops_f16() {
use intrinsics::*;
// small hack to make type inference better
@ -273,7 +273,7 @@ fn simd_ops_f64() {
assert_eq!(f64x2::from_array([f64::NAN, 0.0]).reduce_min(), 0.0);
}
pub fn simd_ops_f128() {
fn simd_ops_f128() {
use intrinsics::*;
// small hack to make type inference better
@ -454,6 +454,18 @@ fn simd_ops_i32() {
0x3fffffffu32 as i32
])
);
// these values are taken from the doctests of `u32::funnel_shl` and `u32::funnel_shr`
let c = u32x4::splat(0x010000b3);
let d = u32x4::splat(0x2fe78e45);
unsafe {
assert_eq!(intrinsics::simd_funnel_shl(c, d, u32x4::splat(0)), c);
assert_eq!(intrinsics::simd_funnel_shl(c, d, u32x4::splat(8)), u32x4::splat(0x0000b32f));
assert_eq!(intrinsics::simd_funnel_shr(c, d, u32x4::splat(0)), d);
assert_eq!(intrinsics::simd_funnel_shr(c, d, u32x4::splat(8)), u32x4::splat(0xb32fe78e));
}
}
fn simd_mask() {

View file

@ -12,7 +12,7 @@
//@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector
//@[z13_no_vector] needs-llvm-components: systemz
#![feature(no_core, lang_items, repr_simd, s390x_target_feature)]
#![feature(no_core, lang_items, repr_simd)]
#![no_core]
#![crate_type = "lib"]
#![allow(non_camel_case_types)]

View file

@ -6,7 +6,7 @@
#![crate_type = "rlib"]
#![feature(no_core, asm_experimental_arch)]
#![feature(s390x_target_feature, simd_ffi, intrinsics, repr_simd)]
#![feature(simd_ffi, intrinsics, repr_simd)]
#![no_core]
extern crate minicore;

View file

@ -5,7 +5,6 @@
repr_simd,
arm_target_feature,
mips_target_feature,
s390x_target_feature,
riscv_target_feature
)]
#![no_std]

View file

@ -0,0 +1,15 @@
#!/path/to/my/interpreter
//@ compile-flags: -Zunstable-options --generate-link-to-definition
// Ensure that we can successfully generate links to definitions in the presence of shebang.
// Implementation-wise, shebang is not a token that's emitted by the lexer. Instead, we need
// to offset the actual lexing which is tricky due to all the byte index and span calculations
// in the Classifier.
fn scope() {
//@ has 'src/shebang/shebang.rs.html'
//@ has - '//a[@href="#15"]' 'function'
function();
}
fn function() {}

View file

@ -0,0 +1,10 @@
--- json
{"edition": "2024"}
---
#![feature(frontmatter)]
// Test that we highlight frontmatter as comments on source code pages.
//@ has 'src/frontmatter/frontmatter.rs.html'
//@ has - '//pre[@class="rust"]//span[@class="comment"]' \
// '--- json {"edition": "2024"} ---'

View file

@ -0,0 +1,6 @@
#!/path/to/somewhere 0 if false ""
// Test that we highlight shebang as comments on source code pages.
//@ has 'src/shebang/shebang.rs.html'
//@ has - '//pre[@class="rust"]//span[@class="comment"]' '#!/path/to/somewhere 0 if false ""'

View file

@ -10,11 +10,9 @@
//@[z13_soft_float] needs-llvm-components: systemz
//@ ignore-backends: gcc
//[z13_soft_float]~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly
//[z13_no_vector,z13_soft_float]~? WARN unstable feature specified for `-Ctarget-feature`
//[z13_soft_float]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature`
#![feature(no_core, repr_simd, s390x_target_feature)]
#![feature(no_core, repr_simd)]
#![no_core]
#![crate_type = "lib"]
#![allow(non_camel_case_types, improper_ctypes_definitions)]

View file

@ -1,5 +1,5 @@
error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:43:1
--> $DIR/simd-abi-checks-s390x.rs:41:1
|
LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:48:1
--> $DIR/simd-abi-checks-s390x.rs:46:1
|
LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:94:1
--> $DIR/simd-abi-checks-s390x.rs:92:1
|
LL | / extern "C" fn vector_transparent_wrapper_ret_small(
LL | | x: &TransparentWrapper<i8x8>,
@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper<i8x8> {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:101:1
--> $DIR/simd-abi-checks-s390x.rs:99:1
|
LL | / extern "C" fn vector_transparent_wrapper_ret(
LL | | x: &TransparentWrapper<i8x16>,
@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper<i8x16> {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:116:1
--> $DIR/simd-abi-checks-s390x.rs:114:1
|
LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:121:1
--> $DIR/simd-abi-checks-s390x.rs:119:1
|
LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `Wrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:132:1
--> $DIR/simd-abi-checks-s390x.rs:130:1
|
LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `Wrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:137:1
--> $DIR/simd-abi-checks-s390x.rs:135:1
|
LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:148:1
--> $DIR/simd-abi-checks-s390x.rs:146:1
|
LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:153:1
--> $DIR/simd-abi-checks-s390x.rs:151:1
|
LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here

View file

@ -1,9 +1,5 @@
warning: unstable feature specified for `-Ctarget-feature`: `vector`
|
= note: this feature is not stably supported; its behavior can change in the future
error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:43:1
--> $DIR/simd-abi-checks-s390x.rs:41:1
|
LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -11,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:48:1
--> $DIR/simd-abi-checks-s390x.rs:46:1
|
LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -19,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:94:1
--> $DIR/simd-abi-checks-s390x.rs:92:1
|
LL | / extern "C" fn vector_transparent_wrapper_ret_small(
LL | | x: &TransparentWrapper<i8x8>,
@ -29,7 +25,7 @@ LL | | ) -> TransparentWrapper<i8x8> {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:101:1
--> $DIR/simd-abi-checks-s390x.rs:99:1
|
LL | / extern "C" fn vector_transparent_wrapper_ret(
LL | | x: &TransparentWrapper<i8x16>,
@ -39,7 +35,7 @@ LL | | ) -> TransparentWrapper<i8x16> {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:116:1
--> $DIR/simd-abi-checks-s390x.rs:114:1
|
LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -47,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:121:1
--> $DIR/simd-abi-checks-s390x.rs:119:1
|
LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -55,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `Wrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:132:1
--> $DIR/simd-abi-checks-s390x.rs:130:1
|
LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -63,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `Wrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:137:1
--> $DIR/simd-abi-checks-s390x.rs:135:1
|
LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -71,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:148:1
--> $DIR/simd-abi-checks-s390x.rs:146:1
|
LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -79,12 +75,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:153:1
--> $DIR/simd-abi-checks-s390x.rs:151:1
|
LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: aborting due to 10 previous errors; 1 warning emitted
error: aborting due to 10 previous errors

View file

@ -1,7 +1,3 @@
warning: unstable feature specified for `-Ctarget-feature`: `vector`
|
= note: this feature is not stably supported; its behavior can change in the future
warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: currently unsupported ABI-configuration feature
|
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@ -13,7 +9,7 @@ warning: target feature `soft-float` must be disabled to ensure that the ABI of
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:43:1
--> $DIR/simd-abi-checks-s390x.rs:41:1
|
LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -21,7 +17,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:48:1
--> $DIR/simd-abi-checks-s390x.rs:46:1
|
LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -29,7 +25,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:94:1
--> $DIR/simd-abi-checks-s390x.rs:92:1
|
LL | / extern "C" fn vector_transparent_wrapper_ret_small(
LL | | x: &TransparentWrapper<i8x8>,
@ -39,7 +35,7 @@ LL | | ) -> TransparentWrapper<i8x8> {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:101:1
--> $DIR/simd-abi-checks-s390x.rs:99:1
|
LL | / extern "C" fn vector_transparent_wrapper_ret(
LL | | x: &TransparentWrapper<i8x16>,
@ -49,7 +45,7 @@ LL | | ) -> TransparentWrapper<i8x16> {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:116:1
--> $DIR/simd-abi-checks-s390x.rs:114:1
|
LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -57,7 +53,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:121:1
--> $DIR/simd-abi-checks-s390x.rs:119:1
|
LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -65,7 +61,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `Wrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:132:1
--> $DIR/simd-abi-checks-s390x.rs:130:1
|
LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -73,7 +69,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `Wrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:137:1
--> $DIR/simd-abi-checks-s390x.rs:135:1
|
LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -81,7 +77,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:148:1
--> $DIR/simd-abi-checks-s390x.rs:146:1
|
LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@ -89,12 +85,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
--> $DIR/simd-abi-checks-s390x.rs:153:1
--> $DIR/simd-abi-checks-s390x.rs:151:1
|
LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
error: aborting due to 10 previous errors; 3 warnings emitted
error: aborting due to 10 previous errors; 2 warnings emitted

View file

@ -8,8 +8,6 @@
//@[s390x_vector_stable] needs-llvm-components: systemz
//@ ignore-backends: gcc
//~? WARN unstable feature specified for `-Ctarget-feature`
#![crate_type = "rlib"]
#![feature(no_core, repr_simd)]
#![cfg_attr(not(s390x_vector_stable), feature(asm_experimental_reg))]

View file

@ -1,153 +1,149 @@
warning: unstable feature specified for `-Ctarget-feature`: `vector`
|
= note: this feature is not stably supported; its behavior can change in the future
error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:33:18
--> $DIR/bad-reg.rs:31:18
|
LL | asm!("", out("r11") _);
| ^^^^^^^^^^^^
error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:35:18
--> $DIR/bad-reg.rs:33:18
|
LL | asm!("", out("r15") _);
| ^^^^^^^^^^^^
error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:37:18
--> $DIR/bad-reg.rs:35:18
|
LL | asm!("", out("c0") _);
| ^^^^^^^^^^^
error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:39:18
--> $DIR/bad-reg.rs:37:18
|
LL | asm!("", out("c1") _);
| ^^^^^^^^^^^
error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:41:18
--> $DIR/bad-reg.rs:39:18
|
LL | asm!("", out("c2") _);
| ^^^^^^^^^^^
error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:43:18
--> $DIR/bad-reg.rs:41:18
|
LL | asm!("", out("c3") _);
| ^^^^^^^^^^^
error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:45:18
--> $DIR/bad-reg.rs:43:18
|
LL | asm!("", out("c4") _);
| ^^^^^^^^^^^
error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:47:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("c5") _);
| ^^^^^^^^^^^
error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:49:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("c6") _);
| ^^^^^^^^^^^
error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:51:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("c7") _);
| ^^^^^^^^^^^
error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:53:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("c8") _);
| ^^^^^^^^^^^
error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:55:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("c9") _);
| ^^^^^^^^^^^
error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:57:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("c10") _);
| ^^^^^^^^^^^^
error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:59:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("c11") _);
| ^^^^^^^^^^^^
error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:61:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("c12") _);
| ^^^^^^^^^^^^
error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:63:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("c13") _);
| ^^^^^^^^^^^^
error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:65:18
--> $DIR/bad-reg.rs:63:18
|
LL | asm!("", out("c14") _);
| ^^^^^^^^^^^^
error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:67:18
--> $DIR/bad-reg.rs:65:18
|
LL | asm!("", out("c15") _);
| ^^^^^^^^^^^^
error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:67:18
|
LL | asm!("", out("a0") _);
| ^^^^^^^^^^^
error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:71:18
--> $DIR/bad-reg.rs:69:18
|
LL | asm!("", out("a1") _);
| ^^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:122:18
--> $DIR/bad-reg.rs:120:18
|
LL | asm!("", in("a2") x);
| ^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:125:18
--> $DIR/bad-reg.rs:123:18
|
LL | asm!("", out("a2") x);
| ^^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:128:26
--> $DIR/bad-reg.rs:126:26
|
LL | asm!("/* {} */", in(areg) x);
| ^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:131:26
--> $DIR/bad-reg.rs:129:26
|
LL | asm!("/* {} */", out(areg) _);
| ^^^^^^^^^^^
error: register `f0` conflicts with register `v0`
--> $DIR/bad-reg.rs:136:31
--> $DIR/bad-reg.rs:134:31
|
LL | asm!("", out("v0") _, out("f0") _);
| ----------- ^^^^^^^^^^^ register `f0`
@ -155,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _);
| register `v0`
error: register `f1` conflicts with register `v1`
--> $DIR/bad-reg.rs:138:31
--> $DIR/bad-reg.rs:136:31
|
LL | asm!("", out("v1") _, out("f1") _);
| ----------- ^^^^^^^^^^^ register `f1`
@ -163,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _);
| register `v1`
error: register `f2` conflicts with register `v2`
--> $DIR/bad-reg.rs:140:31
--> $DIR/bad-reg.rs:138:31
|
LL | asm!("", out("v2") _, out("f2") _);
| ----------- ^^^^^^^^^^^ register `f2`
@ -171,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _);
| register `v2`
error: register `f3` conflicts with register `v3`
--> $DIR/bad-reg.rs:142:31
--> $DIR/bad-reg.rs:140:31
|
LL | asm!("", out("v3") _, out("f3") _);
| ----------- ^^^^^^^^^^^ register `f3`
@ -179,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _);
| register `v3`
error: register `f4` conflicts with register `v4`
--> $DIR/bad-reg.rs:144:31
--> $DIR/bad-reg.rs:142:31
|
LL | asm!("", out("v4") _, out("f4") _);
| ----------- ^^^^^^^^^^^ register `f4`
@ -187,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _);
| register `v4`
error: register `f5` conflicts with register `v5`
--> $DIR/bad-reg.rs:146:31
--> $DIR/bad-reg.rs:144:31
|
LL | asm!("", out("v5") _, out("f5") _);
| ----------- ^^^^^^^^^^^ register `f5`
@ -195,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _);
| register `v5`
error: register `f6` conflicts with register `v6`
--> $DIR/bad-reg.rs:148:31
--> $DIR/bad-reg.rs:146:31
|
LL | asm!("", out("v6") _, out("f6") _);
| ----------- ^^^^^^^^^^^ register `f6`
@ -203,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _);
| register `v6`
error: register `f7` conflicts with register `v7`
--> $DIR/bad-reg.rs:150:31
--> $DIR/bad-reg.rs:148:31
|
LL | asm!("", out("v7") _, out("f7") _);
| ----------- ^^^^^^^^^^^ register `f7`
@ -211,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _);
| register `v7`
error: register `f8` conflicts with register `v8`
--> $DIR/bad-reg.rs:152:31
--> $DIR/bad-reg.rs:150:31
|
LL | asm!("", out("v8") _, out("f8") _);
| ----------- ^^^^^^^^^^^ register `f8`
@ -219,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _);
| register `v8`
error: register `f9` conflicts with register `v9`
--> $DIR/bad-reg.rs:154:31
--> $DIR/bad-reg.rs:152:31
|
LL | asm!("", out("v9") _, out("f9") _);
| ----------- ^^^^^^^^^^^ register `f9`
@ -227,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _);
| register `v9`
error: register `f10` conflicts with register `v10`
--> $DIR/bad-reg.rs:156:32
--> $DIR/bad-reg.rs:154:32
|
LL | asm!("", out("v10") _, out("f10") _);
| ------------ ^^^^^^^^^^^^ register `f10`
@ -235,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _);
| register `v10`
error: register `f11` conflicts with register `v11`
--> $DIR/bad-reg.rs:158:32
--> $DIR/bad-reg.rs:156:32
|
LL | asm!("", out("v11") _, out("f11") _);
| ------------ ^^^^^^^^^^^^ register `f11`
@ -243,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _);
| register `v11`
error: register `f12` conflicts with register `v12`
--> $DIR/bad-reg.rs:160:32
--> $DIR/bad-reg.rs:158:32
|
LL | asm!("", out("v12") _, out("f12") _);
| ------------ ^^^^^^^^^^^^ register `f12`
@ -251,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _);
| register `v12`
error: register `f13` conflicts with register `v13`
--> $DIR/bad-reg.rs:162:32
--> $DIR/bad-reg.rs:160:32
|
LL | asm!("", out("v13") _, out("f13") _);
| ------------ ^^^^^^^^^^^^ register `f13`
@ -259,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _);
| register `v13`
error: register `f14` conflicts with register `v14`
--> $DIR/bad-reg.rs:164:32
--> $DIR/bad-reg.rs:162:32
|
LL | asm!("", out("v14") _, out("f14") _);
| ------------ ^^^^^^^^^^^^ register `f14`
@ -267,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _);
| register `v14`
error: register `f15` conflicts with register `v15`
--> $DIR/bad-reg.rs:166:32
--> $DIR/bad-reg.rs:164:32
|
LL | asm!("", out("v15") _, out("f15") _);
| ------------ ^^^^^^^^^^^^ register `f15`
@ -275,73 +271,73 @@ LL | asm!("", out("v15") _, out("f15") _);
| register `v15`
error: invalid register `f16`: unknown register
--> $DIR/bad-reg.rs:169:32
--> $DIR/bad-reg.rs:167:32
|
LL | asm!("", out("v16") _, out("f16") _);
| ^^^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:76:18
--> $DIR/bad-reg.rs:74:18
|
LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:80:18
--> $DIR/bad-reg.rs:78:18
|
LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg
| ^^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:84:18
--> $DIR/bad-reg.rs:82:18
|
LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:88:18
--> $DIR/bad-reg.rs:86:18
|
LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg
| ^^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:92:18
--> $DIR/bad-reg.rs:90:18
|
LL | asm!("", in("v0") b);
| ^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:97:18
--> $DIR/bad-reg.rs:95:18
|
LL | asm!("", out("v0") b);
| ^^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:102:26
--> $DIR/bad-reg.rs:100:26
|
LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:106:26
--> $DIR/bad-reg.rs:104:26
|
LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:110:26
--> $DIR/bad-reg.rs:108:26
|
LL | asm!("/* {} */", in(vreg) b);
| ^^^^^^^^^^
error: register class `vreg` requires the `vector` target feature
--> $DIR/bad-reg.rs:115:26
--> $DIR/bad-reg.rs:113:26
|
LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg
| ^^^^^^^^^^^
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:122:27
--> $DIR/bad-reg.rs:120:27
|
LL | asm!("", in("a2") x);
| ^
@ -349,7 +345,7 @@ LL | asm!("", in("a2") x);
= note: register class `areg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:125:28
--> $DIR/bad-reg.rs:123:28
|
LL | asm!("", out("a2") x);
| ^
@ -357,12 +353,12 @@ LL | asm!("", out("a2") x);
= note: register class `areg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:128:35
--> $DIR/bad-reg.rs:126:35
|
LL | asm!("/* {} */", in(areg) x);
| ^
|
= note: register class `areg` supports these types:
error: aborting due to 54 previous errors; 1 warning emitted
error: aborting due to 54 previous errors

View file

@ -1,153 +1,149 @@
warning: unstable feature specified for `-Ctarget-feature`: `vector`
|
= note: this feature is not stably supported; its behavior can change in the future
error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:33:18
--> $DIR/bad-reg.rs:31:18
|
LL | asm!("", out("r11") _);
| ^^^^^^^^^^^^
error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:35:18
--> $DIR/bad-reg.rs:33:18
|
LL | asm!("", out("r15") _);
| ^^^^^^^^^^^^
error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:37:18
--> $DIR/bad-reg.rs:35:18
|
LL | asm!("", out("c0") _);
| ^^^^^^^^^^^
error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:39:18
--> $DIR/bad-reg.rs:37:18
|
LL | asm!("", out("c1") _);
| ^^^^^^^^^^^
error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:41:18
--> $DIR/bad-reg.rs:39:18
|
LL | asm!("", out("c2") _);
| ^^^^^^^^^^^
error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:43:18
--> $DIR/bad-reg.rs:41:18
|
LL | asm!("", out("c3") _);
| ^^^^^^^^^^^
error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:45:18
--> $DIR/bad-reg.rs:43:18
|
LL | asm!("", out("c4") _);
| ^^^^^^^^^^^
error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:47:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("c5") _);
| ^^^^^^^^^^^
error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:49:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("c6") _);
| ^^^^^^^^^^^
error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:51:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("c7") _);
| ^^^^^^^^^^^
error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:53:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("c8") _);
| ^^^^^^^^^^^
error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:55:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("c9") _);
| ^^^^^^^^^^^
error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:57:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("c10") _);
| ^^^^^^^^^^^^
error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:59:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("c11") _);
| ^^^^^^^^^^^^
error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:61:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("c12") _);
| ^^^^^^^^^^^^
error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:63:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("c13") _);
| ^^^^^^^^^^^^
error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:65:18
--> $DIR/bad-reg.rs:63:18
|
LL | asm!("", out("c14") _);
| ^^^^^^^^^^^^
error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:67:18
--> $DIR/bad-reg.rs:65:18
|
LL | asm!("", out("c15") _);
| ^^^^^^^^^^^^
error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:67:18
|
LL | asm!("", out("a0") _);
| ^^^^^^^^^^^
error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:71:18
--> $DIR/bad-reg.rs:69:18
|
LL | asm!("", out("a1") _);
| ^^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:122:18
--> $DIR/bad-reg.rs:120:18
|
LL | asm!("", in("a2") x);
| ^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:125:18
--> $DIR/bad-reg.rs:123:18
|
LL | asm!("", out("a2") x);
| ^^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:128:26
--> $DIR/bad-reg.rs:126:26
|
LL | asm!("/* {} */", in(areg) x);
| ^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:131:26
--> $DIR/bad-reg.rs:129:26
|
LL | asm!("/* {} */", out(areg) _);
| ^^^^^^^^^^^
error: register `f0` conflicts with register `v0`
--> $DIR/bad-reg.rs:136:31
--> $DIR/bad-reg.rs:134:31
|
LL | asm!("", out("v0") _, out("f0") _);
| ----------- ^^^^^^^^^^^ register `f0`
@ -155,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _);
| register `v0`
error: register `f1` conflicts with register `v1`
--> $DIR/bad-reg.rs:138:31
--> $DIR/bad-reg.rs:136:31
|
LL | asm!("", out("v1") _, out("f1") _);
| ----------- ^^^^^^^^^^^ register `f1`
@ -163,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _);
| register `v1`
error: register `f2` conflicts with register `v2`
--> $DIR/bad-reg.rs:140:31
--> $DIR/bad-reg.rs:138:31
|
LL | asm!("", out("v2") _, out("f2") _);
| ----------- ^^^^^^^^^^^ register `f2`
@ -171,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _);
| register `v2`
error: register `f3` conflicts with register `v3`
--> $DIR/bad-reg.rs:142:31
--> $DIR/bad-reg.rs:140:31
|
LL | asm!("", out("v3") _, out("f3") _);
| ----------- ^^^^^^^^^^^ register `f3`
@ -179,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _);
| register `v3`
error: register `f4` conflicts with register `v4`
--> $DIR/bad-reg.rs:144:31
--> $DIR/bad-reg.rs:142:31
|
LL | asm!("", out("v4") _, out("f4") _);
| ----------- ^^^^^^^^^^^ register `f4`
@ -187,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _);
| register `v4`
error: register `f5` conflicts with register `v5`
--> $DIR/bad-reg.rs:146:31
--> $DIR/bad-reg.rs:144:31
|
LL | asm!("", out("v5") _, out("f5") _);
| ----------- ^^^^^^^^^^^ register `f5`
@ -195,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _);
| register `v5`
error: register `f6` conflicts with register `v6`
--> $DIR/bad-reg.rs:148:31
--> $DIR/bad-reg.rs:146:31
|
LL | asm!("", out("v6") _, out("f6") _);
| ----------- ^^^^^^^^^^^ register `f6`
@ -203,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _);
| register `v6`
error: register `f7` conflicts with register `v7`
--> $DIR/bad-reg.rs:150:31
--> $DIR/bad-reg.rs:148:31
|
LL | asm!("", out("v7") _, out("f7") _);
| ----------- ^^^^^^^^^^^ register `f7`
@ -211,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _);
| register `v7`
error: register `f8` conflicts with register `v8`
--> $DIR/bad-reg.rs:152:31
--> $DIR/bad-reg.rs:150:31
|
LL | asm!("", out("v8") _, out("f8") _);
| ----------- ^^^^^^^^^^^ register `f8`
@ -219,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _);
| register `v8`
error: register `f9` conflicts with register `v9`
--> $DIR/bad-reg.rs:154:31
--> $DIR/bad-reg.rs:152:31
|
LL | asm!("", out("v9") _, out("f9") _);
| ----------- ^^^^^^^^^^^ register `f9`
@ -227,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _);
| register `v9`
error: register `f10` conflicts with register `v10`
--> $DIR/bad-reg.rs:156:32
--> $DIR/bad-reg.rs:154:32
|
LL | asm!("", out("v10") _, out("f10") _);
| ------------ ^^^^^^^^^^^^ register `f10`
@ -235,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _);
| register `v10`
error: register `f11` conflicts with register `v11`
--> $DIR/bad-reg.rs:158:32
--> $DIR/bad-reg.rs:156:32
|
LL | asm!("", out("v11") _, out("f11") _);
| ------------ ^^^^^^^^^^^^ register `f11`
@ -243,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _);
| register `v11`
error: register `f12` conflicts with register `v12`
--> $DIR/bad-reg.rs:160:32
--> $DIR/bad-reg.rs:158:32
|
LL | asm!("", out("v12") _, out("f12") _);
| ------------ ^^^^^^^^^^^^ register `f12`
@ -251,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _);
| register `v12`
error: register `f13` conflicts with register `v13`
--> $DIR/bad-reg.rs:162:32
--> $DIR/bad-reg.rs:160:32
|
LL | asm!("", out("v13") _, out("f13") _);
| ------------ ^^^^^^^^^^^^ register `f13`
@ -259,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _);
| register `v13`
error: register `f14` conflicts with register `v14`
--> $DIR/bad-reg.rs:164:32
--> $DIR/bad-reg.rs:162:32
|
LL | asm!("", out("v14") _, out("f14") _);
| ------------ ^^^^^^^^^^^^ register `f14`
@ -267,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _);
| register `v14`
error: register `f15` conflicts with register `v15`
--> $DIR/bad-reg.rs:166:32
--> $DIR/bad-reg.rs:164:32
|
LL | asm!("", out("v15") _, out("f15") _);
| ------------ ^^^^^^^^^^^^ register `f15`
@ -275,13 +271,13 @@ LL | asm!("", out("v15") _, out("f15") _);
| register `v15`
error: invalid register `f16`: unknown register
--> $DIR/bad-reg.rs:169:32
--> $DIR/bad-reg.rs:167:32
|
LL | asm!("", out("v16") _, out("f16") _);
| ^^^^^^^^^^^^
error: type `u8` cannot be used with this register class
--> $DIR/bad-reg.rs:92:27
--> $DIR/bad-reg.rs:90:27
|
LL | asm!("", in("v0") b);
| ^
@ -289,7 +285,7 @@ LL | asm!("", in("v0") b);
= note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
error: type `u8` cannot be used with this register class
--> $DIR/bad-reg.rs:97:28
--> $DIR/bad-reg.rs:95:28
|
LL | asm!("", out("v0") b);
| ^
@ -297,7 +293,7 @@ LL | asm!("", out("v0") b);
= note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
error: type `u8` cannot be used with this register class
--> $DIR/bad-reg.rs:110:35
--> $DIR/bad-reg.rs:108:35
|
LL | asm!("/* {} */", in(vreg) b);
| ^
@ -305,7 +301,7 @@ LL | asm!("/* {} */", in(vreg) b);
= note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:122:27
--> $DIR/bad-reg.rs:120:27
|
LL | asm!("", in("a2") x);
| ^
@ -313,7 +309,7 @@ LL | asm!("", in("a2") x);
= note: register class `areg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:125:28
--> $DIR/bad-reg.rs:123:28
|
LL | asm!("", out("a2") x);
| ^
@ -321,12 +317,12 @@ LL | asm!("", out("a2") x);
= note: register class `areg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:128:35
--> $DIR/bad-reg.rs:126:35
|
LL | asm!("/* {} */", in(areg) x);
| ^
|
= note: register class `areg` supports these types:
error: aborting due to 47 previous errors; 1 warning emitted
error: aborting due to 47 previous errors

View file

@ -1,129 +1,125 @@
warning: unstable feature specified for `-Ctarget-feature`: `vector`
|
= note: this feature is not stably supported; its behavior can change in the future
error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:33:18
--> $DIR/bad-reg.rs:31:18
|
LL | asm!("", out("r11") _);
| ^^^^^^^^^^^^
error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:35:18
--> $DIR/bad-reg.rs:33:18
|
LL | asm!("", out("r15") _);
| ^^^^^^^^^^^^
error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:37:18
--> $DIR/bad-reg.rs:35:18
|
LL | asm!("", out("c0") _);
| ^^^^^^^^^^^
error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:39:18
--> $DIR/bad-reg.rs:37:18
|
LL | asm!("", out("c1") _);
| ^^^^^^^^^^^
error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:41:18
--> $DIR/bad-reg.rs:39:18
|
LL | asm!("", out("c2") _);
| ^^^^^^^^^^^
error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:43:18
--> $DIR/bad-reg.rs:41:18
|
LL | asm!("", out("c3") _);
| ^^^^^^^^^^^
error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:45:18
--> $DIR/bad-reg.rs:43:18
|
LL | asm!("", out("c4") _);
| ^^^^^^^^^^^
error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:47:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("c5") _);
| ^^^^^^^^^^^
error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:49:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("c6") _);
| ^^^^^^^^^^^
error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:51:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("c7") _);
| ^^^^^^^^^^^
error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:53:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("c8") _);
| ^^^^^^^^^^^
error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:55:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("c9") _);
| ^^^^^^^^^^^
error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:57:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("c10") _);
| ^^^^^^^^^^^^
error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:59:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("c11") _);
| ^^^^^^^^^^^^
error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:61:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("c12") _);
| ^^^^^^^^^^^^
error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:63:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("c13") _);
| ^^^^^^^^^^^^
error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:65:18
--> $DIR/bad-reg.rs:63:18
|
LL | asm!("", out("c14") _);
| ^^^^^^^^^^^^
error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:67:18
--> $DIR/bad-reg.rs:65:18
|
LL | asm!("", out("c15") _);
| ^^^^^^^^^^^^
error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:67:18
|
LL | asm!("", out("a0") _);
| ^^^^^^^^^^^
error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
--> $DIR/bad-reg.rs:71:18
--> $DIR/bad-reg.rs:69:18
|
LL | asm!("", out("a1") _);
| ^^^^^^^^^^^
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:76:18
--> $DIR/bad-reg.rs:74:18
|
LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
@ -133,7 +129,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:80:18
--> $DIR/bad-reg.rs:78:18
|
LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg
| ^^^^^^^^^^^
@ -143,7 +139,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:84:18
--> $DIR/bad-reg.rs:82:18
|
LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
@ -153,7 +149,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:88:18
--> $DIR/bad-reg.rs:86:18
|
LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg
| ^^^^^^^^^^^
@ -163,7 +159,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:92:18
--> $DIR/bad-reg.rs:90:18
|
LL | asm!("", in("v0") b);
| ^^^^^^^^^^
@ -173,7 +169,7 @@ LL | asm!("", in("v0") b);
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:97:18
--> $DIR/bad-reg.rs:95:18
|
LL | asm!("", out("v0") b);
| ^^^^^^^^^^^
@ -183,7 +179,7 @@ LL | asm!("", out("v0") b);
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:102:26
--> $DIR/bad-reg.rs:100:26
|
LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
@ -193,7 +189,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:106:26
--> $DIR/bad-reg.rs:104:26
|
LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
| ^^^^^^^^^^
@ -203,7 +199,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:110:26
--> $DIR/bad-reg.rs:108:26
|
LL | asm!("/* {} */", in(vreg) b);
| ^^^^^^^^^^
@ -213,7 +209,7 @@ LL | asm!("/* {} */", in(vreg) b);
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/bad-reg.rs:115:26
--> $DIR/bad-reg.rs:113:26
|
LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg
| ^^^^^^^^^^^
@ -223,31 +219,31 @@ LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimenta
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:122:18
--> $DIR/bad-reg.rs:120:18
|
LL | asm!("", in("a2") x);
| ^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:125:18
--> $DIR/bad-reg.rs:123:18
|
LL | asm!("", out("a2") x);
| ^^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:128:26
--> $DIR/bad-reg.rs:126:26
|
LL | asm!("/* {} */", in(areg) x);
| ^^^^^^^^^^
error: register class `areg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:131:26
--> $DIR/bad-reg.rs:129:26
|
LL | asm!("/* {} */", out(areg) _);
| ^^^^^^^^^^^
error: register `f0` conflicts with register `v0`
--> $DIR/bad-reg.rs:136:31
--> $DIR/bad-reg.rs:134:31
|
LL | asm!("", out("v0") _, out("f0") _);
| ----------- ^^^^^^^^^^^ register `f0`
@ -255,7 +251,7 @@ LL | asm!("", out("v0") _, out("f0") _);
| register `v0`
error: register `f1` conflicts with register `v1`
--> $DIR/bad-reg.rs:138:31
--> $DIR/bad-reg.rs:136:31
|
LL | asm!("", out("v1") _, out("f1") _);
| ----------- ^^^^^^^^^^^ register `f1`
@ -263,7 +259,7 @@ LL | asm!("", out("v1") _, out("f1") _);
| register `v1`
error: register `f2` conflicts with register `v2`
--> $DIR/bad-reg.rs:140:31
--> $DIR/bad-reg.rs:138:31
|
LL | asm!("", out("v2") _, out("f2") _);
| ----------- ^^^^^^^^^^^ register `f2`
@ -271,7 +267,7 @@ LL | asm!("", out("v2") _, out("f2") _);
| register `v2`
error: register `f3` conflicts with register `v3`
--> $DIR/bad-reg.rs:142:31
--> $DIR/bad-reg.rs:140:31
|
LL | asm!("", out("v3") _, out("f3") _);
| ----------- ^^^^^^^^^^^ register `f3`
@ -279,7 +275,7 @@ LL | asm!("", out("v3") _, out("f3") _);
| register `v3`
error: register `f4` conflicts with register `v4`
--> $DIR/bad-reg.rs:144:31
--> $DIR/bad-reg.rs:142:31
|
LL | asm!("", out("v4") _, out("f4") _);
| ----------- ^^^^^^^^^^^ register `f4`
@ -287,7 +283,7 @@ LL | asm!("", out("v4") _, out("f4") _);
| register `v4`
error: register `f5` conflicts with register `v5`
--> $DIR/bad-reg.rs:146:31
--> $DIR/bad-reg.rs:144:31
|
LL | asm!("", out("v5") _, out("f5") _);
| ----------- ^^^^^^^^^^^ register `f5`
@ -295,7 +291,7 @@ LL | asm!("", out("v5") _, out("f5") _);
| register `v5`
error: register `f6` conflicts with register `v6`
--> $DIR/bad-reg.rs:148:31
--> $DIR/bad-reg.rs:146:31
|
LL | asm!("", out("v6") _, out("f6") _);
| ----------- ^^^^^^^^^^^ register `f6`
@ -303,7 +299,7 @@ LL | asm!("", out("v6") _, out("f6") _);
| register `v6`
error: register `f7` conflicts with register `v7`
--> $DIR/bad-reg.rs:150:31
--> $DIR/bad-reg.rs:148:31
|
LL | asm!("", out("v7") _, out("f7") _);
| ----------- ^^^^^^^^^^^ register `f7`
@ -311,7 +307,7 @@ LL | asm!("", out("v7") _, out("f7") _);
| register `v7`
error: register `f8` conflicts with register `v8`
--> $DIR/bad-reg.rs:152:31
--> $DIR/bad-reg.rs:150:31
|
LL | asm!("", out("v8") _, out("f8") _);
| ----------- ^^^^^^^^^^^ register `f8`
@ -319,7 +315,7 @@ LL | asm!("", out("v8") _, out("f8") _);
| register `v8`
error: register `f9` conflicts with register `v9`
--> $DIR/bad-reg.rs:154:31
--> $DIR/bad-reg.rs:152:31
|
LL | asm!("", out("v9") _, out("f9") _);
| ----------- ^^^^^^^^^^^ register `f9`
@ -327,7 +323,7 @@ LL | asm!("", out("v9") _, out("f9") _);
| register `v9`
error: register `f10` conflicts with register `v10`
--> $DIR/bad-reg.rs:156:32
--> $DIR/bad-reg.rs:154:32
|
LL | asm!("", out("v10") _, out("f10") _);
| ------------ ^^^^^^^^^^^^ register `f10`
@ -335,7 +331,7 @@ LL | asm!("", out("v10") _, out("f10") _);
| register `v10`
error: register `f11` conflicts with register `v11`
--> $DIR/bad-reg.rs:158:32
--> $DIR/bad-reg.rs:156:32
|
LL | asm!("", out("v11") _, out("f11") _);
| ------------ ^^^^^^^^^^^^ register `f11`
@ -343,7 +339,7 @@ LL | asm!("", out("v11") _, out("f11") _);
| register `v11`
error: register `f12` conflicts with register `v12`
--> $DIR/bad-reg.rs:160:32
--> $DIR/bad-reg.rs:158:32
|
LL | asm!("", out("v12") _, out("f12") _);
| ------------ ^^^^^^^^^^^^ register `f12`
@ -351,7 +347,7 @@ LL | asm!("", out("v12") _, out("f12") _);
| register `v12`
error: register `f13` conflicts with register `v13`
--> $DIR/bad-reg.rs:162:32
--> $DIR/bad-reg.rs:160:32
|
LL | asm!("", out("v13") _, out("f13") _);
| ------------ ^^^^^^^^^^^^ register `f13`
@ -359,7 +355,7 @@ LL | asm!("", out("v13") _, out("f13") _);
| register `v13`
error: register `f14` conflicts with register `v14`
--> $DIR/bad-reg.rs:164:32
--> $DIR/bad-reg.rs:162:32
|
LL | asm!("", out("v14") _, out("f14") _);
| ------------ ^^^^^^^^^^^^ register `f14`
@ -367,7 +363,7 @@ LL | asm!("", out("v14") _, out("f14") _);
| register `v14`
error: register `f15` conflicts with register `v15`
--> $DIR/bad-reg.rs:166:32
--> $DIR/bad-reg.rs:164:32
|
LL | asm!("", out("v15") _, out("f15") _);
| ------------ ^^^^^^^^^^^^ register `f15`
@ -375,13 +371,13 @@ LL | asm!("", out("v15") _, out("f15") _);
| register `v15`
error: invalid register `f16`: unknown register
--> $DIR/bad-reg.rs:169:32
--> $DIR/bad-reg.rs:167:32
|
LL | asm!("", out("v16") _, out("f16") _);
| ^^^^^^^^^^^^
error[E0658]: type `i64x2` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:76:27
--> $DIR/bad-reg.rs:74:27
|
LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg
| ^
@ -391,7 +387,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `i64x2` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:80:28
--> $DIR/bad-reg.rs:78:28
|
LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg
| ^
@ -401,7 +397,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `i32` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:84:27
--> $DIR/bad-reg.rs:82:27
|
LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg
| ^
@ -411,7 +407,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `i32` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:88:28
--> $DIR/bad-reg.rs:86:28
|
LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg
| ^
@ -421,7 +417,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: type `u8` cannot be used with this register class
--> $DIR/bad-reg.rs:92:27
--> $DIR/bad-reg.rs:90:27
|
LL | asm!("", in("v0") b);
| ^
@ -429,7 +425,7 @@ LL | asm!("", in("v0") b);
= note: register class `vreg` supports these types:
error: type `u8` cannot be used with this register class
--> $DIR/bad-reg.rs:97:28
--> $DIR/bad-reg.rs:95:28
|
LL | asm!("", out("v0") b);
| ^
@ -437,7 +433,7 @@ LL | asm!("", out("v0") b);
= note: register class `vreg` supports these types:
error[E0658]: type `i64x2` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:102:35
--> $DIR/bad-reg.rs:100:35
|
LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
| ^
@ -447,7 +443,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `i32` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:106:35
--> $DIR/bad-reg.rs:104:35
|
LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
| ^
@ -457,7 +453,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: type `u8` cannot be used with this register class
--> $DIR/bad-reg.rs:110:35
--> $DIR/bad-reg.rs:108:35
|
LL | asm!("/* {} */", in(vreg) b);
| ^
@ -465,7 +461,7 @@ LL | asm!("/* {} */", in(vreg) b);
= note: register class `vreg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:122:27
--> $DIR/bad-reg.rs:120:27
|
LL | asm!("", in("a2") x);
| ^
@ -473,7 +469,7 @@ LL | asm!("", in("a2") x);
= note: register class `areg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:125:28
--> $DIR/bad-reg.rs:123:28
|
LL | asm!("", out("a2") x);
| ^
@ -481,13 +477,13 @@ LL | asm!("", out("a2") x);
= note: register class `areg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:128:35
--> $DIR/bad-reg.rs:126:35
|
LL | asm!("/* {} */", in(areg) x);
| ^
|
= note: register class `areg` supports these types:
error: aborting due to 63 previous errors; 1 warning emitted
error: aborting due to 63 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -11,6 +11,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
|
LL | fn ord<a>() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn ord<a>() -> _ {
LL + fn ord<a>() -> impl AsyncFn() {
|
error[E0392]: lifetime parameter `'g` is never used
--> $DIR/ice-async-closure-variance-issue-148488.rs:3:10

View file

@ -0,0 +1,64 @@
#![allow(dead_code)]
//@ run-rustfix
//@ edition: 2021
// The suggestion should be `impl AsyncFn()` instead of something like `{async closure@...}`
fn test1() -> impl AsyncFn() {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn()
async || {}
}
fn test2() -> impl AsyncFn(i32) -> i32 {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn(i32) -> i32
async |x: i32| x + 1
}
fn test3() -> impl AsyncFn(i32, i32) -> i32 {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn(i32, i32) -> i32
async |x: i32, y: i32| x + y
}
fn test4() -> impl AsyncFn() {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn()
async || -> () { () }
}
fn test5() -> impl AsyncFn() -> i32 {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn() -> i32
let z = 42;
async move || z
}
fn test6() -> impl AsyncFnMut() -> i32 {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFnMut() -> i32
let mut x = 0;
async move || {
x += 1;
x
}
}
fn test7() -> impl AsyncFnOnce() {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFnOnce()
let s = String::from("hello");
async move || {
drop(s);
}
}
fn main() {}

View file

@ -0,0 +1,64 @@
#![allow(dead_code)]
//@ run-rustfix
//@ edition: 2021
// The suggestion should be `impl AsyncFn()` instead of something like `{async closure@...}`
fn test1() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn()
async || {}
}
fn test2() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn(i32) -> i32
async |x: i32| x + 1
}
fn test3() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn(i32, i32) -> i32
async |x: i32, y: i32| x + y
}
fn test4() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn()
async || -> () { () }
}
fn test5() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFn() -> i32
let z = 42;
async move || z
}
fn test6() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFnMut() -> i32
let mut x = 0;
async move || {
x += 1;
x
}
}
fn test7() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl AsyncFnOnce()
let s = String::from("hello");
async move || {
drop(s);
}
}
fn main() {}

View file

@ -0,0 +1,87 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:7:15
|
LL | fn test1() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test1() -> _ {
LL + fn test1() -> impl AsyncFn() {
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:14:15
|
LL | fn test2() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test2() -> _ {
LL + fn test2() -> impl AsyncFn(i32) -> i32 {
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:21:15
|
LL | fn test3() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test3() -> _ {
LL + fn test3() -> impl AsyncFn(i32, i32) -> i32 {
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:28:15
|
LL | fn test4() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test4() -> _ {
LL + fn test4() -> impl AsyncFn() {
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:35:15
|
LL | fn test5() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test5() -> _ {
LL + fn test5() -> impl AsyncFn() -> i32 {
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:43:15
|
LL | fn test6() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test6() -> _ {
LL + fn test6() -> impl AsyncFnMut() -> i32 {
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-impl-async-fn-issue-148493.rs:54:15
|
LL | fn test7() -> _ {
| ^ not allowed in type signatures
|
help: replace with an appropriate return type
|
LL - fn test7() -> _ {
LL + fn test7() -> impl AsyncFnOnce() {
|
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0121`.