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:
commit
29e035e172
64 changed files with 575 additions and 488 deletions
|
|
@ -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(®_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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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))?;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -2143,6 +2143,7 @@ symbols! {
|
|||
sparc,
|
||||
sparc64,
|
||||
sparc_target_feature,
|
||||
spe_acc,
|
||||
specialization,
|
||||
speed,
|
||||
spirv,
|
||||
|
|
|
|||
|
|
@ -1271,6 +1271,9 @@ impl InlineAsmClobberAbi {
|
|||
ctr,
|
||||
lr,
|
||||
xer,
|
||||
|
||||
// These are only supported on PowerPC SPE targets.
|
||||
spe_acc,
|
||||
}
|
||||
},
|
||||
InlineAsmClobberAbi::S390x => clobbered_regs! {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(iter_array_chunks)]
|
||||
#![feature(iter_next_chunk)]
|
||||
#![feature(iter_advance_by)]
|
||||
#![feature(uint_gather_scatter_bits)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
|
|
|
|||
62
library/coretests/benches/num/int_bits/mod.rs
Normal file
62
library/coretests/benches/num/int_bits/mod.rs
Normal 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);
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
mod dec2flt;
|
||||
mod flt2dec;
|
||||
mod int_bits;
|
||||
mod int_log;
|
||||
mod int_pow;
|
||||
mod int_sqrt;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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` |
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
fn main() {
|
||||
let _p: char = 100;
|
||||
//~^ ERROR mismatched types
|
||||
//~| NOTE expected `char`, found `u8`
|
||||
//~| NOTE expected due to this
|
||||
}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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}`
|
||||
|
|
@ -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`.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
fn main() { format!("{:?}", None); }
|
||||
//~^ ERROR type annotations needed [E0282]
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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`
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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`
|
||||
|
||||
|
|
|
|||
|
|
@ -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]]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
fn main() {
|
||||
let x: u32 = ( //~ ERROR mismatched types
|
||||
);
|
||||
}
|
||||
|
|
@ -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`.
|
||||
16
tests/ui/reachable/guard_read_for_never.rs
Normal file
16
tests/ui/reachable/guard_read_for_never.rs
Normal 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;
|
||||
();
|
||||
}
|
||||
}
|
||||
19
tests/ui/reachable/nested_type_ascription.rs
Normal file
19
tests/ui/reachable/nested_type_ascription.rs
Normal 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
|
||||
();
|
||||
}
|
||||
}
|
||||
17
tests/ui/reachable/type_ascribe_never_field.rs
Normal file
17
tests/ui/reachable/type_ascribe_never_field.rs
Normal 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
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
//! regression test for <https://github.com/rust-lang/rust/issues/3109>
|
||||
//@ run-pass
|
||||
pub fn main() {
|
||||
println!("{:?}", ("hi there!", "you"));
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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);
|
||||
| ^^^
|
||||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue