Auto merge of #149632 - matthiaskrgr:rollup-c5iqgtn, r=matthiaskrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#149521 (Improve `io::Error::downcast`)
 - rust-lang/rust#149544 (Only apply `no_mangle_const_items`'s suggestion to plain const items)
 - rust-lang/rust#149545 (fix the check for which expressions read never type)
 - rust-lang/rust#149570 (rename cortex-ar references to unified aarch32)
 - rust-lang/rust#149574 (Batched compiletest Config fixups)
 - rust-lang/rust#149579 (Motor OS: fix compile error)
 - rust-lang/rust#149595 (Tidying up `tests/ui/issues` tests [2/N])
 - rust-lang/rust#149597 (Revert "implement and test `Iterator::{exactly_one, collect_array}`")
 - rust-lang/rust#149608 (Allow PowerPC spe_acc as clobber-only register)
 - rust-lang/rust#149610 (Implement benchmarks for uN::{gather,scatter}_bits)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-12-04 14:38:19 +00:00
commit 29e035e172
64 changed files with 575 additions and 488 deletions

View file

@ -209,10 +209,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
}
("r", dummy_output_type(self.cx, reg.reg_class()))
} else {
// `clobber_abi` can add lots of clobbers that are not supported by the target,
// such as AVX-512 registers, so we just ignore unsupported registers
let is_target_supported =
reg.reg_class().supported_types(asm_arch, true).iter().any(
let is_target_supported = match reg.reg_class() {
// `clobber_abi` clobbers spe_acc on all PowerPC targets. This
// register is unique to the powerpc*spe target, and the target
// is not supported by gcc. Ignore it.
InlineAsmRegClass::PowerPC(
PowerPCInlineAsmRegClass::spe_acc,
) => false,
// `clobber_abi` can add lots of clobbers that are not supported by the target,
// such as AVX-512 registers, so we just ignore unsupported registers
x => x.supported_types(asm_arch, true).iter().any(
|&(_, feature)| {
if let Some(feature) = feature {
self.tcx
@ -222,7 +228,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
true // Register class is unconditionally supported
}
},
);
),
};
if is_target_supported && !clobbers.contains(&reg_name) {
clobbers.push(reg_name);
@ -710,7 +717,8 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
| PowerPCInlineAsmRegClass::xer
| PowerPCInlineAsmRegClass::spe_acc,
) => {
unreachable!("clobber-only")
}
@ -793,7 +801,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
| PowerPCInlineAsmRegClass::xer
| PowerPCInlineAsmRegClass::spe_acc,
) => {
unreachable!("clobber-only")
}

View file

@ -663,7 +663,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
| PowerPCInlineAsmRegClass::xer
| PowerPCInlineAsmRegClass::spe_acc,
) => {
unreachable!("clobber-only")
}
@ -843,7 +844,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
| PowerPCInlineAsmRegClass::xer
| PowerPCInlineAsmRegClass::spe_acc,
) => {
unreachable!("clobber-only")
}

View file

@ -86,8 +86,7 @@ impl MetadataLoader for DefaultMetadataLoader {
format!("failed to parse aix dylib '{}': {}", path.display(), e)
})?;
// FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
match Itertools::exactly_one(archive.members()) {
match archive.members().exactly_one() {
Ok(lib) => {
let lib = lib.map_err(|e| {
format!("failed to parse aix dylib '{}': {}", path.display(), e)

View file

@ -1793,6 +1793,55 @@ impl<'hir> Pat<'hir> {
});
is_never_pattern
}
/// Whether this pattern constitutes a read of value of the scrutinee that
/// it is matching against. This is used to determine whether we should
/// perform `NeverToAny` coercions.
///
/// See [`expr_guaranteed_to_constitute_read_for_never`][m] for the nuances of
/// what happens when this returns true.
///
/// [m]: ../../rustc_middle/ty/struct.TyCtxt.html#method.expr_guaranteed_to_constitute_read_for_never
pub fn is_guaranteed_to_constitute_read_for_never(&self) -> bool {
match self.kind {
// Does not constitute a read.
PatKind::Wild => false,
// The guard cannot affect if we make a read or not (it runs after the inner pattern
// has matched), therefore it's irrelevant.
PatKind::Guard(pat, _) => pat.is_guaranteed_to_constitute_read_for_never(),
// This is unnecessarily restrictive when the pattern that doesn't
// constitute a read is unreachable.
//
// For example `match *never_ptr { value => {}, _ => {} }` or
// `match *never_ptr { _ if false => {}, value => {} }`.
//
// It is however fine to be restrictive here; only returning `true`
// can lead to unsoundness.
PatKind::Or(subpats) => {
subpats.iter().all(|pat| pat.is_guaranteed_to_constitute_read_for_never())
}
// Does constitute a read, since it is equivalent to a discriminant read.
PatKind::Never => true,
// All of these constitute a read, or match on something that isn't `!`,
// which would require a `NeverToAny` coercion.
PatKind::Missing
| PatKind::Binding(_, _, _, _)
| PatKind::Struct(_, _, _)
| PatKind::TupleStruct(_, _, _)
| PatKind::Tuple(_, _)
| PatKind::Box(_)
| PatKind::Ref(_, _, _)
| PatKind::Deref(_)
| PatKind::Expr(_)
| PatKind::Range(_, _, _)
| PatKind::Slice(_, _, _)
| PatKind::Err(_) => true,
}
}
}
/// A single field in a struct pattern.

View file

@ -1078,7 +1078,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self,
cause,
allow_two_phase,
self.expr_guaranteed_to_constitute_read_for_never(expr),
self.tcx.expr_guaranteed_to_constitute_read_for_never(expr),
);
let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?;

View file

@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// While we don't allow *arbitrary* coercions here, we *do* allow
// coercions from ! to `expected`.
if self.try_structurally_resolve_type(expr.span, ty).is_never()
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
&& self.tcx.expr_guaranteed_to_constitute_read_for_never(expr)
{
if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
let reported = self.dcx().span_delayed_bug(
@ -320,7 +320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// diverging would be unsound since we may never actually read the `!`.
// e.g. `let _ = *never_ptr;` with `never_ptr: *const !`.
if self.try_structurally_resolve_type(expr.span, ty).is_never()
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
&& self.tcx.expr_guaranteed_to_constitute_read_for_never(expr)
{
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
}
@ -339,199 +339,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
}
/// Whether this expression constitutes a read of value of the type that
/// it evaluates to.
///
/// This is used to determine if we should consider the block to diverge
/// if the expression evaluates to `!`, and if we should insert a `NeverToAny`
/// coercion for values of type `!`.
///
/// This function generally returns `false` if the expression is a place
/// expression and the *parent* expression is the scrutinee of a match or
/// the pointee of an `&` addr-of expression, since both of those parent
/// expressions take a *place* and not a value.
pub(super) fn expr_guaranteed_to_constitute_read_for_never(
&self,
expr: &'tcx hir::Expr<'tcx>,
) -> bool {
// We only care about place exprs. Anything else returns an immediate
// which would constitute a read. We don't care about distinguishing
// "syntactic" place exprs since if the base of a field projection is
// not a place then it would've been UB to read from it anyways since
// that constitutes a read.
if !expr.is_syntactic_place_expr() {
return true;
}
let parent_node = self.tcx.parent_hir_node(expr.hir_id);
match parent_node {
hir::Node::Expr(parent_expr) => {
match parent_expr.kind {
// Addr-of, field projections, and LHS of assignment don't constitute reads.
// Assignment does call `drop_in_place`, though, but its safety
// requirements are not the same.
ExprKind::AddrOf(..) | hir::ExprKind::Field(..) => false,
// Place-preserving expressions only constitute reads if their
// parent expression constitutes a read.
ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
self.expr_guaranteed_to_constitute_read_for_never(expr)
}
ExprKind::Assign(lhs, _, _) => {
// Only the LHS does not constitute a read
expr.hir_id != lhs.hir_id
}
// See note on `PatKind::Or` below for why this is `all`.
ExprKind::Match(scrutinee, arms, _) => {
assert_eq!(scrutinee.hir_id, expr.hir_id);
arms.iter()
.all(|arm| self.pat_guaranteed_to_constitute_read_for_never(arm.pat))
}
ExprKind::Let(hir::LetExpr { init, pat, .. }) => {
assert_eq!(init.hir_id, expr.hir_id);
self.pat_guaranteed_to_constitute_read_for_never(*pat)
}
// Any expression child of these expressions constitute reads.
ExprKind::Array(_)
| ExprKind::Call(_, _)
| ExprKind::Use(_, _)
| ExprKind::MethodCall(_, _, _, _)
| ExprKind::Tup(_)
| ExprKind::Binary(_, _, _)
| ExprKind::Unary(_, _)
| ExprKind::Cast(_, _)
| ExprKind::DropTemps(_)
| ExprKind::If(_, _, _)
| ExprKind::Closure(_)
| ExprKind::Block(_, _)
| ExprKind::AssignOp(_, _, _)
| ExprKind::Index(_, _, _)
| ExprKind::Break(_, _)
| ExprKind::Ret(_)
| ExprKind::Become(_)
| ExprKind::InlineAsm(_)
| ExprKind::Struct(_, _, _)
| ExprKind::Repeat(_, _)
| ExprKind::Yield(_, _) => true,
// These expressions have no (direct) sub-exprs.
ExprKind::ConstBlock(_)
| ExprKind::Loop(_, _, _, _)
| ExprKind::Lit(_)
| ExprKind::Path(_)
| ExprKind::Continue(_)
| ExprKind::OffsetOf(_, _)
| ExprKind::Err(_) => unreachable!("no sub-expr expected for {:?}", expr.kind),
}
}
// If we have a subpattern that performs a read, we want to consider this
// to diverge for compatibility to support something like `let x: () = *never_ptr;`.
hir::Node::LetStmt(hir::LetStmt { init: Some(target), pat, .. }) => {
assert_eq!(target.hir_id, expr.hir_id);
self.pat_guaranteed_to_constitute_read_for_never(*pat)
}
// These nodes (if they have a sub-expr) do constitute a read.
hir::Node::Block(_)
| hir::Node::Arm(_)
| hir::Node::ExprField(_)
| hir::Node::AnonConst(_)
| hir::Node::ConstBlock(_)
| hir::Node::ConstArg(_)
| hir::Node::Stmt(_)
| hir::Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
..
})
| hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Const(..), ..
})
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
hir::Node::TyPat(_) | hir::Node::Pat(_) => {
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
true
}
// These nodes do not have direct sub-exprs.
hir::Node::Param(_)
| hir::Node::Item(_)
| hir::Node::ForeignItem(_)
| hir::Node::TraitItem(_)
| hir::Node::ImplItem(_)
| hir::Node::Variant(_)
| hir::Node::Field(_)
| hir::Node::PathSegment(_)
| hir::Node::Ty(_)
| hir::Node::AssocItemConstraint(_)
| hir::Node::TraitRef(_)
| hir::Node::PatField(_)
| hir::Node::PatExpr(_)
| hir::Node::LetStmt(_)
| hir::Node::Synthetic
| hir::Node::Err(_)
| hir::Node::Ctor(_)
| hir::Node::Lifetime(_)
| hir::Node::GenericParam(_)
| hir::Node::Crate(_)
| hir::Node::Infer(_)
| hir::Node::WherePredicate(_)
| hir::Node::PreciseCapturingNonLifetimeArg(_)
| hir::Node::OpaqueTy(_) => {
unreachable!("no sub-expr expected for {parent_node:?}")
}
}
}
/// Whether this pattern constitutes a read of value of the scrutinee that
/// it is matching against. This is used to determine whether we should
/// perform `NeverToAny` coercions.
///
/// See above for the nuances of what happens when this returns true.
pub(super) fn pat_guaranteed_to_constitute_read_for_never(&self, pat: &hir::Pat<'_>) -> bool {
match pat.kind {
// Does not constitute a read.
hir::PatKind::Wild => false,
// Might not constitute a read, since the condition might be false.
hir::PatKind::Guard(_, _) => true,
// This is unnecessarily restrictive when the pattern that doesn't
// constitute a read is unreachable.
//
// For example `match *never_ptr { value => {}, _ => {} }` or
// `match *never_ptr { _ if false => {}, value => {} }`.
//
// It is however fine to be restrictive here; only returning `true`
// can lead to unsoundness.
hir::PatKind::Or(subpats) => {
subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(pat))
}
// Does constitute a read, since it is equivalent to a discriminant read.
hir::PatKind::Never => true,
// All of these constitute a read, or match on something that isn't `!`,
// which would require a `NeverToAny` coercion.
hir::PatKind::Missing
| hir::PatKind::Binding(_, _, _, _)
| hir::PatKind::Struct(_, _, _)
| hir::PatKind::TupleStruct(_, _, _)
| hir::PatKind::Tuple(_, _)
| hir::PatKind::Box(_)
| hir::PatKind::Ref(_, _, _)
| hir::PatKind::Deref(_)
| hir::PatKind::Expr(_)
| hir::PatKind::Range(_, _, _)
| hir::PatKind::Slice(_, _, _)
| hir::PatKind::Err(_) => true,
}
}
#[instrument(skip(self, expr), level = "debug")]
fn check_expr_kind(
&self,

View file

@ -41,7 +41,7 @@ pub use rustc_session::lint::builtin::*;
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::source_map::Spanned;
use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym};
use rustc_target::asm::InlineAsmArch;
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
@ -997,18 +997,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id);
}
}
hir::ItemKind::Const(..) => {
hir::ItemKind::Const(ident, generics, ..) => {
if find_attr!(attrs, AttributeKind::NoMangle(..)) {
// account for "pub const" (#45562)
let start = cx
.tcx
.sess
.source_map()
.span_to_snippet(it.span)
.map(|snippet| snippet.find("const").unwrap_or(0))
.unwrap_or(0) as u32;
// `const` is 5 chars
let suggestion = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
let suggestion =
if generics.params.is_empty() && generics.where_clause_span.is_empty() {
// account for "pub const" (#45562)
Some(it.span.until(ident.span))
} else {
None
};
// Const items do not refer to a particular location in memory, and therefore
// don't have anything to attach a symbol to

View file

@ -228,8 +228,8 @@ pub(crate) struct BuiltinNoMangleGeneric {
#[derive(LintDiagnostic)]
#[diag(lint_builtin_const_no_mangle)]
pub(crate) struct BuiltinConstNoMangle {
#[suggestion(code = "pub static", applicability = "machine-applicable")]
pub suggestion: Span,
#[suggestion(code = "pub static ", applicability = "machine-applicable")]
pub suggestion: Option<Span>,
}
#[derive(LintDiagnostic)]

View file

@ -217,6 +217,146 @@ impl<'tcx> TyCtxt<'tcx> {
}
None
}
/// Whether this expression constitutes a read of value of the type that
/// it evaluates to.
///
/// This is used to determine if we should consider the block to diverge
/// if the expression evaluates to `!`, and if we should insert a `NeverToAny`
/// coercion for values of type `!`.
///
/// This function generally returns `false` if the expression is a place
/// expression and the *parent* expression is the scrutinee of a match or
/// the pointee of an `&` addr-of expression, since both of those parent
/// expressions take a *place* and not a value.
pub fn expr_guaranteed_to_constitute_read_for_never(self, expr: &Expr<'_>) -> bool {
// We only care about place exprs. Anything else returns an immediate
// which would constitute a read. We don't care about distinguishing
// "syntactic" place exprs since if the base of a field projection is
// not a place then it would've been UB to read from it anyways since
// that constitutes a read.
if !expr.is_syntactic_place_expr() {
return true;
}
let parent_node = self.parent_hir_node(expr.hir_id);
match parent_node {
Node::Expr(parent_expr) => {
match parent_expr.kind {
// Addr-of, field projections, and LHS of assignment don't constitute reads.
// Assignment does call `drop_in_place`, though, but its safety
// requirements are not the same.
ExprKind::AddrOf(..) | ExprKind::Field(..) => false,
// Place-preserving expressions only constitute reads if their
// parent expression constitutes a read.
ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
self.expr_guaranteed_to_constitute_read_for_never(parent_expr)
}
ExprKind::Assign(lhs, _, _) => {
// Only the LHS does not constitute a read
expr.hir_id != lhs.hir_id
}
// See note on `PatKind::Or` in `Pat::is_guaranteed_to_constitute_read_for_never`
// for why this is `all`.
ExprKind::Match(scrutinee, arms, _) => {
assert_eq!(scrutinee.hir_id, expr.hir_id);
arms.iter().all(|arm| arm.pat.is_guaranteed_to_constitute_read_for_never())
}
ExprKind::Let(LetExpr { init, pat, .. }) => {
assert_eq!(init.hir_id, expr.hir_id);
pat.is_guaranteed_to_constitute_read_for_never()
}
// Any expression child of these expressions constitute reads.
ExprKind::Array(_)
| ExprKind::Call(_, _)
| ExprKind::Use(_, _)
| ExprKind::MethodCall(_, _, _, _)
| ExprKind::Tup(_)
| ExprKind::Binary(_, _, _)
| ExprKind::Unary(_, _)
| ExprKind::Cast(_, _)
| ExprKind::DropTemps(_)
| ExprKind::If(_, _, _)
| ExprKind::Closure(_)
| ExprKind::Block(_, _)
| ExprKind::AssignOp(_, _, _)
| ExprKind::Index(_, _, _)
| ExprKind::Break(_, _)
| ExprKind::Ret(_)
| ExprKind::Become(_)
| ExprKind::InlineAsm(_)
| ExprKind::Struct(_, _, _)
| ExprKind::Repeat(_, _)
| ExprKind::Yield(_, _) => true,
// These expressions have no (direct) sub-exprs.
ExprKind::ConstBlock(_)
| ExprKind::Loop(_, _, _, _)
| ExprKind::Lit(_)
| ExprKind::Path(_)
| ExprKind::Continue(_)
| ExprKind::OffsetOf(_, _)
| ExprKind::Err(_) => unreachable!("no sub-expr expected for {:?}", expr.kind),
}
}
// If we have a subpattern that performs a read, we want to consider this
// to diverge for compatibility to support something like `let x: () = *never_ptr;`.
Node::LetStmt(LetStmt { init: Some(target), pat, .. }) => {
assert_eq!(target.hir_id, expr.hir_id);
pat.is_guaranteed_to_constitute_read_for_never()
}
// These nodes (if they have a sub-expr) do constitute a read.
Node::Block(_)
| Node::Arm(_)
| Node::ExprField(_)
| Node::AnonConst(_)
| Node::ConstBlock(_)
| Node::ConstArg(_)
| Node::Stmt(_)
| Node::Item(Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. })
| Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
| Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => true,
Node::TyPat(_) | Node::Pat(_) => {
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
true
}
// These nodes do not have direct sub-exprs.
Node::Param(_)
| Node::Item(_)
| Node::ForeignItem(_)
| Node::TraitItem(_)
| Node::ImplItem(_)
| Node::Variant(_)
| Node::Field(_)
| Node::PathSegment(_)
| Node::Ty(_)
| Node::AssocItemConstraint(_)
| Node::TraitRef(_)
| Node::PatField(_)
| Node::PatExpr(_)
| Node::LetStmt(_)
| Node::Synthetic
| Node::Err(_)
| Node::Ctor(_)
| Node::Lifetime(_)
| Node::GenericParam(_)
| Node::Crate(_)
| Node::Infer(_)
| Node::WherePredicate(_)
| Node::PreciseCapturingNonLifetimeArg(_)
| Node::OpaqueTy(_) => {
unreachable!("no sub-expr expected for {parent_node:?}")
}
}
}
}
/// Hashes computed by [`TyCtxt::hash_owner_nodes`] if necessary.

View file

@ -2143,6 +2143,7 @@ symbols! {
sparc,
sparc64,
sparc_target_feature,
spe_acc,
specialization,
speed,
spirv,

View file

@ -1271,6 +1271,9 @@ impl InlineAsmClobberAbi {
ctr,
lr,
xer,
// These are only supported on PowerPC SPE targets.
spe_acc,
}
},
InlineAsmClobberAbi::S390x => clobbered_regs! {

View file

@ -17,6 +17,7 @@ def_reg_class! {
ctr,
lr,
xer,
spe_acc,
}
}
@ -63,7 +64,7 @@ impl PowerPCInlineAsmRegClass {
Self::vsreg => types! {
vsx: F32, F64, VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
},
Self::cr | Self::ctr | Self::lr | Self::xer => &[],
Self::cr | Self::ctr | Self::lr | Self::xer | Self::spe_acc => &[],
}
}
}
@ -285,6 +286,7 @@ def_regs! {
ctr: ctr = ["ctr"],
lr: lr = ["lr"],
xer: xer = ["xer"],
spe_acc: spe_acc = ["spe_acc"],
#error = ["r1", "1", "sp"] =>
"the stack pointer cannot be used as an operand for inline asm",
#error = ["r2", "2"] =>
@ -342,6 +344,7 @@ impl PowerPCInlineAsmReg {
(ctr, "ctr");
(lr, "lr");
(xer, "xer");
(spe_acc, "spe_acc");
}
}

View file

@ -4034,62 +4034,6 @@ pub trait Iterator {
{
unreachable!("Always specialized");
}
/// Checks if the iterator contains *exactly* one element.
/// If so, returns this one element.
///
/// See also [`collect_array`](Iterator::collect_array) for lengths other than `1`.
///
/// # Examples
///
/// ```
/// #![feature(exact_length_collection)]
///
/// assert_eq!([1].into_iter().exactly_one(), Some(1));
/// assert_eq!([].into_iter().exactly_one(), None::<()>);
///
/// // There is exactly one even integer in the array:
/// assert_eq!([1, 2, 3].into_iter().filter(|x| x % 2 == 0).exactly_one(), Some(2));
/// // But there are two odds, which is too many:
/// assert_eq!([1, 2, 3].into_iter().filter(|x| x % 2 == 1).exactly_one(), None);
/// ```
#[inline]
#[unstable(feature = "exact_length_collection", issue = "149266")]
fn exactly_one(self) -> Option<Self::Item>
where
Self: Sized,
{
self.collect_array::<1>().map(|[i]| i)
}
/// Checks if an iterator has *exactly* `N` elements.
/// If so, returns those `N` elements in an array.
///
/// See also [`exactly_one`](Iterator::exactly_one) when expecting a single element.
///
/// # Examples
///
/// ```
/// #![feature(exact_length_collection)]
///
/// assert_eq!([1, 2, 3, 4].into_iter().collect_array(), Some([1, 2, 3, 4]));
/// assert_eq!([1, 2].into_iter().chain([3, 4]).collect_array(), Some([1, 2, 3, 4]));
///
/// // Iterator contains too few elements:
/// assert_eq!([1, 2].into_iter().collect_array::<4>(), None);
/// // Iterator contains too many elements:
/// assert_eq!([1, 2, 3, 4, 5].into_iter().collect_array::<4>(), None);
/// // Taking 4 makes it work again:
/// assert_eq!([1, 2, 3, 4, 5].into_iter().take(4).collect_array(), Some([1, 2, 3, 4]));
/// ```
#[inline]
#[unstable(feature = "exact_length_collection", issue = "149266")]
fn collect_array<const N: usize>(mut self) -> Option<[Self::Item; N]>
where
Self: Sized,
{
self.next_chunk().ok().filter(|_| self.next().is_none())
}
}
trait SpecIterEq<B: Iterator>: Iterator {

View file

@ -8,6 +8,7 @@
#![feature(iter_array_chunks)]
#![feature(iter_next_chunk)]
#![feature(iter_advance_by)]
#![feature(uint_gather_scatter_bits)]
extern crate test;

View file

@ -0,0 +1,62 @@
const BYTES: usize = 1 << 10;
macro_rules! bench_template {
($op:path, $name:ident, $mask:expr) => {
#[bench]
fn $name(bench: &mut ::test::Bencher) {
use ::rand::Rng;
let mut rng = crate::bench_rng();
let mut dst = vec![0; ITERATIONS];
let src1: Vec<U> = (0..ITERATIONS).map(|_| rng.random_range(0..=U::MAX)).collect();
let mut src2: Vec<U> = (0..ITERATIONS).map(|_| rng.random_range(0..=U::MAX)).collect();
// Fix the loop invariant mask
src2[0] = U::MAX / 3;
let dst = dst.first_chunk_mut().unwrap();
let src1 = src1.first_chunk().unwrap();
let src2 = src2.first_chunk().unwrap();
#[allow(unused)]
fn vectored(dst: &mut Data, src1: &Data, src2: &Data) {
let mask = $mask;
for k in 0..ITERATIONS {
dst[k] = $op(src1[k], mask(src2, k));
}
}
let f: fn(&mut Data, &Data, &Data) = vectored;
let f = ::test::black_box(f);
bench.iter(|| {
f(dst, src1, src2);
});
}
};
}
macro_rules! bench_type {
($U:ident) => {
mod $U {
type U = $U;
const ITERATIONS: usize = super::BYTES / size_of::<U>();
type Data = [U; ITERATIONS];
bench_mask_kind!(constant, |_, _| const { U::MAX / 3 });
bench_mask_kind!(invariant, |src: &Data, _| src[0]);
bench_mask_kind!(variable, |src: &Data, k| src[k]);
}
};
}
macro_rules! bench_mask_kind {
($mask_kind:ident, $mask:expr) => {
mod $mask_kind {
use super::{Data, ITERATIONS, U};
bench_template!(U::gather_bits, gather_bits, $mask);
bench_template!(U::scatter_bits, scatter_bits, $mask);
}
};
}
bench_type!(u8);
bench_type!(u16);
bench_type!(u32);
bench_type!(u64);
bench_type!(u128);

View file

@ -1,5 +1,6 @@
mod dec2flt;
mod flt2dec;
mod int_bits;
mod int_log;
mod int_pow;
mod int_sqrt;

View file

@ -950,19 +950,19 @@ impl Error {
where
E: error::Error + Send + Sync + 'static,
{
match self.repr.into_data() {
ErrorData::Custom(b) if b.error.is::<E>() => {
let res = (*b).error.downcast::<E>();
// downcast is a really trivial and is marked as inline, so
// it's likely be inlined here.
//
// And the compiler should be able to eliminate the branch
// that produces `Err` here since b.error.is::<E>()
// returns true.
Ok(*res.unwrap())
if let ErrorData::Custom(c) = self.repr.data()
&& c.error.is::<E>()
{
if let ErrorData::Custom(b) = self.repr.into_data()
&& let Ok(err) = b.error.downcast::<E>()
{
Ok(*err)
} else {
// Safety: We have just checked that the condition is true
unsafe { crate::hint::unreachable_unchecked() }
}
repr_data => Err(Self { repr: Repr::new(repr_data) }),
} else {
Err(self)
}
}

View file

@ -133,15 +133,6 @@ unsafe impl Send for Repr {}
unsafe impl Sync for Repr {}
impl Repr {
pub(super) fn new(dat: ErrorData<Box<Custom>>) -> Self {
match dat {
ErrorData::Os(code) => Self::new_os(code),
ErrorData::Simple(kind) => Self::new_simple(kind),
ErrorData::SimpleMessage(simple_message) => Self::new_simple_message(simple_message),
ErrorData::Custom(b) => Self::new_custom(b),
}
}
pub(super) fn new_custom(b: Box<Custom>) -> Self {
let p = Box::into_raw(b).cast::<u8>();
// Should only be possible if an allocator handed out a pointer with

View file

@ -10,9 +10,6 @@ pub(super) struct Repr(Inner);
impl Repr {
#[inline]
pub(super) fn new(dat: ErrorData<Box<Custom>>) -> Self {
Self(dat)
}
pub(super) fn new_custom(b: Box<Custom>) -> Self {
Self(Inner::Custom(b))
}

View file

@ -2,6 +2,7 @@ use crate::ffi::CStr;
use crate::io;
use crate::num::NonZeroUsize;
use crate::sys::map_motor_error;
use crate::thread::ThreadInit;
use crate::time::Duration;
pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 256;
@ -14,21 +15,21 @@ unsafe impl Send for Thread {}
unsafe impl Sync for Thread {}
impl Thread {
pub unsafe fn new(
stack: usize,
_name: Option<&str>,
p: Box<dyn FnOnce()>,
) -> io::Result<Thread> {
pub unsafe fn new(stack: usize, init: Box<ThreadInit>) -> io::Result<Thread> {
extern "C" fn __moto_rt_thread_fn(thread_arg: u64) {
unsafe {
Box::from_raw(
core::ptr::with_exposed_provenance::<Box<dyn FnOnce()>>(thread_arg as usize)
.cast_mut(),
)();
let init = Box::from_raw(core::ptr::with_exposed_provenance_mut::<ThreadInit>(
thread_arg as usize,
));
let rust_start = init.init();
if let Some(name) = crate::thread::current().name() {
let _ = moto_rt::thread::set_name(name);
}
rust_start();
}
}
let thread_arg = Box::into_raw(Box::new(p)).expose_provenance() as u64;
let thread_arg = Box::into_raw(init).expose_provenance() as u64;
let sys_thread = moto_rt::thread::spawn(__moto_rt_thread_fn, stack, thread_arg)
.map_err(map_motor_error)?;
Ok(Self { sys_thread })

View file

@ -46,10 +46,10 @@ disabled as needed with `-C target-feature=(+/-)`.
## Start-up and Low-Level Code
The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`]
and [`cortex-r-rt`] crates, which may be useful for writing bare-metal code
The [Rust Embedded Devices Working Group Arm Team] maintain the [`aarch32-cpu`]
and [`aarch32-rt`] crates, which may be useful for writing bare-metal code
using this target. Those crates include several examples which run in QEMU and
build using these targets.
[`cortex-ar`]: https://docs.rs/cortex-ar
[`cortex-r-rt`]: https://docs.rs/cortex-r-rt
[`aarch32-cpu`]: https://docs.rs/aarch32-cpu
[`aarch32-rt`]: https://docs.rs/aarch32-rt

View file

@ -63,10 +63,10 @@ and disable them via `.cargo/config.toml` file.
## Start-up and Low-Level Code
The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`]
and [`cortex-a-rt`] crates, which may be useful for writing bare-metal code
using this target. The [`cortex-ar` repository](https://github.com/rust-embedded/cortex-ar)
includes several examples which run in QEMU and build using these targets.
The [Rust Embedded Devices Working Group Arm Team] maintain the [`aarch32-cpu`]
and [`aarch32-rt`] crates, which may be useful for writing bare-metal code
using this target. Those crates include several examples which run in QEMU and
build using these targets.
[`cortex-ar`]: https://docs.rs/cortex-ar
[`cortex-a-rt`]: https://docs.rs/cortex-a-rt
[`aarch32-cpu`]: https://docs.rs/aarch32-cpu
[`aarch32-rt`]: https://docs.rs/aarch32-rt

View file

@ -41,10 +41,10 @@ disabled as needed with `-C target-feature=(+/-)`.
## Start-up and Low-Level Code
The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`]
and [`cortex-r-rt`] crates, which may be useful for writing bare-metal code
The [Rust Embedded Devices Working Group Arm Team] maintain the [`aarch32-cpu`]
and [`aarch32-rt`] crates, which may be useful for writing bare-metal code
using this target. Those crates include several examples which run in QEMU and
build using these targets.
[`cortex-ar`]: https://docs.rs/cortex-ar
[`cortex-r-rt`]: https://docs.rs/cortex-r-rt
[`aarch32-cpu`]: https://docs.rs/aarch32-cpu
[`aarch32-rt`]: https://docs.rs/aarch32-rt

View file

@ -40,6 +40,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| PowerPC | `ctr` | `ctr` | Only clobbers |
| PowerPC | `lr` | `lr` | Only clobbers |
| PowerPC | `xer` | `xer` | Only clobbers |
| PowerPC | `spe_acc` | `spe_acc` | Only clobbers |
| wasm32 | `local` | None\* | `r` |
| BPF | `reg` | `r[0-10]` | `r` |
| BPF | `wreg` | `w[0-10]` | `w` |
@ -63,6 +64,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
> - WebAssembly doesn't have registers, so named registers are not supported.
>
> - r29 is reserved only on 32 bit PowerPC targets.
>
> - spe_acc is only available on PowerPC SPE targets.
# Register class supported types
@ -87,6 +90,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| PowerPC | `ctr` | N/A | Only clobbers |
| PowerPC | `lr` | N/A | Only clobbers |
| PowerPC | `xer` | N/A | Only clobbers |
| PowerPC | `spe_acc` | N/A | Only clobbers |
| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
| BPF | `reg` | None | `i8` `i16` `i32` `i64` |
| BPF | `wreg` | `alu32` | `i8` `i16` `i32` |

View file

@ -1126,8 +1126,7 @@ pub(crate) fn print_impl(
}
if impl_.kind.is_fake_variadic()
&& let Some(generics) = ty.generics()
// FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
&& let Ok(inner_type) = Itertools::exactly_one(generics)
&& let Ok(inner_type) = generics.exactly_one()
{
let last = ty.last();
if f.alternate() {
@ -1207,8 +1206,7 @@ impl clean::Impl {
}
} else if let clean::Type::Path { path } = type_
&& let Some(generics) = path.generics()
// FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
&& let Ok(ty) = Itertools::exactly_one(generics)
&& let Ok(ty) = generics.exactly_one()
&& self.kind.is_fake_variadic()
{
print_anchor(path.def_id(), path.last(), cx).fmt(f)?;

View file

@ -92,8 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
(matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id)))
.then_some((v.def_id, v.span))
});
// FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
if let Ok((id, span)) = Itertools::exactly_one(iter)
if let Ok((id, span)) = iter.exactly_one()
&& !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..))
{
self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
.iter()
.filter(|field| !cx.effective_visibilities.is_exported(field.def_id));
if fields.len() > 1
// FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
&& let Ok(field) = Itertools::exactly_one(private_fields)
&& let Ok(field) = private_fields.exactly_one()
&& let TyKind::Tup([]) = field.ty.kind
{
span_lint_and_then(

View file

@ -252,10 +252,7 @@ pub struct Config {
///
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage1/bin/lib`
///
/// FIXME: maybe rename this to reflect (1) which target platform (host, not target), and (2)
/// which `rustc` (the `rustc`-under-test, not the stage 0 `rustc` unless forced).
pub compile_lib_path: Utf8PathBuf,
pub host_compile_lib_path: Utf8PathBuf,
/// Path to libraries needed to run the compiled executable for the **target** platform. This
/// corresponds to the **target** sysroot libraries, including the **target** standard library.
@ -263,21 +260,28 @@ pub struct Config {
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/i686-unknown-linux-gnu/lib`
///
/// FIXME: maybe rename this to reflect (1) which target platform (target, not host), and (2)
/// what "run libraries" are against.
///
/// FIXME: this is very under-documented in conjunction with the `remote-test-client` scheme and
/// `RUNNER` scheme to actually run the target executable under the target platform environment,
/// cf. [`Self::remote_test_client`] and [`Self::runner`].
pub run_lib_path: Utf8PathBuf,
pub target_run_lib_path: Utf8PathBuf,
/// Path to the *staged* `rustc`-under-test. Unless forced, this `rustc` is *staged*, and must
/// not be confused with [`Self::stage0_rustc_path`].
/// Path to the `rustc`-under-test.
///
/// For `ui-fulldeps` test suite specifically:
///
/// - This is the **stage 0** compiler when testing `ui-fulldeps` under `--stage=1`.
/// - This is the **stage 2** compiler when testing `ui-fulldeps` under `--stage=2`.
///
/// See [`Self::query_rustc_path`] for the `--stage=1` `ui-fulldeps` scenario where a separate
/// in-tree `rustc` is used for querying target information.
///
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc`
///
/// FIXME: maybe rename this to reflect that this is the `rustc`-under-test.
/// # Note on forced stage0
///
/// It is possible for this `rustc` to be a stage 0 `rustc` if explicitly configured with the
/// bootstrap option `build.compiletest-allow-stage0=true` and specifying `--stage=0`.
pub rustc_path: Utf8PathBuf,
/// Path to a *staged* **host** platform cargo executable (unless stage 0 is forced). This
@ -317,10 +321,10 @@ pub struct Config {
pub python: String,
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
pub jsondocck_path: Option<String>,
pub jsondocck_path: Option<Utf8PathBuf>,
/// Path to the `src/tools/jsondoclint/` bootstrap tool executable.
pub jsondoclint_path: Option<String>,
pub jsondoclint_path: Option<Utf8PathBuf>,
/// Path to a host LLVM `FileCheck` executable.
pub llvm_filecheck: Option<Utf8PathBuf>,
@ -333,7 +337,7 @@ pub struct Config {
/// The path to the **target** `clang` executable to run `clang`-based tests with. If `None`,
/// then these tests will be ignored.
pub run_clang_based_tests_with: Option<String>,
pub run_clang_based_tests_with: Option<Utf8PathBuf>,
/// Path to the directory containing the sources. This corresponds to the root folder of a
/// `rust-lang/rust` checkout.
@ -526,7 +530,7 @@ pub struct Config {
///
/// FIXME: we are propagating a python from `PYTHONPATH`, not from an explicit config for gdb
/// debugger script.
pub gdb: Option<String>,
pub gdb: Option<Utf8PathBuf>,
/// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch
///
@ -571,7 +575,7 @@ pub struct Config {
///
/// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for
/// `arm-linux-androideabi` target.
pub adb_path: String,
pub adb_path: Utf8PathBuf,
/// Extra parameter to run test suite on `arm-linux-androideabi`.
///
@ -580,7 +584,7 @@ pub struct Config {
///
/// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for
/// `arm-linux-androideabi` target.
pub adb_test_dir: String,
pub adb_test_dir: Utf8PathBuf,
/// Status whether android device available or not. When unavailable, this will cause tests to
/// panic when the test binary is attempted to be run.
@ -656,7 +660,7 @@ pub struct Config {
pub llvm_components: String,
/// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests.
pub nodejs: Option<String>,
pub nodejs: Option<Utf8PathBuf>,
/// Whether to rerun tests even if the inputs are unchanged.
pub force_rerun: bool,
@ -683,9 +687,12 @@ pub struct Config {
pub builtin_cfg_names: OnceLock<HashSet<String>>,
pub supported_crate_types: OnceLock<HashSet<String>>,
/// FIXME: rename this to the more canonical `no_capture`, or better, invert this to `capture`
/// to avoid `!nocapture` double-negatives.
pub nocapture: bool,
/// Should we capture console output that would be printed by test runners via their `stdout`
/// and `stderr` trait objects, or via the custom panic hook.
///
/// The default is `true`. This can be disabled via the compiletest cli flag `--no-capture`
/// (which mirrors the libtest `--no-capture` flag).
pub capture: bool,
/// Needed both to construct [`build_helper::git::GitConfig`].
pub nightly_branch: String,
@ -1093,7 +1100,7 @@ fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, Stri
let query_rustc_path = config.query_rustc_path.as_deref().unwrap_or(&config.rustc_path);
let mut command = Command::new(query_rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
add_dylib_path(&mut command, iter::once(&config.host_compile_lib_path));
command.args(&config.target_rustcflags).args(args);
command.env("RUSTC_BOOTSTRAP", "1");
command.envs(envs);

View file

@ -133,7 +133,7 @@ pub(crate) fn discover_gdb(
gdb: Option<String>,
target: &str,
android_cross_path: &Utf8Path,
) -> Option<String> {
) -> Option<Utf8PathBuf> {
#[cfg(not(windows))]
const GDB_FALLBACK: &str = "gdb";
#[cfg(windows)]
@ -155,10 +155,10 @@ pub(crate) fn discover_gdb(
Some(ref s) => s.to_owned(),
};
Some(gdb)
Some(Utf8PathBuf::from(gdb))
}
pub(crate) fn query_gdb_version(gdb: &str) -> Option<u32> {
pub(crate) fn query_gdb_version(gdb: &Utf8Path) -> Option<u32> {
let mut version_line = None;
if let Ok(output) = Command::new(&gdb).arg("--version").output() {
if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() {

View file

@ -367,7 +367,7 @@ impl CachedNeedsConditions {
//
// However, `rust-lld` is only located under the lib path, so we look for it there.
rust_lld: config
.compile_lib_path
.host_compile_lib_path
.parent()
.expect("couldn't traverse to the parent of the specified --compile-lib-path")
.join("lib")

View file

@ -196,10 +196,10 @@ enum CaptureKind {
impl CaptureKind {
fn for_config(config: &Config) -> Self {
if config.nocapture {
Self::None
} else {
if config.capture {
Self::Capture { buf: output_capture::CaptureBuf::new() }
} else {
Self::None
}
}

View file

@ -375,8 +375,8 @@ fn parse_config(args: Vec<String>) -> Config {
fail_fast: matches.opt_present("fail-fast")
|| env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
host_compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
target_run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
rustc_path: opt_path(matches, "rustc-path"),
cargo_path: matches.opt_str("cargo-path").map(Utf8PathBuf::from),
stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(Utf8PathBuf::from),
@ -384,9 +384,11 @@ fn parse_config(args: Vec<String>) -> Config {
rustdoc_path: matches.opt_str("rustdoc-path").map(Utf8PathBuf::from),
coverage_dump_path: matches.opt_str("coverage-dump-path").map(Utf8PathBuf::from),
python: matches.opt_str("python").unwrap(),
jsondocck_path: matches.opt_str("jsondocck-path"),
jsondoclint_path: matches.opt_str("jsondoclint-path"),
run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"),
jsondocck_path: matches.opt_str("jsondocck-path").map(Utf8PathBuf::from),
jsondoclint_path: matches.opt_str("jsondoclint-path").map(Utf8PathBuf::from),
run_clang_based_tests_with: matches
.opt_str("run-clang-based-tests-with")
.map(Utf8PathBuf::from),
llvm_filecheck: matches.opt_str("llvm-filecheck").map(Utf8PathBuf::from),
llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(Utf8PathBuf::from),
@ -441,8 +443,8 @@ fn parse_config(args: Vec<String>) -> Config {
llvm_version,
system_llvm: matches.opt_present("system-llvm"),
android_cross_path,
adb_path: opt_str2(matches.opt_str("adb-path")),
adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")),
adb_path: Utf8PathBuf::from(opt_str2(matches.opt_str("adb-path"))),
adb_test_dir: Utf8PathBuf::from(opt_str2(matches.opt_str("adb-test-dir"))),
adb_device_status: opt_str2(matches.opt_str("target")).contains("android")
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
@ -466,7 +468,7 @@ fn parse_config(args: Vec<String>) -> Config {
target_linker: matches.opt_str("target-linker"),
host_linker: matches.opt_str("host-linker"),
llvm_components: matches.opt_str("llvm-components").unwrap(),
nodejs: matches.opt_str("nodejs"),
nodejs: matches.opt_str("nodejs").map(Utf8PathBuf::from),
force_rerun: matches.opt_present("force-rerun"),
@ -474,7 +476,7 @@ fn parse_config(args: Vec<String>) -> Config {
builtin_cfg_names: OnceLock::new(),
supported_crate_types: OnceLock::new(),
nocapture: matches.opt_present("no-capture"),
capture: !matches.opt_present("no-capture"),
nightly_branch: matches.opt_str("nightly-branch").unwrap(),
git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
@ -688,7 +690,7 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
stamp.add_dir(&src_root.join("src/etc/natvis"));
stamp.add_dir(&config.run_lib_path);
stamp.add_dir(&config.target_run_lib_path);
if let Some(ref rustdoc_path) = config.rustdoc_path {
stamp.add_path(&rustdoc_path);

View file

@ -458,7 +458,7 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
rustc,
self.config.compile_lib_path.as_path(),
self.config.host_compile_lib_path.as_path(),
Some(aux_dir.as_path()),
src,
)
@ -1060,7 +1060,7 @@ impl<'test> TestCx<'test> {
rustdoc.current_dir(current_dir);
rustdoc
.arg("-L")
.arg(self.config.run_lib_path.as_path())
.arg(self.config.target_run_lib_path.as_path())
.arg("-L")
.arg(aux_dir)
.arg("-o")
@ -1151,7 +1151,7 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
test_client,
self.config.run_lib_path.as_path(),
self.config.target_run_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
)
@ -1166,7 +1166,7 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
wr_run,
self.config.run_lib_path.as_path(),
self.config.target_run_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
)
@ -1181,7 +1181,7 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
program,
self.config.run_lib_path.as_path(),
self.config.target_run_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
)
@ -1321,7 +1321,7 @@ impl<'test> TestCx<'test> {
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
self.compose_and_run(
rustc,
self.config.compile_lib_path.as_path(),
self.config.host_compile_lib_path.as_path(),
Some(aux_dir.as_path()),
input,
)
@ -1344,7 +1344,8 @@ impl<'test> TestCx<'test> {
rustc.arg("-Cpanic=abort");
rustc.args(self.props.minicore_compile_flags.clone());
let res = self.compose_and_run(rustc, self.config.compile_lib_path.as_path(), None, None);
let res =
self.compose_and_run(rustc, self.config.host_compile_lib_path.as_path(), None, None);
if !res.status.success() {
self.fatal_proc_rec(
&format!("auxiliary build of {} failed to compile: ", self.config.minicore_path),
@ -1458,7 +1459,7 @@ impl<'test> TestCx<'test> {
let auxres = aux_cx.compose_and_run(
aux_rustc,
aux_cx.config.compile_lib_path.as_path(),
aux_cx.config.host_compile_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
);

View file

@ -90,7 +90,7 @@ impl TestCx<'_> {
let debugger_run_result = self.compose_and_run(
cdb,
self.config.run_lib_path.as_path(),
self.config.target_run_lib_path.as_path(),
None, // aux_path
None, // input
);
@ -313,7 +313,7 @@ impl TestCx<'_> {
gdb.args(debugger_opts).env("PYTHONPATH", pythonpath);
debugger_run_result =
self.compose_and_run(gdb, self.config.run_lib_path.as_path(), None, None);
self.compose_and_run(gdb, self.config.target_run_lib_path.as_path(), None, None);
}
if !debugger_run_result.status.success() {

View file

@ -172,10 +172,10 @@ impl TestCx<'_> {
.env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap())
// Provide the directory to libraries that are needed to run the *compiler* invoked
// by the recipe.
.env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path)
.env("HOST_RUSTC_DYLIB_PATH", &self.config.host_compile_lib_path)
// Provide the directory to libraries that might be needed to run binaries created
// by a compiler invoked by the recipe.
.env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path)
.env("TARGET_EXE_DYLIB_PATH", &self.config.target_run_lib_path)
// Provide the target.
.env("TARGET", &self.config.target)
// Some tests unfortunately still need Python, so provide path to a Python interpreter.

View file

@ -58,8 +58,8 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
edition: Default::default(),
bless: Default::default(),
fail_fast: Default::default(),
compile_lib_path: Utf8PathBuf::default(),
run_lib_path: Utf8PathBuf::default(),
host_compile_lib_path: Utf8PathBuf::default(),
target_run_lib_path: Utf8PathBuf::default(),
rustc_path: Utf8PathBuf::default(),
cargo_path: Default::default(),
stage0_rustc_path: Default::default(),
@ -130,7 +130,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
target_cfgs: Default::default(),
builtin_cfg_names: Default::default(),
supported_crate_types: Default::default(),
nocapture: Default::default(),
capture: Default::default(),
nightly_branch: Default::default(),
git_merge_commit_email: Default::default(),
profiler_runtime: Default::default(),

View file

@ -69,10 +69,10 @@ pub unsafe fn vs32_clobber() {
// Output format depends on the availability of altivec and vsx
// CHECK-LABEL: @clobber_abi
// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
#[no_mangle]
pub unsafe fn clobber_abi() {
asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
@ -104,10 +104,10 @@ pub unsafe fn clobber_preservesflags() {
// Output format depends on the availability of altivec and vsx
// CHECK-LABEL: @clobber_abi_no_preserves_flags
#[no_mangle]
// powerpc: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// powerpc64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// powerpc64le: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// aix64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
// powerpc: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
// powerpc64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
// powerpc64le: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
// aix64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"()
pub unsafe fn clobber_abi_no_preserves_flags() {
// Use a nop to prevent aliasing of identical functions here.
asm!("nop", clobber_abi("C"), options(nostack, nomem));

View file

@ -4,7 +4,7 @@ use std::mem::MaybeUninit;
trait CollectSlice<'a>: Iterator {
fn inner_array<const N: usize>(&mut self) -> [Self::Item; N];
fn custom_collect_array<const N: usize>(&mut self) -> [Self::Item; N] {
fn collect_array<const N: usize>(&mut self) -> [Self::Item; N] {
let result = self.inner_array();
assert!(self.next().is_none());
result
@ -34,5 +34,5 @@ where
fn main() {
let mut foos = [0u64; 9].iter().cloned();
let _bar: [u64; 9] = foos.custom_collect_array::<9_usize>();
let _bar: [u64; 9] = foos.collect_array::<9_usize>();
}

View file

@ -1,6 +0,0 @@
fn main() {
let _p: char = 100;
//~^ ERROR mismatched types
//~| NOTE expected `char`, found `u8`
//~| NOTE expected due to this
}

View file

@ -1,11 +0,0 @@
error[E0308]: mismatched types
--> $DIR/issue-3477.rs:2:20
|
LL | let _p: char = 100;
| ---- ^^^ expected `char`, found `u8`
| |
| expected due to this
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -2,7 +2,7 @@ error: const items should never be `#[no_mangle]`
--> $DIR/issue-45562.rs:5:14
|
LL | #[no_mangle] pub const RAH: usize = 5;
| ---------^^^^^^^^^^^^^^^^
| ----------^^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`
|

View file

@ -1,7 +0,0 @@
// Regression test for issue #4935
fn foo(a: usize) {}
//~^ NOTE defined here
fn main() { foo(5, 6) }
//~^ ERROR function takes 1 argument but 2 arguments were supplied
//~| NOTE unexpected argument #2 of type `{integer}`

View file

@ -1,20 +0,0 @@
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/issue-4935.rs:5:13
|
LL | fn main() { foo(5, 6) }
| ^^^ - unexpected argument #2 of type `{integer}`
|
note: function defined here
--> $DIR/issue-4935.rs:3:4
|
LL | fn foo(a: usize) {}
| ^^^
help: remove the extra argument
|
LL - fn main() { foo(5, 6) }
LL + fn main() { foo(5) }
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0061`.

View file

@ -1,2 +0,0 @@
fn main() { format!("{:?}", None); }
//~^ ERROR type annotations needed [E0282]

View file

@ -1,14 +0,0 @@
error[E0282]: type annotations needed
--> $DIR/issue-5062.rs:1:29
|
LL | fn main() { format!("{:?}", None); }
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
help: consider specifying the generic argument
|
LL | fn main() { format!("{:?}", None::<T>); }
| +++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0282`.

View file

@ -31,7 +31,7 @@ error: const items should never be `#[no_mangle]`
--> $DIR/lint-unexported-no-mangle.rs:9:1
|
LL | const FOO: u64 = 1;
| -----^^^^^^^^^^^^^^
| ------^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`
|
@ -41,7 +41,7 @@ error: const items should never be `#[no_mangle]`
--> $DIR/lint-unexported-no-mangle.rs:12:1
|
LL | pub const PUB_FOO: u64 = 1;
| ---------^^^^^^^^^^^^^^^^^^
| ----------^^^^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`

View file

@ -0,0 +1,24 @@
//! Ensure the `no_mangle_const_items` lint triggers but does not offer a `pub static`
//! suggestion for consts that have generics or a where-clause.
//! regression test for <https://github.com/rust-lang/rust/issues/149511>
#![feature(generic_const_items)]
#![allow(incomplete_features)]
#![deny(no_mangle_const_items)]
trait Trait {
const ASSOC: u32;
}
#[unsafe(no_mangle)]
const WHERE_BOUND: u32 = <&'static ()>::ASSOC where for<'a> &'a (): Trait;
//~^ ERROR: const items should never be `#[no_mangle]`
#[no_mangle]
const _: () = () where;
//~^ ERROR: const items should never be `#[no_mangle]`
#[unsafe(no_mangle)]
pub const GENERIC<const N: usize>: usize = N;
//~^ ERROR: const items should never be `#[no_mangle]`
fn main() {}

View file

@ -0,0 +1,26 @@
error: const items should never be `#[no_mangle]`
--> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:13:1
|
LL | const WHERE_BOUND: u32 = <&'static ()>::ASSOC where for<'a> &'a (): Trait;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:7:9
|
LL | #![deny(no_mangle_const_items)]
| ^^^^^^^^^^^^^^^^^^^^^
error: const items should never be `#[no_mangle]`
--> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:17:1
|
LL | const _: () = () where;
| ^^^^^^^^^^^^^^^^^^^^^^^
error: const items should never be `#[no_mangle]`
--> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:21:1
|
LL | pub const GENERIC<const N: usize>: usize = N;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -52,7 +52,7 @@ error: const items should never be `#[no_mangle]`
--> $DIR/suggestions.rs:6:14
|
LL | #[no_mangle] const DISCOVERY: usize = 1;
| -----^^^^^^^^^^^^^^^^^^^^^^
| ------^^^^^^^^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`
|
@ -81,7 +81,7 @@ error: const items should never be `#[no_mangle]`
--> $DIR/suggestions.rs:22:18
|
LL | #[no_mangle] pub const DAUNTLESS: bool = true;
| ---------^^^^^^^^^^^^^^^^^^^^^^^^
| ----------^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`
@ -97,7 +97,7 @@ error: const items should never be `#[no_mangle]`
--> $DIR/suggestions.rs:31:18
|
LL | #[no_mangle] pub(crate) const VETAR: bool = true;
| ----------------^^^^^^^^^^^^^^^^^^^^
| -----------------^^^^^^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`

View file

@ -29,11 +29,10 @@ where
fn main() {
assert_eq!(
CollectArray::collect_array(
&mut [[1, 2], [3, 4]]
[[1, 2], [3, 4]]
.iter()
.map(|row| CollectArray::collect_array(&mut row.iter()))
),
.map(|row| row.iter().collect_array())
.collect_array(),
[[&1, &2], [&3, &4]]
);
}

View file

@ -0,0 +1,9 @@
//! regression test for <https://github.com/rust-lang/rust/issues/3477>
fn main() {
let x: u32 = ();
//~^ ERROR mismatched types
let _p: char = 100;
//~^ ERROR mismatched types
}

View file

@ -0,0 +1,19 @@
error[E0308]: mismatched types
--> $DIR/assignment-mismatch-various-types.rs:4:18
|
LL | let x: u32 = ();
| --- ^^ expected `u32`, found `()`
| |
| expected due to this
error[E0308]: mismatched types
--> $DIR/assignment-mismatch-various-types.rs:7:20
|
LL | let _p: char = 100;
| ---- ^^^ expected `char`, found `u8`
| |
| expected due to this
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,4 +0,0 @@
fn main() {
let x: u32 = ( //~ ERROR mismatched types
);
}

View file

@ -1,13 +0,0 @@
error[E0308]: mismatched types
--> $DIR/main.rs:2:18
|
LL | let x: u32 = (
| ____________---___^
| | |
| | expected due to this
LL | | );
| |_____^ expected `u32`, found `()`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,16 @@
// Regression test for <https://github.com/rust-lang/rust/pull/149545#discussion_r2585205872>
//
//@ check-pass
#![feature(guard_patterns, never_type)]
#![expect(incomplete_features, unused_parens)]
#![deny(unreachable_code)]
fn main() {
unsafe {
let x = std::ptr::null::<!>();
// This should not constitute a read for never, therefore no code here is unreachable
let (_ if false): ! = *x;
();
}
}

View file

@ -0,0 +1,19 @@
// Regression test for <https://github.com/rust-lang/rust/issues/149542>.
//
// This checks that a nested type ascription doesn't cause a crash when the
// compiler checks if it constitutes a read of the never type.
//
//@ check-pass
#![feature(never_type)]
#![feature(type_ascription)]
#![deny(unreachable_code)]
fn main() {
unsafe {
let _ = type_ascribe!(type_ascribe!(*std::ptr::null(), !), _);
// this is *not* unreachable, because previous line does not actually read the never type
();
}
}

View file

@ -0,0 +1,17 @@
// Regression test for <https://github.com/rust-lang/rust/issues/149431>
//
// Checks that type ascription of a field place with type never is correctly
// checked for if it constitutes a read of type never. (it doesn't)
//
//@ check-pass
#![feature(never_type)]
#![feature(type_ascription)]
#![deny(unreachable_code)]
fn main() {
let x: (!,);
let _ = type_ascribe!(x.0, _);
(); // reachable
}

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/3109>
//@ run-pass
pub fn main() {
println!("{:?}", ("hi there!", "you"));

View file

@ -1,3 +1,5 @@
//! regression test for <https://github.com/rust-lang/rust/issues/51874>
fn main() {
let a = (1.0).pow(1.0); //~ ERROR can't call method `pow` on ambiguous numeric type
}

View file

@ -1,5 +1,5 @@
error[E0689]: can't call method `pow` on ambiguous numeric type `{float}`
--> $DIR/issue-51874.rs:2:19
--> $DIR/ambiguous-num-type-method-call.rs:4:19
|
LL | let a = (1.0).pow(1.0);
| ^^^

View file

@ -1,5 +1,9 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/5062>.
fn foo() {
format!("{:?}", None); //~ ERROR type annotations needed [E0282]
}
fn main() {
None; //~ ERROR type annotations needed [E0282]
}

View file

@ -1,5 +1,16 @@
error[E0282]: type annotations needed
--> $DIR/type-inference-unconstrained-none.rs:4:5
--> $DIR/type-inference-unconstrained-none.rs:4:21
|
LL | format!("{:?}", None);
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
help: consider specifying the generic argument
|
LL | format!("{:?}", None::<T>);
| +++++
error[E0282]: type annotations needed
--> $DIR/type-inference-unconstrained-none.rs:8:5
|
LL | None;
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
@ -9,6 +20,6 @@ help: consider specifying the generic argument
LL | None::<T>;
| +++++
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0282`.