diff --git a/RELEASES.md b/RELEASES.md
index b6dc062864678..33abe45ce4629 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1778,7 +1778,7 @@ Language
- [Undeprecate lint `unstable_features` and make use of it in the compiler.](https://github.com/rust-lang/rust/pull/118639/)
- [Make inductive cycles in coherence ambiguous always.](https://github.com/rust-lang/rust/pull/118649/)
- [Get rid of type-driven traversal in const-eval interning](https://github.com/rust-lang/rust/pull/119044/),
- only as a [future compatiblity lint](https://github.com/rust-lang/rust/pull/122204) for now.
+ only as a [future compatibility lint](https://github.com/rust-lang/rust/pull/122204) for now.
- [Deny braced macro invocations in let-else.](https://github.com/rust-lang/rust/pull/119062/)
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 87c9c797ea5b4..de3e0e0c87f5a 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -3137,7 +3137,7 @@ impl FnRetTy {
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
pub enum Inline {
Yes,
- No,
+ No { had_parse_error: Result<(), ErrorGuaranteed> },
}
/// Module item kind.
@@ -3147,7 +3147,7 @@ pub enum ModKind {
/// or with definition outlined to a separate file `mod foo;` and already loaded from it.
/// The inner span is from the first token past `{` to the last token until `}`,
/// or from the first to the last token in the loaded file.
- Loaded(ThinVec>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
+ Loaded(ThinVec>, Inline, ModSpans),
/// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
Unloaded,
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 72817a0a9a053..cd0f9f2403e3f 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -251,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ItemKind::Mod(_, ident, mod_kind) => {
let ident = self.lower_ident(*ident);
match mod_kind {
- ModKind::Loaded(items, _, spans, _) => {
+ ModKind::Loaded(items, _, spans) => {
hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 73cbcdd30ced7..c0679c1b8fffe 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -20,6 +20,10 @@ ast_passes_abi_must_not_have_return_type=
.note = functions with the {$abi} ABI cannot have a return type
.help = remove the return type
+ast_passes_abi_x86_interrupt =
+ invalid signature for `extern "x86-interrupt"` function
+ .note = functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found {$param_count})
+
ast_passes_assoc_const_without_body =
associated constant in `impl` without body
.suggestion = provide a definition for the constant
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 0c72f3190074e..ef4410566c510 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -405,6 +405,17 @@ impl<'a> AstValidator<'a> {
if let InterruptKind::X86 = interrupt_kind {
// "x86-interrupt" is special because it does have arguments.
// FIXME(workingjubilee): properly lint on acceptable input types.
+ let inputs = &sig.decl.inputs;
+ let param_count = inputs.len();
+ if !matches!(param_count, 1 | 2) {
+ let mut spans: Vec =
+ inputs.iter().map(|arg| arg.span).collect();
+ if spans.is_empty() {
+ spans = vec![sig.span];
+ }
+ self.dcx().emit_err(errors::AbiX86Interrupt { spans, param_count });
+ }
+
if let FnRetTy::Ty(ref ret_ty) = sig.decl.output
&& match &ret_ty.kind {
TyKind::Never => false,
@@ -1169,7 +1180,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
}
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
- if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _))
+ if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
&& !attr::contains_name(&item.attrs, sym::path)
{
self.check_mod_file_item_asciionly(*ident);
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 5ecc0d21411d1..b9b2d27195450 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -891,3 +891,12 @@ pub(crate) struct AbiMustNotHaveReturnType {
pub span: Span,
pub abi: ExternAbi,
}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_abi_x86_interrupt)]
+#[note]
+pub(crate) struct AbiX86Interrupt {
+ #[primary_span]
+ pub spans: Vec,
+ pub param_count: usize,
+}
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index a960b96b91c20..8db2904cfd7b7 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1895,7 +1895,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if !output_ty
.is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env))
{
- span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
+ span_mirbug!(self, term, "call to non-diverging function {:?} w/o dest", sig);
}
} else {
let dest_ty = destination.ty(self.body, tcx).ty;
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index e803f3be82b9a..a9d91f77560a7 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -141,7 +141,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
if let ast::ItemKind::Mod(
_,
_,
- ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
+ ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }),
) = item.kind
{
let prev_tests = mem::take(&mut self.tests);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
index d1502d2b1e62e..18a783a348a45 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
@@ -276,7 +276,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
&& let ty::Adt(adt_def, args) = ty.kind()
{
let def_id = adt_def.did();
- // If any sub type reference the original type definition and the sub type has a type
+ // If any child type references the original type definition and the child type has a type
// parameter that strictly contains the original parameter, the original type is a recursive
// type that can expanding indefinitely. Example,
// ```
@@ -285,21 +285,43 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
// Item(T),
// }
// ```
- let is_expanding_recursive = adt_def.is_enum()
- && debug_context(cx).adt_stack.borrow().iter().any(|(parent_def_id, parent_args)| {
- if def_id == *parent_def_id {
- args.iter().zip(parent_args.iter()).any(|(arg, parent_arg)| {
- if let (Some(arg), Some(parent_arg)) = (arg.as_type(), parent_arg.as_type())
- {
- arg != parent_arg && arg.contains(parent_arg)
- } else {
- false
- }
- })
- } else {
- false
- }
- });
+ let is_expanding_recursive = {
+ let stack = debug_context(cx).adt_stack.borrow();
+ stack
+ .iter()
+ .enumerate()
+ .rev()
+ .skip(1)
+ .filter(|(_, (ancestor_def_id, _))| def_id == *ancestor_def_id)
+ .any(|(ancestor_index, (_, ancestor_args))| {
+ args.iter()
+ .zip(ancestor_args.iter())
+ .filter_map(|(arg, ancestor_arg)| arg.as_type().zip(ancestor_arg.as_type()))
+ .any(|(arg, ancestor_arg)|
+ // Strictly contains.
+ (arg != ancestor_arg && arg.contains(ancestor_arg))
+ // Check all types between current and ancestor use the
+ // ancestor_arg.
+ // Otherwise, duplicate wrappers in normal recursive type may be
+ // regarded as expanding.
+ // ```
+ // struct Recursive {
+ // a: Box>,
+ // }
+ // ```
+ // It can produce an ADT stack like this,
+ // - Box
+ // - Recursive
+ // - Box>
+ && stack[ancestor_index + 1..stack.len()].iter().all(
+ |(_, intermediate_args)|
+ intermediate_args
+ .iter()
+ .filter_map(|arg| arg.as_type())
+ .any(|mid_arg| mid_arg.contains(ancestor_arg))
+ ))
+ })
+ };
if is_expanding_recursive {
// FIXME: indicate that this is an expanding recursive type in stub metadata?
return DINodeCreationResult::new(stub_info.metadata, false);
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 1f7f4c7d856d0..755275d3cdac0 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -801,7 +801,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
ItemKind::Mod(
_,
_,
- ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _, _),
+ ModKind::Unloaded
+ | ModKind::Loaded(_, Inline::No { .. }, _),
)
) =>
{
@@ -1035,7 +1036,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fn visit_item(&mut self, item: &'ast ast::Item) {
match &item.kind {
ItemKind::Mod(_, _, mod_kind)
- if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) =>
+ if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
{
feature_err(
self.sess,
@@ -1346,7 +1347,7 @@ impl InvocationCollectorNode for Box {
let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { unreachable!() };
let ecx = &mut collector.cx;
let (file_path, dir_path, dir_ownership) = match mod_kind {
- ModKind::Loaded(_, inline, _, _) => {
+ ModKind::Loaded(_, inline, _) => {
// Inline `mod foo { ... }`, but we still need to push directories.
let (dir_path, dir_ownership) = mod_dir_path(
ecx.sess,
@@ -1360,7 +1361,7 @@ impl InvocationCollectorNode for Box {
// This lets `parse_external_mod` catch cycles if it's self-referential.
let file_path = match inline {
Inline::Yes => None,
- Inline::No => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path),
+ Inline::No { .. } => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path),
};
node.attrs = attrs;
(file_path, dir_path, dir_ownership)
@@ -1396,7 +1397,7 @@ impl InvocationCollectorNode for Box {
);
}
- *mod_kind = ModKind::Loaded(items, Inline::No, spans, had_parse_error);
+ *mod_kind = ModKind::Loaded(items, Inline::No { had_parse_error }, spans);
node.attrs = attrs;
if node.attrs.len() > old_attrs_len {
// If we loaded an out-of-line module and added some inner attributes,
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 662c67f2d3f25..6666ea33cd379 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -120,7 +120,7 @@ pub(crate) fn mod_dir_path(
(dir_path, dir_ownership)
}
- Inline::No => {
+ Inline::No { .. } => {
// FIXME: This is a subset of `parse_external_mod` without actual parsing,
// check whether the logic for unloaded, loaded and inline modules can be unified.
let file_path = mod_file_path(sess, ident, attrs, &module.dir_path, dir_ownership)
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 8006cfcf30fda..c3c0a34df710c 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -3097,7 +3097,7 @@ impl EarlyLintPass for SpecialModuleName {
if let ast::ItemKind::Mod(
_,
ident,
- ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _, _),
+ ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No { .. }, _),
) = item.kind
{
if item.attrs.iter().any(|a| a.has_name(sym::path)) {
diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs
index d4b6da2c14b76..e0cbe8519edd5 100644
--- a/compiler/rustc_mir_build/src/check_tail_calls.rs
+++ b/compiler/rustc_mir_build/src/check_tail_calls.rs
@@ -135,30 +135,23 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
self.report_abi_mismatch(expr.span, caller_sig.abi, callee_sig.abi);
}
+ // FIXME(explicit_tail_calls): this currently fails for cases where opaques are used.
+ // e.g.
+ // ```
+ // fn a() -> impl Sized { become b() } // ICE
+ // fn b() -> u8 { 0 }
+ // ```
+ // we should think what is the expected behavior here.
+ // (we should probably just accept this by revealing opaques?)
if caller_sig.inputs_and_output != callee_sig.inputs_and_output {
- if caller_sig.inputs() != callee_sig.inputs() {
- self.report_arguments_mismatch(
- expr.span,
- self.tcx.liberate_late_bound_regions(
- CRATE_DEF_ID.to_def_id(),
- self.caller_ty.fn_sig(self.tcx),
- ),
- self.tcx
- .liberate_late_bound_regions(CRATE_DEF_ID.to_def_id(), ty.fn_sig(self.tcx)),
- );
- }
-
- // FIXME(explicit_tail_calls): this currently fails for cases where opaques are used.
- // e.g.
- // ```
- // fn a() -> impl Sized { become b() } // ICE
- // fn b() -> u8 { 0 }
- // ```
- // we should think what is the expected behavior here.
- // (we should probably just accept this by revealing opaques?)
- if caller_sig.output() != callee_sig.output() {
- span_bug!(expr.span, "hir typeck should have checked the return type already");
- }
+ self.report_signature_mismatch(
+ expr.span,
+ self.tcx.liberate_late_bound_regions(
+ CRATE_DEF_ID.to_def_id(),
+ self.caller_ty.fn_sig(self.tcx),
+ ),
+ self.tcx.liberate_late_bound_regions(CRATE_DEF_ID.to_def_id(), ty.fn_sig(self.tcx)),
+ );
}
{
@@ -365,7 +358,7 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
self.found_errors = Err(err);
}
- fn report_arguments_mismatch(
+ fn report_signature_mismatch(
&mut self,
sp: Span,
caller_sig: ty::FnSig<'_>,
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index ca89eb1e2cfd4..fd9fb65417c4c 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -43,7 +43,7 @@ impl<'a> Parser<'a> {
self.expect(exp!(OpenBrace))?;
let (inner_attrs, items, inner_span) = self.parse_mod(exp!(CloseBrace))?;
attrs.extend(inner_attrs);
- ModKind::Loaded(items, Inline::Yes, inner_span, Ok(()))
+ ModKind::Loaded(items, Inline::Yes, inner_span)
};
Ok(ItemKind::Mod(safety, ident, mod_kind))
}
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index e0d8fce0685da..f75a625a279bb 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -11,7 +11,7 @@ use std::sync::Arc;
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
use rustc_ast::{
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
- ForeignItemKind, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
+ ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
};
use rustc_attr_parsing as attr;
use rustc_attr_parsing::AttributeParser;
@@ -813,7 +813,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ItemKind::Mod(_, ident, ref mod_kind) => {
self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
- if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind {
+ if let ast::ModKind::Loaded(_, Inline::No { had_parse_error: Err(_) }, _) = mod_kind
+ {
self.r.mods_with_parse_errors.insert(def_id);
}
self.parent_scope.module = self.r.new_local_module(
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index ff39ba46d9791..64641ecc0807e 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -3410,7 +3410,7 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
fn visit_item(&mut self, item: &'tcx ast::Item) {
if self.target_module == item.id {
- if let ItemKind::Mod(_, _, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind {
+ if let ItemKind::Mod(_, _, ModKind::Loaded(items, _inline, mod_spans)) = &item.kind {
let inject = mod_spans.inject_use_span;
if is_span_suitable_for_use_injection(inject) {
self.first_legal_span = Some(inject);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index bc8c8a444058d..953449c67581c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -2878,7 +2878,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// we check if `TraitB` can be reachable from `S`
// to determine whether to note `TraitA` is sealed trait.
if let ty::Adt(adt, _) = ty.kind() {
- let visibilities = tcx.effective_visibilities(());
+ let visibilities = &tcx.resolutions(()).effective_visibilities;
visibilities.effective_vis(local).is_none_or(|v| {
v.at_level(Level::Reexported)
.is_accessible_from(adt.did(), tcx)
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index b3a498570f95a..bb75ec74c8177 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -621,11 +621,11 @@ impl [T; N] {
/// assert_eq!(strings.len(), 3);
/// ```
#[stable(feature = "array_methods", since = "1.77.0")]
- #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")]
+ #[rustc_const_stable(feature = "const_array_each_ref", since = "CURRENT_RUSTC_VERSION")]
pub const fn each_ref(&self) -> [&T; N] {
let mut buf = [null::(); N];
- // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
+ // FIXME(const_trait_impl): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
let mut i = 0;
while i < N {
buf[i] = &raw const self[i];
@@ -652,11 +652,11 @@ impl [T; N] {
/// assert_eq!(floats, [0.0, 2.7, -1.0]);
/// ```
#[stable(feature = "array_methods", since = "1.77.0")]
- #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")]
+ #[rustc_const_stable(feature = "const_array_each_ref", since = "CURRENT_RUSTC_VERSION")]
pub const fn each_mut(&mut self) -> [&mut T; N] {
let mut buf = [null_mut::(); N];
- // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
+ // FIXME(const_trait_impl): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
let mut i = 0;
while i < N {
buf[i] = &raw mut self[i];
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index ae360df80f60b..98091e9fe83fb 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -34,53 +34,44 @@ where
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
#[cfg_attr(feature = "panic_immediate_abort", inline)]
#[track_caller]
-const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
- const_panic!(
- "slice start index is out of range for slice",
- "range start index {index} out of range for slice of length {len}",
- index: usize,
- len: usize,
- )
-}
+const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
+ if start > len {
+ const_panic!(
+ "slice start index is out of range for slice",
+ "range start index {start} out of range for slice of length {len}",
+ start: usize,
+ len: usize,
+ )
+ }
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[track_caller]
-const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
- const_panic!(
- "slice end index is out of range for slice",
- "range end index {index} out of range for slice of length {len}",
- index: usize,
- len: usize,
- )
-}
+ if end > len {
+ const_panic!(
+ "slice end index is out of range for slice",
+ "range end index {end} out of range for slice of length {len}",
+ end: usize,
+ len: usize,
+ )
+ }
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[track_caller]
-const fn slice_index_order_fail(index: usize, end: usize) -> ! {
+ if start > end {
+ const_panic!(
+ "slice index start is larger than end",
+ "slice index starts at {start} but ends at {end}",
+ start: usize,
+ end: usize,
+ )
+ }
+
+ // Only reachable if the range was a `RangeInclusive` or a
+ // `RangeToInclusive`, with `end == len`.
const_panic!(
- "slice index start is larger than end",
- "slice index starts at {index} but ends at {end}",
- index: usize,
+ "slice end index is out of range for slice",
+ "range end index {end} out of range for slice of length {len}",
end: usize,
+ len: usize,
)
}
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[track_caller]
-const fn slice_start_index_overflow_fail() -> ! {
- panic!("attempted to index slice from after maximum usize");
-}
-
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[track_caller]
-const fn slice_end_index_overflow_fail() -> ! {
- panic!("attempted to index slice up to maximum usize");
-}
-
// The UbChecks are great for catching bugs in the unsafe methods, but including
// them in safe indexing is unnecessary and hurts inlining and debug runtime perf.
// Both the safe and unsafe public methods share these helpers,
@@ -341,7 +332,7 @@ unsafe impl const SliceIndex<[T]> for ops::IndexRange {
// SAFETY: `self` is checked to be valid and in bounds above.
unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
} else {
- slice_end_index_len_fail(self.end(), slice.len())
+ slice_index_fail(self.start(), self.end(), slice.len())
}
}
@@ -351,7 +342,7 @@ unsafe impl const SliceIndex<[T]> for ops::IndexRange {
// SAFETY: `self` is checked to be valid and in bounds above.
unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
} else {
- slice_end_index_len_fail(self.end(), slice.len())
+ slice_index_fail(self.start(), self.end(), slice.len())
}
}
}
@@ -436,26 +427,27 @@ unsafe impl const SliceIndex<[T]> for ops::Range {
#[inline(always)]
fn index(self, slice: &[T]) -> &[T] {
// Using checked_sub is a safe way to get `SubUnchecked` in MIR
- let Some(new_len) = usize::checked_sub(self.end, self.start) else {
- slice_index_order_fail(self.start, self.end)
- };
- if self.end > slice.len() {
- slice_end_index_len_fail(self.end, slice.len());
+ if let Some(new_len) = usize::checked_sub(self.end, self.start)
+ && self.end <= slice.len()
+ {
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
+ } else {
+ slice_index_fail(self.start, self.end, slice.len())
}
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- let Some(new_len) = usize::checked_sub(self.end, self.start) else {
- slice_index_order_fail(self.start, self.end)
- };
- if self.end > slice.len() {
- slice_end_index_len_fail(self.end, slice.len());
+ // Using checked_sub is a safe way to get `SubUnchecked` in MIR
+ if let Some(new_len) = usize::checked_sub(self.end, self.start)
+ && self.end <= slice.len()
+ {
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
+ } else {
+ slice_index_fail(self.start, self.end, slice.len())
}
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
}
}
@@ -567,7 +559,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeFrom {
#[inline]
fn index(self, slice: &[T]) -> &[T] {
if self.start > slice.len() {
- slice_start_index_len_fail(self.start, slice.len());
+ slice_index_fail(self.start, slice.len(), slice.len())
}
// SAFETY: `self` is checked to be valid and in bounds above.
unsafe { &*self.get_unchecked(slice) }
@@ -576,7 +568,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeFrom {
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
if self.start > slice.len() {
- slice_start_index_len_fail(self.start, slice.len());
+ slice_index_fail(self.start, slice.len(), slice.len())
}
// SAFETY: `self` is checked to be valid and in bounds above.
unsafe { &mut *self.get_unchecked_mut(slice) }
@@ -690,18 +682,32 @@ unsafe impl const SliceIndex<[T]> for ops::RangeInclusive {
#[inline]
fn index(self, slice: &[T]) -> &[T] {
- if *self.end() == usize::MAX {
- slice_end_index_overflow_fail();
+ let Self { mut start, mut end, exhausted } = self;
+ let len = slice.len();
+ if end < len {
+ end = end + 1;
+ start = if exhausted { end } else { start };
+ if let Some(new_len) = usize::checked_sub(end, start) {
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
+ }
}
- self.into_slice_range().index(slice)
+ slice_index_fail(start, end, slice.len())
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- if *self.end() == usize::MAX {
- slice_end_index_overflow_fail();
+ let Self { mut start, mut end, exhausted } = self;
+ let len = slice.len();
+ if end < len {
+ end = end + 1;
+ start = if exhausted { end } else { start };
+ if let Some(new_len) = usize::checked_sub(end, start) {
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
+ }
}
- self.into_slice_range().index_mut(slice)
+ slice_index_fail(start, end, slice.len())
}
}
@@ -852,28 +858,26 @@ where
{
let len = bounds.end;
- let start = match range.start_bound() {
- ops::Bound::Included(&start) => start,
- ops::Bound::Excluded(start) => {
- start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
- }
- ops::Bound::Unbounded => 0,
- };
-
let end = match range.end_bound() {
- ops::Bound::Included(end) => {
- end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
- }
+ ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
+ // Cannot overflow because `end < len` implies `end < usize::MAX`.
+ ops::Bound::Included(&end) => end + 1,
+
+ ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
ops::Bound::Excluded(&end) => end,
ops::Bound::Unbounded => len,
};
- if start > end {
- slice_index_order_fail(start, end);
- }
- if end > len {
- slice_end_index_len_fail(end, len);
- }
+ let start = match range.start_bound() {
+ ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
+ // Cannot overflow because `start < end` implies `start < usize::MAX`.
+ ops::Bound::Excluded(&start) => start + 1,
+
+ ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
+ ops::Bound::Included(&start) => start,
+
+ ops::Bound::Unbounded => 0,
+ };
ops::Range { start, end }
}
@@ -982,25 +986,27 @@ pub(crate) fn into_slice_range(
len: usize,
(start, end): (ops::Bound, ops::Bound),
) -> ops::Range {
- use ops::Bound;
- let start = match start {
- Bound::Included(start) => start,
- Bound::Excluded(start) => {
- start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
- }
- Bound::Unbounded => 0,
- };
-
let end = match end {
- Bound::Included(end) => {
- end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
- }
- Bound::Excluded(end) => end,
- Bound::Unbounded => len,
+ ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
+ // Cannot overflow because `end < len` implies `end < usize::MAX`.
+ ops::Bound::Included(end) => end + 1,
+
+ ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
+ ops::Bound::Excluded(end) => end,
+
+ ops::Bound::Unbounded => len,
};
- // Don't bother with checking `start < end` and `end <= len`
- // since these checks are handled by `Range` impls
+ let start = match start {
+ ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
+ // Cannot overflow because `start < end` implies `start < usize::MAX`.
+ ops::Bound::Excluded(start) => start + 1,
+
+ ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
+ ops::Bound::Included(start) => start,
+
+ ops::Bound::Unbounded => 0,
+ };
start..end
}
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index ca668361ef63b..59ffe7ad49c05 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -125,7 +125,7 @@ impl Poll> {
}
}
- /// Maps a `Poll::Ready>` to `Poll::Ready>` by
+ /// Maps a `Poll::Ready>` to `Poll::Ready>` by
/// applying a function to a contained `Poll::Ready(Err)` value, leaving all other
/// variants untouched.
///
diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs
index 992f24cb18f20..110c4e5f3b406 100644
--- a/library/coretests/tests/slice.rs
+++ b/library/coretests/tests/slice.rs
@@ -1492,28 +1492,28 @@ mod slice_index {
// note: using 0 specifically ensures that the result of overflowing is 0..0,
// so that `get` doesn't simply return None for the wrong reason.
bad: data[0 ..= usize::MAX];
- message: "maximum usize";
+ message: "out of range";
}
in mod rangetoinclusive_overflow {
data: [0, 1];
bad: data[..= usize::MAX];
- message: "maximum usize";
+ message: "out of range";
}
in mod boundpair_overflow_end {
data: [0; 1];
bad: data[(Bound::Unbounded, Bound::Included(usize::MAX))];
- message: "maximum usize";
+ message: "out of range";
}
in mod boundpair_overflow_start {
data: [0; 1];
bad: data[(Bound::Excluded(usize::MAX), Bound::Unbounded)];
- message: "maximum usize";
+ message: "out of range";
}
} // panic_cases!
}
@@ -2008,7 +2008,7 @@ fn test_copy_within_panics_src_inverted() {
bytes.copy_within(2..1, 0);
}
#[test]
-#[should_panic(expected = "attempted to index slice up to maximum usize")]
+#[should_panic(expected = "out of range")]
fn test_copy_within_panics_src_out_of_bounds() {
let mut bytes = *b"Hello, World!";
// an inclusive range ending at usize::MAX would make src_end overflow
diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs
index 889ed3c538035..6104a02c739b5 100644
--- a/library/std/src/collections/mod.rs
+++ b/library/std/src/collections/mod.rs
@@ -26,7 +26,7 @@
//! should be considered. Detailed discussions of strengths and weaknesses of
//! individual collections can be found on their own documentation pages.
//!
-//! ### Use a `Vec` when:
+//! ### Use a [`Vec`] when:
//! * You want to collect items up to be processed or sent elsewhere later, and
//! don't care about any properties of the actual values being stored.
//! * You want a sequence of elements in a particular order, and will only be
@@ -35,25 +35,25 @@
//! * You want a resizable array.
//! * You want a heap-allocated array.
//!
-//! ### Use a `VecDeque` when:
+//! ### Use a [`VecDeque`] when:
//! * You want a [`Vec`] that supports efficient insertion at both ends of the
//! sequence.
//! * You want a queue.
//! * You want a double-ended queue (deque).
//!
-//! ### Use a `LinkedList` when:
+//! ### Use a [`LinkedList`] when:
//! * You want a [`Vec`] or [`VecDeque`] of unknown size, and can't tolerate
//! amortization.
//! * You want to efficiently split and append lists.
//! * You are *absolutely* certain you *really*, *truly*, want a doubly linked
//! list.
//!
-//! ### Use a `HashMap` when:
+//! ### Use a [`HashMap`] when:
//! * You want to associate arbitrary keys with an arbitrary value.
//! * You want a cache.
//! * You want a map, with no extra functionality.
//!
-//! ### Use a `BTreeMap` when:
+//! ### Use a [`BTreeMap`] when:
//! * You want a map sorted by its keys.
//! * You want to be able to get a range of entries on-demand.
//! * You're interested in what the smallest or largest key-value pair is.
@@ -65,7 +65,7 @@
//! * There is no meaningful value to associate with your keys.
//! * You just want a set.
//!
-//! ### Use a `BinaryHeap` when:
+//! ### Use a [`BinaryHeap`] when:
//!
//! * You want to store a bunch of elements, but only ever want to process the
//! "biggest" or "most important" one at any given time.
diff --git a/library/std_detect/src/detect/os/riscv.rs b/library/std_detect/src/detect/os/riscv.rs
index c6acbd3525bd3..9b9e0cba09d1c 100644
--- a/library/std_detect/src/detect/os/riscv.rs
+++ b/library/std_detect/src/detect/os/riscv.rs
@@ -119,11 +119,31 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize
imply!(d | zfhmin | zfa => f);
imply!(zfbfmin => f); // and some of (not all) "Zfh" instructions.
- // Relatively complex implication rules from the "C" extension.
+ // Relatively complex implication rules around the "C" extension.
+ // (from "C" and some others)
imply!(c => zca);
imply!(c & d => zcd);
#[cfg(target_arch = "riscv32")]
imply!(c & f => zcf);
+ // (to "C"; defined as superset)
+ cfg_select! {
+ target_arch = "riscv32" => {
+ if value.test(Feature::d as u32) {
+ imply!(zcf & zcd => c);
+ } else if value.test(Feature::f as u32) {
+ imply!(zcf => c);
+ } else {
+ imply!(zca => c);
+ }
+ }
+ _ => {
+ if value.test(Feature::d as u32) {
+ imply!(zcd => c);
+ } else {
+ imply!(zca => c);
+ }
+ }
+ }
imply!(zicntr | zihpm | f | zfinx | zve32x => zicsr);
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index 2b36b0f2e2717..77c9622a9bf0d 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -122,7 +122,7 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option {
// Download from upstream CI
- let root = ci_gcc_root(&builder.config);
+ let root = ci_gcc_root(&builder.config, target);
let gcc_stamp = BuildStamp::new(&root).with_prefix("gcc").add_stamp(&upstream);
if !gcc_stamp.is_up_to_date() && !builder.config.dry_run() {
builder.config.download_ci_gcc(&upstream, &root);
@@ -286,8 +286,8 @@ pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) {
/// The absolute path to the downloaded GCC artifacts.
#[cfg(not(test))]
-fn ci_gcc_root(config: &crate::Config) -> PathBuf {
- config.out.join(config.host_target).join("ci-gcc")
+fn ci_gcc_root(config: &crate::Config, target: TargetSelection) -> PathBuf {
+ config.out.join(target).join("ci-gcc")
}
/// Detect whether GCC sources have been modified locally or not.
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index e7a57a7f3755b..56e7582a6ffda 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1830,10 +1830,27 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--host").arg(&*compiler.host.triple);
cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));
- if let Some(codegen_backend) = builder.config.default_codegen_backend(compiler.host) {
- // Tells compiletest which codegen backend is used by default by the compiler.
+ if let Some(codegen_backend) = builder.config.cmd.test_codegen_backend() {
+ if !builder.config.enabled_codegen_backends(compiler.host).contains(codegen_backend) {
+ eprintln!(
+ "\
+ERROR: No configured backend named `{name}`
+HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?}]`",
+ name = codegen_backend.name(),
+ );
+ crate::exit!(1);
+ }
+ // Tells compiletest that we want to use this codegen in particular and to override
+ // the default one.
+ cmd.arg("--override-codegen-backend").arg(codegen_backend.name());
+ // Tells compiletest which codegen backend to use.
+ // It is used to e.g. ignore tests that don't support that codegen backend.
+ cmd.arg("--default-codegen-backend").arg(codegen_backend.name());
+ } else {
+ // Tells compiletest which codegen backend to use.
// It is used to e.g. ignore tests that don't support that codegen backend.
- cmd.arg("--codegen-backend").arg(codegen_backend.name());
+ cmd.arg("--default-codegen-backend")
+ .arg(builder.config.default_codegen_backend(compiler.host).unwrap().name());
}
if builder.build.config.llvm_enzyme {
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 69a744a86cb85..721924034123e 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -1326,7 +1326,12 @@ impl Builder<'_> {
if let Some(limit) = limit
&& (build_compiler_stage == 0
- || self.config.default_codegen_backend(target).unwrap_or_default().is_llvm())
+ || self
+ .config
+ .default_codegen_backend(target)
+ .cloned()
+ .unwrap_or_default()
+ .is_llvm())
{
rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={limit}"));
}
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 5eea54360238d..d0647537e5668 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1755,8 +1755,8 @@ impl Config {
/// Returns the codegen backend that should be configured as the *default* codegen backend
/// for a rustc compiled by bootstrap.
- pub fn default_codegen_backend(&self, target: TargetSelection) -> Option {
- self.enabled_codegen_backends(target).first().cloned()
+ pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<&CodegenBackendKind> {
+ self.enabled_codegen_backends(target).first()
}
pub fn jemalloc(&self, target: TargetSelection) -> bool {
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 17bfb388280a9..c01b71b926068 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -15,7 +15,7 @@ use crate::core::build_steps::setup::Profile;
use crate::core::builder::{Builder, Kind};
use crate::core::config::Config;
use crate::core::config::target_selection::{TargetSelectionList, target_selection_list};
-use crate::{Build, DocTests};
+use crate::{Build, CodegenBackendKind, DocTests};
#[derive(Copy, Clone, Default, Debug, ValueEnum)]
pub enum Color {
@@ -419,6 +419,9 @@ pub enum Subcommand {
#[arg(long)]
/// don't capture stdout/stderr of tests
no_capture: bool,
+ #[arg(long)]
+ /// Use a different codegen backend when running tests.
+ test_codegen_backend: Option,
},
/// Build and run some test suites *in Miri*
Miri {
@@ -658,6 +661,13 @@ impl Subcommand {
_ => vec![],
}
}
+
+ pub fn test_codegen_backend(&self) -> Option<&CodegenBackendKind> {
+ match self {
+ Subcommand::Test { test_codegen_backend, .. } => test_codegen_backend.as_ref(),
+ _ => None,
+ }
+ }
}
/// Returns the shell completion for a given shell, if the result differs from the current
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 8f766ed00a5be..ec7edbf753129 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -165,6 +165,20 @@ impl CodegenBackendKind {
}
}
+impl std::str::FromStr for CodegenBackendKind {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result {
+ match s.to_lowercase().as_str() {
+ "" => Err("Invalid empty backend name"),
+ "gcc" => Ok(Self::Gcc),
+ "llvm" => Ok(Self::Llvm),
+ "cranelift" => Ok(Self::Cranelift),
+ _ => Ok(Self::Custom(s.to_string())),
+ }
+ }
+}
+
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum DocTests {
/// Run normal tests and doc tests (default).
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index b2f9960a4492a..4fb5891ed181a 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -506,6 +506,11 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Warning,
summary: "It is no longer possible to `x clippy` with stage 0. All clippy commands have to be on stage 1+.",
},
+ ChangeInfo {
+ change_id: 145256,
+ severity: ChangeSeverity::Info,
+ summary: "Added `--test-codegen-backend` CLI option for tests",
+ },
ChangeInfo {
change_id: 145379,
severity: ChangeSeverity::Info,
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index 0b9af33421461..544f9b97237cb 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -305,6 +305,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-sepa
complete -c x -n "__fish_x_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
complete -c x -n "__fish_x_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
complete -c x -n "__fish_x_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
+complete -c x -n "__fish_x_using_subcommand test" -l test-codegen-backend -d 'Use a different codegen backend when running tests' -r
complete -c x -n "__fish_x_using_subcommand test" -l config -d 'TOML configuration file for build' -r -F
complete -c x -n "__fish_x_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
complete -c x -n "__fish_x_using_subcommand test" -l build -d 'host target of the stage0 compiler' -r -f
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index 95cee4b633625..b03acf930f70d 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -351,6 +351,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
[CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
[CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
[CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
+ [CompletionResult]::new('--test-codegen-backend', '--test-codegen-backend', [CompletionResultType]::ParameterName, 'Use a different codegen backend when running tests')
[CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
[CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
[CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler')
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 6fba6a4562368..08e4cd26ce887 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -305,6 +305,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comm
complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
+complete -c x.py -n "__fish_x.py_using_subcommand test" -l test-codegen-backend -d 'Use a different codegen backend when running tests' -r
complete -c x.py -n "__fish_x.py_using_subcommand test" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_x.py_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
complete -c x.py -n "__fish_x.py_using_subcommand test" -l build -d 'host target of the stage0 compiler' -r -f
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 458879a17a7b9..3d95d88af4955 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -351,6 +351,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
[CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
[CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
+ [CompletionResult]::new('--test-codegen-backend', '--test-codegen-backend', [CompletionResultType]::ParameterName, 'Use a different codegen backend when running tests')
[CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
[CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
[CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index e003bf7fd0b43..8ff0eaf35c89a 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -3875,7 +3875,7 @@ _x.py() {
return 0
;;
x.py__test)
- opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
+ opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@@ -3905,6 +3905,10 @@ _x.py() {
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
+ --test-codegen-backend)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
--config)
local oldifs
if [ -n "${IFS+x}" ]; then
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index b82c2d65e8694..9d2d73e582ec6 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -351,6 +351,7 @@ _arguments "${_arguments_options[@]}" : \
'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
'--run=[whether to execute run-* tests]:auto | always | never:_default' \
+'--test-codegen-backend=[Use a different codegen backend when running tests]:TEST_CODEGEN_BACKEND:_default' \
'--config=[TOML configuration file for build]:FILE:_files' \
'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
'--build=[host target of the stage0 compiler]:BUILD:' \
diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh
index c2cb771002017..c1b73fb7c9e34 100644
--- a/src/etc/completions/x.sh
+++ b/src/etc/completions/x.sh
@@ -3875,7 +3875,7 @@ _x() {
return 0
;;
x__test)
- opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
+ opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@@ -3905,6 +3905,10 @@ _x() {
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
+ --test-codegen-backend)
+ COMPREPLY=($(compgen -f "${cur}"))
+ return 0
+ ;;
--config)
local oldifs
if [ -n "${IFS+x}" ]; then
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index 49139e70f7fb2..29237ef9bf8fd 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -351,6 +351,7 @@ _arguments "${_arguments_options[@]}" : \
'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
'--run=[whether to execute run-* tests]:auto | always | never:_default' \
+'--test-codegen-backend=[Use a different codegen backend when running tests]:TEST_CODEGEN_BACKEND:_default' \
'--config=[TOML configuration file for build]:FILE:_files' \
'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
'--build=[host target of the stage0 compiler]:BUILD:' \
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index d55208150b843..42b87d562529b 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -5252,7 +5252,7 @@ if (typeof window !== "undefined") {
},
loadTreeByHash: hashHex => {
const script = document.createElement("script");
- script.src = `${ROOT_PATH}/search.index/${hashHex}.js`;
+ script.src = `${ROOT_PATH}search.index/${hashHex}.js`;
script.onerror = e => {
if (databaseCallbacks) {
databaseCallbacks.err_rn_(hashHex, e);
@@ -5262,7 +5262,7 @@ if (typeof window !== "undefined") {
},
loadDataByNameAndHash: (name, hashHex) => {
const script = document.createElement("script");
- script.src = `${ROOT_PATH}/search.index/${name}/${hashHex}.js`;
+ script.src = `${ROOT_PATH}search.index/${name}/${hashHex}.js`;
script.onerror = e => {
if (databaseCallbacks) {
databaseCallbacks.err_rd_(hashHex, e);
diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
index ce551a64d9984..759b7b6837bd5 100644
--- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
+++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
@@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
impl EarlyLintPass for DuplicateMod {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
+ if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No { .. }, mod_spans)) = &item.kind
&& let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
&& let Some(local_path) = real.into_local_path()
&& let Ok(absolute_path) = local_path.canonicalize()
diff --git a/src/tools/clippy/clippy_lints/src/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
index 3bd74856165da..76e67b1154be1 100644
--- a/src/tools/clippy/clippy_lints/src/empty_line_after.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
@@ -442,7 +442,7 @@ impl EmptyLineAfter {
None => span.shrink_to_lo(),
},
mod_items: match kind {
- ItemKind::Mod(_, _, ModKind::Loaded(items, _, _, _)) => items
+ ItemKind::Mod(_, _, ModKind::Loaded(items, _, _)) => items
.iter()
.filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
.map(|i| i.id)
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index 1d3ae89494414..5368701c30416 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -164,7 +164,7 @@ impl Visitor<'_> for NestingVisitor<'_, '_> {
}
match &item.kind {
- ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _, _)) => {
+ ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => {
self.nest_level += 1;
if !self.check_indent(item.span, item.id) {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 24e017f7cf7de..d80a9d9dd07d8 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -403,7 +403,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
ls == rs
&& eq_id(*li, *ri)
&& match (lmk, rmk) {
- (ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => {
+ (ModKind::Loaded(litems, linline, _), ModKind::Loaded(ritems, rinline, _)) => {
linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind))
},
(ModKind::Unloaded, ModKind::Unloaded) => true,
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 2d49b1a7097d0..7fc80c1edb158 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -692,7 +692,9 @@ pub struct Config {
pub minicore_path: Utf8PathBuf,
/// Current codegen backend used.
- pub codegen_backend: CodegenBackend,
+ pub default_codegen_backend: CodegenBackend,
+ /// Name/path of the backend to use instead of `default_codegen_backend`.
+ pub override_codegen_backend: Option,
}
impl Config {
@@ -796,7 +798,8 @@ impl Config {
profiler_runtime: Default::default(),
diff_command: Default::default(),
minicore_path: Default::default(),
- codegen_backend: CodegenBackend::Llvm,
+ default_codegen_backend: CodegenBackend::Llvm,
+ override_codegen_backend: None,
}
}
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index 13e694b7f03ca..00007aa1d6683 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -1624,7 +1624,7 @@ fn ignore_backends(
}
}
}) {
- if config.codegen_backend == backend {
+ if config.default_codegen_backend == backend {
return IgnoreDecision::Ignore {
reason: format!("{} backend is marked as ignore", backend.as_str()),
};
@@ -1651,12 +1651,12 @@ fn needs_backends(
panic!("Invalid needs-backends value `{backend}` in `{path}`: {error}")
}
})
- .any(|backend| config.codegen_backend == backend)
+ .any(|backend| config.default_codegen_backend == backend)
{
return IgnoreDecision::Ignore {
reason: format!(
"{} backend is not part of required backends",
- config.codegen_backend.as_str()
+ config.default_codegen_backend.as_str()
),
};
}
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index f5409e783418b..469dd68207edc 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -212,9 +212,15 @@ pub fn parse_config(args: Vec) -> Config {
)
.optopt(
"",
- "codegen-backend",
+ "default-codegen-backend",
"the codegen backend currently used",
"CODEGEN BACKEND NAME",
+ )
+ .optopt(
+ "",
+ "override-codegen-backend",
+ "the codegen backend to use instead of the default one",
+ "CODEGEN BACKEND [NAME | PATH]",
);
let (argv0, args_) = args.split_first().unwrap();
@@ -276,14 +282,17 @@ pub fn parse_config(args: Vec) -> Config {
|| directives::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?),
);
- let codegen_backend = match matches.opt_str("codegen-backend").as_deref() {
+ let default_codegen_backend = match matches.opt_str("default-codegen-backend").as_deref() {
Some(backend) => match CodegenBackend::try_from(backend) {
Ok(backend) => backend,
- Err(error) => panic!("invalid value `{backend}` for `--codegen-backend`: {error}"),
+ Err(error) => {
+ panic!("invalid value `{backend}` for `--defalt-codegen-backend`: {error}")
+ }
},
// By default, it's always llvm.
None => CodegenBackend::Llvm,
};
+ let override_codegen_backend = matches.opt_str("override-codegen-backend");
let run_ignored = matches.opt_present("ignored");
let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions");
@@ -472,7 +481,8 @@ pub fn parse_config(args: Vec) -> Config {
minicore_path: opt_path(matches, "minicore-path"),
- codegen_backend,
+ default_codegen_backend,
+ override_codegen_backend,
}
}
@@ -812,13 +822,13 @@ fn collect_tests_from_dir(
&& let Some(Utf8Component::Normal(parent)) = components.next()
&& parent == "tests"
&& let Ok(backend) = CodegenBackend::try_from(backend)
- && backend != cx.config.codegen_backend
+ && backend != cx.config.default_codegen_backend
{
// We ignore asm tests which don't match the current codegen backend.
warning!(
"Ignoring tests in `{dir}` because they don't match the configured codegen \
backend (`{}`)",
- cx.config.codegen_backend.as_str(),
+ cx.config.default_codegen_backend.as_str(),
);
return Ok(TestCollector::new());
}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 821cb12864764..2402ed9a950f2 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1558,6 +1558,11 @@ impl<'test> TestCx<'test> {
rustc.arg("--sysroot").arg(&self.config.sysroot_base);
}
+ // If the provided codegen backend is not LLVM, we need to pass it.
+ if let Some(ref backend) = self.config.override_codegen_backend {
+ rustc.arg(format!("-Zcodegen-backend={}", backend));
+ }
+
// Optionally prevent default --target if specified in test compile-flags.
let custom_target = self.props.compile_flags.iter().any(|x| x.starts_with("--target"));
diff --git a/src/tools/miri/tests/panic/oob_subslice.stderr b/src/tools/miri/tests/panic/oob_subslice.stderr
index f8270f4ad4de1..e1e5bd33d311b 100644
--- a/src/tools/miri/tests/panic/oob_subslice.stderr
+++ b/src/tools/miri/tests/panic/oob_subslice.stderr
@@ -1,5 +1,5 @@
thread 'main' ($TID) panicked at tests/panic/oob_subslice.rs:LL:CC:
-range end index 5 out of range for slice of length 4
+range end index 4 out of range for slice of length 4
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 10df6f9670263..6555679c39448 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -3600,7 +3600,7 @@ pub(crate) fn rewrite_extern_crate(
pub(crate) fn is_mod_decl(item: &ast::Item) -> bool {
!matches!(
item.kind,
- ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _))
+ ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _))
)
}
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index 3bc656b64b3a1..af9feccb32e2f 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -316,11 +316,12 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
self.directory = directory;
}
match (sub_mod.ast_mod_kind, sub_mod.items) {
- (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _, _))), _) => {
+ (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => {
self.visit_mod_from_ast(items)
}
- (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _, _))), _)
- | (_, Cow::Owned(items)) => self.visit_mod_outside_ast(items),
+ (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => {
+ self.visit_mod_outside_ast(items)
+ }
(_, _) => Ok(()),
}
}
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index 23d07c930d905..a3acbb218ff29 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -942,7 +942,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let ident_str = rewrite_ident(&self.get_context(), ident).to_owned();
self.push_str(&ident_str);
- if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans, _) = mod_kind {
+ if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans) = mod_kind {
let ast::ModSpans {
inner_span,
inject_use_span: _,
diff --git a/tests/codegen-llvm/abi-x86-interrupt.rs b/tests/codegen-llvm/abi-x86-interrupt.rs
index 9a1ded2c9e372..b5c495803d898 100644
--- a/tests/codegen-llvm/abi-x86-interrupt.rs
+++ b/tests/codegen-llvm/abi-x86-interrupt.rs
@@ -15,4 +15,4 @@ use minicore::*;
// CHECK: define x86_intrcc void @has_x86_interrupt_abi
#[no_mangle]
-pub extern "x86-interrupt" fn has_x86_interrupt_abi() {}
+pub extern "x86-interrupt" fn has_x86_interrupt_abi(_p: *const u8) {}
diff --git a/tests/codegen-llvm/binary-search-index-no-bound-check.rs b/tests/codegen-llvm/binary-search-index-no-bound-check.rs
index d59c0beec6419..8322c4179bd14 100644
--- a/tests/codegen-llvm/binary-search-index-no-bound-check.rs
+++ b/tests/codegen-llvm/binary-search-index-no-bound-check.rs
@@ -8,8 +8,7 @@
#[no_mangle]
pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
if let Ok(idx) = s.binary_search(&b'\\') { s[idx] } else { 42 }
}
diff --git a/tests/codegen-llvm/integer-overflow.rs b/tests/codegen-llvm/integer-overflow.rs
index 80362247a86f1..df7845be06d17 100644
--- a/tests/codegen-llvm/integer-overflow.rs
+++ b/tests/codegen-llvm/integer-overflow.rs
@@ -10,7 +10,7 @@ pub struct S1<'a> {
// CHECK-LABEL: @slice_no_index_order
#[no_mangle]
pub fn slice_no_index_order<'a>(s: &'a mut S1, n: usize) -> &'a [u8] {
- // CHECK-NOT: slice_index_order_fail
+ // CHECK-COUNT-1: slice_index_fail
let d = &s.data[s.position..s.position + n];
s.position += n;
return d;
@@ -19,6 +19,6 @@ pub fn slice_no_index_order<'a>(s: &'a mut S1, n: usize) -> &'a [u8] {
// CHECK-LABEL: @test_check
#[no_mangle]
pub fn test_check<'a>(s: &'a mut S1, x: usize, y: usize) -> &'a [u8] {
- // CHECK: slice_index_order_fail
+ // CHECK-COUNT-1: slice_index_fail
&s.data[x..y]
}
diff --git a/tests/codegen-llvm/issues/issue-113757-bounds-check-after-cmp-max.rs b/tests/codegen-llvm/issues/issue-113757-bounds-check-after-cmp-max.rs
index d495adf99804c..0db8a5220ec5b 100644
--- a/tests/codegen-llvm/issues/issue-113757-bounds-check-after-cmp-max.rs
+++ b/tests/codegen-llvm/issues/issue-113757-bounds-check-after-cmp-max.rs
@@ -5,7 +5,7 @@
use std::cmp::max;
// CHECK-LABEL: @foo
-// CHECK-NOT: slice_start_index_len_fail
+// CHECK-NOT: slice_index_fail
// CHECK-NOT: unreachable
#[no_mangle]
pub fn foo(v: &mut Vec, size: usize) -> Option<&mut [u8]> {
diff --git a/tests/codegen-llvm/issues/issue-27130.rs b/tests/codegen-llvm/issues/issue-27130.rs
index 594e02af0977f..3e53c5cffd666 100644
--- a/tests/codegen-llvm/issues/issue-27130.rs
+++ b/tests/codegen-llvm/issues/issue-27130.rs
@@ -6,7 +6,7 @@
#[no_mangle]
pub fn trim_in_place(a: &mut &[u8]) {
while a.first() == Some(&42) {
- // CHECK-NOT: slice_index_order_fail
+ // CHECK-NOT: slice_index_fail
*a = &a[1..];
}
}
@@ -15,7 +15,7 @@ pub fn trim_in_place(a: &mut &[u8]) {
#[no_mangle]
pub fn trim_in_place2(a: &mut &[u8]) {
while let Some(&42) = a.first() {
- // CHECK-NOT: slice_index_order_fail
+ // CHECK-COUNT-1: slice_index_fail
*a = &a[2..];
}
}
diff --git a/tests/codegen-llvm/issues/issue-69101-bounds-check.rs b/tests/codegen-llvm/issues/issue-69101-bounds-check.rs
index 953b79aa263e8..f1857a9ce89d2 100644
--- a/tests/codegen-llvm/issues/issue-69101-bounds-check.rs
+++ b/tests/codegen-llvm/issues/issue-69101-bounds-check.rs
@@ -10,7 +10,7 @@
// CHECK-LABEL: @already_sliced_no_bounds_check
#[no_mangle]
pub fn already_sliced_no_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
- // CHECK: slice_end_index_len_fail
+ // CHECK: slice_index_fail
// CHECK-NOT: panic_bounds_check
let _ = (&a[..2048], &b[..2048], &mut c[..2048]);
for i in 0..1024 {
@@ -21,7 +21,7 @@ pub fn already_sliced_no_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK-LABEL: @already_sliced_no_bounds_check_exact
#[no_mangle]
pub fn already_sliced_no_bounds_check_exact(a: &[u8], b: &[u8], c: &mut [u8]) {
- // CHECK: slice_end_index_len_fail
+ // CHECK: slice_index_fail
// CHECK-NOT: panic_bounds_check
let _ = (&a[..1024], &b[..1024], &mut c[..1024]);
for i in 0..1024 {
@@ -33,7 +33,7 @@ pub fn already_sliced_no_bounds_check_exact(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK-LABEL: @already_sliced_bounds_check
#[no_mangle]
pub fn already_sliced_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
- // CHECK: slice_end_index_len_fail
+ // CHECK: slice_index_fail
// CHECK: panic_bounds_check
let _ = (&a[..1023], &b[..2048], &mut c[..2048]);
for i in 0..1024 {
diff --git a/tests/codegen-llvm/issues/issue-73396-bounds-check-after-position.rs b/tests/codegen-llvm/issues/issue-73396-bounds-check-after-position.rs
index 1e2c25babe0a5..8a2200478aa08 100644
--- a/tests/codegen-llvm/issues/issue-73396-bounds-check-after-position.rs
+++ b/tests/codegen-llvm/issues/issue-73396-bounds-check-after-position.rs
@@ -8,8 +8,7 @@
#[no_mangle]
pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
// CHECK-NOT: unreachable
if let Some(idx) = s.iter().position(|b| *b == b'\\') { &s[..idx] } else { s }
@@ -19,8 +18,7 @@ pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
// CHECK-NOT: unreachable
if let Some(idx) = s.iter().position(|b| *b == b'\\') { &s[idx..] } else { s }
@@ -30,8 +28,7 @@ pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn position_index_no_bounds_check(s: &[u8]) -> u8 {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
// CHECK-NOT: unreachable
if let Some(idx) = s.iter().position(|b| *b == b'\\') { s[idx] } else { 42 }
@@ -40,8 +37,7 @@ pub fn position_index_no_bounds_check(s: &[u8]) -> u8 {
#[no_mangle]
pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
// CHECK-NOT: unreachable
if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { &s[..idx] } else { s }
@@ -51,8 +47,7 @@ pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
// CHECK-NOT: unreachable
if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { &s[idx..] } else { s }
@@ -62,8 +57,7 @@ pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn rposition_index_no_bounds_check(s: &[u8]) -> u8 {
// CHECK-NOT: panic
- // CHECK-NOT: slice_start_index_len_fail
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: panic_bounds_check
// CHECK-NOT: unreachable
if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { s[idx] } else { 42 }
diff --git a/tests/codegen-llvm/naked-asan.rs b/tests/codegen-llvm/naked-asan.rs
index 46218cf79d6df..a57e55d1366c3 100644
--- a/tests/codegen-llvm/naked-asan.rs
+++ b/tests/codegen-llvm/naked-asan.rs
@@ -18,10 +18,10 @@ pub fn caller() {
unsafe { asm!("call {}", sym page_fault_handler) }
}
-// CHECK: declare x86_intrcc void @page_fault_handler(){{.*}}#[[ATTRS:[0-9]+]]
+// CHECK: declare x86_intrcc void @page_fault_handler(ptr {{.*}}, i64{{.*}}){{.*}}#[[ATTRS:[0-9]+]]
#[unsafe(naked)]
#[no_mangle]
-pub extern "x86-interrupt" fn page_fault_handler() {
+pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
naked_asm!("ud2")
}
diff --git a/tests/codegen-llvm/slice-last-elements-optimization.rs b/tests/codegen-llvm/slice-last-elements-optimization.rs
index b90f91d7b17b9..d982cda709d47 100644
--- a/tests/codegen-llvm/slice-last-elements-optimization.rs
+++ b/tests/codegen-llvm/slice-last-elements-optimization.rs
@@ -1,19 +1,18 @@
//@ compile-flags: -Copt-level=3
-//@ only-x86_64
//@ min-llvm-version: 20
#![crate_type = "lib"]
// This test verifies that LLVM 20 properly optimizes the bounds check
// when accessing the last few elements of a slice with proper conditions.
// Previously, this would generate an unreachable branch to
-// slice_start_index_len_fail even when the bounds check was provably safe.
+// slice_index_fail even when the bounds check was provably safe.
// CHECK-LABEL: @last_four_initial(
#[no_mangle]
pub fn last_four_initial(s: &[u8]) -> &[u8] {
- // Previously this would generate a branch to slice_start_index_len_fail
+ // Previously this would generate a branch to slice_index_fail
// that is unreachable. The LLVM 20 fix should eliminate this branch.
- // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: unreachable
let start = if s.len() <= 4 { 0 } else { s.len() - 4 };
&s[start..]
@@ -23,7 +22,7 @@ pub fn last_four_initial(s: &[u8]) -> &[u8] {
#[no_mangle]
pub fn last_four_optimized(s: &[u8]) -> &[u8] {
// This version was already correctly optimized before the fix in LLVM 20.
- // CHECK-NOT: slice_start_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK-NOT: unreachable
if s.len() <= 4 { &s[0..] } else { &s[s.len() - 4..] }
}
@@ -32,6 +31,6 @@ pub fn last_four_optimized(s: &[u8]) -> &[u8] {
// CHECK-LABEL: @test_bounds_check_happens(
#[no_mangle]
pub fn test_bounds_check_happens(s: &[u8], i: usize) -> &[u8] {
- // CHECK: slice_start_index_len_fail
+ // CHECK: slice_index_fail
&s[i..]
}
diff --git a/tests/codegen-llvm/slice-reverse.rs b/tests/codegen-llvm/slice-reverse.rs
index e58d1c1d9d8ea..c31cff5010b4e 100644
--- a/tests/codegen-llvm/slice-reverse.rs
+++ b/tests/codegen-llvm/slice-reverse.rs
@@ -8,10 +8,10 @@
#[no_mangle]
pub fn slice_reverse_u8(slice: &mut [u8]) {
// CHECK-NOT: panic_bounds_check
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK: shufflevector <{{[0-9]+}} x i8>
// CHECK-NOT: panic_bounds_check
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
slice.reverse();
}
@@ -19,9 +19,9 @@ pub fn slice_reverse_u8(slice: &mut [u8]) {
#[no_mangle]
pub fn slice_reverse_i32(slice: &mut [i32]) {
// CHECK-NOT: panic_bounds_check
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
// CHECK: shufflevector <{{[0-9]+}} x i32>
// CHECK-NOT: panic_bounds_check
- // CHECK-NOT: slice_end_index_len_fail
+ // CHECK-NOT: slice_index_fail
slice.reverse();
}
diff --git a/tests/debuginfo/recursive-struct.rs b/tests/debuginfo/recursive-struct.rs
index 5be909928480f..427a7100a4f78 100644
--- a/tests/debuginfo/recursive-struct.rs
+++ b/tests/debuginfo/recursive-struct.rs
@@ -62,6 +62,7 @@
use self::Opt::{Empty, Val};
use std::boxed::Box as B;
+use std::marker::PhantomData;
enum Opt {
Empty,
@@ -98,6 +99,11 @@ struct LongCycleWithAnonymousTypes {
value: usize,
}
+struct Expanding {
+ a: PhantomData,
+ b: *const Expanding<(T, T)>,
+}
+
// This test case makes sure that recursive structs are properly described. The Node structs are
// generic so that we can have a new type (that newly needs to be described) for the different
// cases. The potential problem with recursive types is that the DI generation algorithm gets
@@ -205,6 +211,9 @@ fn main() {
value: 30
})))));
+ // This type can generate new instances infinitely if not handled properly.
+ std::hint::black_box(Expanding::<()> { a: PhantomData, b: std::ptr::null() });
+
zzz(); // #break
}
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
index d879d06bb4e47..d4b86b9633acd 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
@@ -4,14 +4,81 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range) -> &[u32] {
debug slice => _1;
debug index => _2;
let mut _0: &[u32];
+ let mut _3: usize;
+ let mut _4: usize;
scope 1 (inlined #[track_caller] core::slice::index::> for [u32]>::index) {
+ scope 2 (inlined #[track_caller] as SliceIndex<[u32]>>::index) {
+ let mut _7: usize;
+ let mut _8: bool;
+ let mut _9: *const [u32];
+ let _12: *const [u32];
+ let mut _13: usize;
+ let mut _14: !;
+ scope 3 (inlined core::num::::checked_sub) {
+ let mut _5: bool;
+ let mut _6: usize;
+ }
+ scope 4 (inlined core::slice::index::get_offset_len_noubcheck::) {
+ let _10: *const u32;
+ scope 5 {
+ let _11: *const u32;
+ scope 6 {
+ }
+ }
+ }
+ }
}
bb0: {
- _0 = as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind continue];
+ _3 = move (_2.0: usize);
+ _4 = move (_2.1: usize);
+ StorageLive(_5);
+ _5 = Lt(copy _4, copy _3);
+ switchInt(move _5) -> [0: bb1, otherwise: bb4];
}
bb1: {
+ _6 = SubUnchecked(copy _4, copy _3);
+ StorageDead(_5);
+ StorageLive(_8);
+ StorageLive(_7);
+ _7 = PtrMetadata(copy _1);
+ _8 = Le(copy _4, move _7);
+ switchInt(move _8) -> [0: bb2, otherwise: bb3];
+ }
+
+ bb2: {
+ StorageDead(_7);
+ goto -> bb5;
+ }
+
+ bb3: {
+ StorageDead(_7);
+ StorageLive(_12);
+ StorageLive(_9);
+ _9 = &raw const (*_1);
+ StorageLive(_10);
+ StorageLive(_11);
+ _10 = copy _9 as *const u32 (PtrToPtr);
+ _11 = Offset(copy _10, copy _3);
+ _12 = *const [u32] from (copy _11, copy _6);
+ StorageDead(_11);
+ StorageDead(_10);
+ StorageDead(_9);
+ _0 = &(*_12);
+ StorageDead(_12);
+ StorageDead(_8);
return;
}
+
+ bb4: {
+ StorageDead(_5);
+ goto -> bb5;
+ }
+
+ bb5: {
+ StorageLive(_13);
+ _13 = PtrMetadata(copy _1);
+ _14 = core::slice::index::slice_index_fail(move _3, move _4, move _13) -> unwind continue;
+ }
}
diff --git a/tests/ui/abi/cannot-be-called.avr.stderr b/tests/ui/abi/cannot-be-called.avr.stderr
index 1129893cbfaf5..ed3fa4a20c5da 100644
--- a/tests/ui/abi/cannot-be-called.avr.stderr
+++ b/tests/ui/abi/cannot-be-called.avr.stderr
@@ -19,53 +19,53 @@ LL | extern "riscv-interrupt-s" fn riscv_s() {}
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
--> $DIR/cannot-be-called.rs:45:8
|
-LL | extern "x86-interrupt" fn x86() {}
+LL | extern "x86-interrupt" fn x86(_x: *const u8) {}
| ^^^^^^^^^^^^^^^
error[E0570]: "msp430-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:70:25
+ --> $DIR/cannot-be-called.rs:72:25
|
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
| ^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:76:26
+ --> $DIR/cannot-be-called.rs:78:26
|
LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:82:26
+ --> $DIR/cannot-be-called.rs:84:26
|
LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:88:22
+ --> $DIR/cannot-be-called.rs:90:22
|
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error: functions with the "avr-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:50:5
+ --> $DIR/cannot-be-called.rs:52:5
|
LL | avr();
| ^^^^^
|
note: an `extern "avr-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:50:5
+ --> $DIR/cannot-be-called.rs:52:5
|
LL | avr();
| ^^^^^
error: functions with the "avr-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:66:5
+ --> $DIR/cannot-be-called.rs:68:5
|
LL | f()
| ^^^
|
note: an `extern "avr-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:66:5
+ --> $DIR/cannot-be-called.rs:68:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-called.i686.stderr b/tests/ui/abi/cannot-be-called.i686.stderr
index 024d5e2e93d6f..6ccb10c44fdf9 100644
--- a/tests/ui/abi/cannot-be-called.i686.stderr
+++ b/tests/ui/abi/cannot-be-called.i686.stderr
@@ -23,49 +23,49 @@ LL | extern "riscv-interrupt-s" fn riscv_s() {}
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "avr-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:64:22
+ --> $DIR/cannot-be-called.rs:66:22
|
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error[E0570]: "msp430-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:70:25
+ --> $DIR/cannot-be-called.rs:72:25
|
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
| ^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:76:26
+ --> $DIR/cannot-be-called.rs:78:26
|
LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:82:26
+ --> $DIR/cannot-be-called.rs:84:26
|
LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error: functions with the "x86-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:58:5
+ --> $DIR/cannot-be-called.rs:60:5
|
-LL | x86();
- | ^^^^^
+LL | x86(&raw const BYTE);
+ | ^^^^^^^^^^^^^^^^^^^^
|
note: an `extern "x86-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:58:5
+ --> $DIR/cannot-be-called.rs:60:5
|
-LL | x86();
- | ^^^^^
+LL | x86(&raw const BYTE);
+ | ^^^^^^^^^^^^^^^^^^^^
error: functions with the "x86-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:90:5
+ --> $DIR/cannot-be-called.rs:92:5
|
LL | f()
| ^^^
|
note: an `extern "x86-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:90:5
+ --> $DIR/cannot-be-called.rs:92:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-called.msp430.stderr b/tests/ui/abi/cannot-be-called.msp430.stderr
index 52d7d792510e0..0bd5bb40b715a 100644
--- a/tests/ui/abi/cannot-be-called.msp430.stderr
+++ b/tests/ui/abi/cannot-be-called.msp430.stderr
@@ -19,53 +19,53 @@ LL | extern "riscv-interrupt-s" fn riscv_s() {}
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
--> $DIR/cannot-be-called.rs:45:8
|
-LL | extern "x86-interrupt" fn x86() {}
+LL | extern "x86-interrupt" fn x86(_x: *const u8) {}
| ^^^^^^^^^^^^^^^
error[E0570]: "avr-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:64:22
+ --> $DIR/cannot-be-called.rs:66:22
|
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:76:26
+ --> $DIR/cannot-be-called.rs:78:26
|
LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:82:26
+ --> $DIR/cannot-be-called.rs:84:26
|
LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:88:22
+ --> $DIR/cannot-be-called.rs:90:22
|
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error: functions with the "msp430-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:52:5
+ --> $DIR/cannot-be-called.rs:54:5
|
LL | msp430();
| ^^^^^^^^
|
note: an `extern "msp430-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:52:5
+ --> $DIR/cannot-be-called.rs:54:5
|
LL | msp430();
| ^^^^^^^^
error: functions with the "msp430-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:72:5
+ --> $DIR/cannot-be-called.rs:74:5
|
LL | f()
| ^^^
|
note: an `extern "msp430-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:72:5
+ --> $DIR/cannot-be-called.rs:74:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-called.riscv32.stderr b/tests/ui/abi/cannot-be-called.riscv32.stderr
index 119d93bd58e92..6d763bd63796b 100644
--- a/tests/ui/abi/cannot-be-called.riscv32.stderr
+++ b/tests/ui/abi/cannot-be-called.riscv32.stderr
@@ -13,71 +13,71 @@ LL | extern "avr-interrupt" fn avr() {}
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
--> $DIR/cannot-be-called.rs:45:8
|
-LL | extern "x86-interrupt" fn x86() {}
+LL | extern "x86-interrupt" fn x86(_x: *const u8) {}
| ^^^^^^^^^^^^^^^
error[E0570]: "avr-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:64:22
+ --> $DIR/cannot-be-called.rs:66:22
|
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error[E0570]: "msp430-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:70:25
+ --> $DIR/cannot-be-called.rs:72:25
|
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
| ^^^^^^^^^^^^^^^^^^
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:88:22
+ --> $DIR/cannot-be-called.rs:90:22
|
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error: functions with the "riscv-interrupt-m" ABI cannot be called
- --> $DIR/cannot-be-called.rs:54:5
+ --> $DIR/cannot-be-called.rs:56:5
|
LL | riscv_m();
| ^^^^^^^^^
|
note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:54:5
+ --> $DIR/cannot-be-called.rs:56:5
|
LL | riscv_m();
| ^^^^^^^^^
error: functions with the "riscv-interrupt-s" ABI cannot be called
- --> $DIR/cannot-be-called.rs:56:5
+ --> $DIR/cannot-be-called.rs:58:5
|
LL | riscv_s();
| ^^^^^^^^^
|
note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:56:5
+ --> $DIR/cannot-be-called.rs:58:5
|
LL | riscv_s();
| ^^^^^^^^^
error: functions with the "riscv-interrupt-m" ABI cannot be called
- --> $DIR/cannot-be-called.rs:78:5
+ --> $DIR/cannot-be-called.rs:80:5
|
LL | f()
| ^^^
|
note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:78:5
+ --> $DIR/cannot-be-called.rs:80:5
|
LL | f()
| ^^^
error: functions with the "riscv-interrupt-s" ABI cannot be called
- --> $DIR/cannot-be-called.rs:84:5
+ --> $DIR/cannot-be-called.rs:86:5
|
LL | f()
| ^^^
|
note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:84:5
+ --> $DIR/cannot-be-called.rs:86:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-called.riscv64.stderr b/tests/ui/abi/cannot-be-called.riscv64.stderr
index 119d93bd58e92..6d763bd63796b 100644
--- a/tests/ui/abi/cannot-be-called.riscv64.stderr
+++ b/tests/ui/abi/cannot-be-called.riscv64.stderr
@@ -13,71 +13,71 @@ LL | extern "avr-interrupt" fn avr() {}
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
--> $DIR/cannot-be-called.rs:45:8
|
-LL | extern "x86-interrupt" fn x86() {}
+LL | extern "x86-interrupt" fn x86(_x: *const u8) {}
| ^^^^^^^^^^^^^^^
error[E0570]: "avr-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:64:22
+ --> $DIR/cannot-be-called.rs:66:22
|
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error[E0570]: "msp430-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:70:25
+ --> $DIR/cannot-be-called.rs:72:25
|
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
| ^^^^^^^^^^^^^^^^^^
error[E0570]: "x86-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:88:22
+ --> $DIR/cannot-be-called.rs:90:22
|
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error: functions with the "riscv-interrupt-m" ABI cannot be called
- --> $DIR/cannot-be-called.rs:54:5
+ --> $DIR/cannot-be-called.rs:56:5
|
LL | riscv_m();
| ^^^^^^^^^
|
note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:54:5
+ --> $DIR/cannot-be-called.rs:56:5
|
LL | riscv_m();
| ^^^^^^^^^
error: functions with the "riscv-interrupt-s" ABI cannot be called
- --> $DIR/cannot-be-called.rs:56:5
+ --> $DIR/cannot-be-called.rs:58:5
|
LL | riscv_s();
| ^^^^^^^^^
|
note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:56:5
+ --> $DIR/cannot-be-called.rs:58:5
|
LL | riscv_s();
| ^^^^^^^^^
error: functions with the "riscv-interrupt-m" ABI cannot be called
- --> $DIR/cannot-be-called.rs:78:5
+ --> $DIR/cannot-be-called.rs:80:5
|
LL | f()
| ^^^
|
note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:78:5
+ --> $DIR/cannot-be-called.rs:80:5
|
LL | f()
| ^^^
error: functions with the "riscv-interrupt-s" ABI cannot be called
- --> $DIR/cannot-be-called.rs:84:5
+ --> $DIR/cannot-be-called.rs:86:5
|
LL | f()
| ^^^
|
note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:84:5
+ --> $DIR/cannot-be-called.rs:86:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-called.rs b/tests/ui/abi/cannot-be-called.rs
index af979d65d3347..b0267cfa37e1a 100644
--- a/tests/ui/abi/cannot-be-called.rs
+++ b/tests/ui/abi/cannot-be-called.rs
@@ -42,9 +42,11 @@ extern "riscv-interrupt-m" fn riscv_m() {}
//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI
extern "riscv-interrupt-s" fn riscv_s() {}
//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI
-extern "x86-interrupt" fn x86() {}
+extern "x86-interrupt" fn x86(_x: *const u8) {}
//[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI
+static BYTE: u8 = 0;
+
/* extern "interrupt" calls */
fn call_the_interrupts() {
avr();
@@ -55,7 +57,7 @@ fn call_the_interrupts() {
//[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-m" ABI cannot be called
riscv_s();
//[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called
- x86();
+ x86(&raw const BYTE);
//[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called
}
diff --git a/tests/ui/abi/cannot-be-called.x64.stderr b/tests/ui/abi/cannot-be-called.x64.stderr
index 024d5e2e93d6f..6ccb10c44fdf9 100644
--- a/tests/ui/abi/cannot-be-called.x64.stderr
+++ b/tests/ui/abi/cannot-be-called.x64.stderr
@@ -23,49 +23,49 @@ LL | extern "riscv-interrupt-s" fn riscv_s() {}
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "avr-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:64:22
+ --> $DIR/cannot-be-called.rs:66:22
|
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error[E0570]: "msp430-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:70:25
+ --> $DIR/cannot-be-called.rs:72:25
|
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
| ^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:76:26
+ --> $DIR/cannot-be-called.rs:78:26
|
LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:82:26
+ --> $DIR/cannot-be-called.rs:84:26
|
LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error: functions with the "x86-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:58:5
+ --> $DIR/cannot-be-called.rs:60:5
|
-LL | x86();
- | ^^^^^
+LL | x86(&raw const BYTE);
+ | ^^^^^^^^^^^^^^^^^^^^
|
note: an `extern "x86-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:58:5
+ --> $DIR/cannot-be-called.rs:60:5
|
-LL | x86();
- | ^^^^^
+LL | x86(&raw const BYTE);
+ | ^^^^^^^^^^^^^^^^^^^^
error: functions with the "x86-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:90:5
+ --> $DIR/cannot-be-called.rs:92:5
|
LL | f()
| ^^^
|
note: an `extern "x86-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:90:5
+ --> $DIR/cannot-be-called.rs:92:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-called.x64_win.stderr b/tests/ui/abi/cannot-be-called.x64_win.stderr
index 024d5e2e93d6f..6ccb10c44fdf9 100644
--- a/tests/ui/abi/cannot-be-called.x64_win.stderr
+++ b/tests/ui/abi/cannot-be-called.x64_win.stderr
@@ -23,49 +23,49 @@ LL | extern "riscv-interrupt-s" fn riscv_s() {}
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "avr-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:64:22
+ --> $DIR/cannot-be-called.rs:66:22
|
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
| ^^^^^^^^^^^^^^^
error[E0570]: "msp430-interrupt" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:70:25
+ --> $DIR/cannot-be-called.rs:72:25
|
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
| ^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:76:26
+ --> $DIR/cannot-be-called.rs:78:26
|
LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target
- --> $DIR/cannot-be-called.rs:82:26
+ --> $DIR/cannot-be-called.rs:84:26
|
LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) {
| ^^^^^^^^^^^^^^^^^^^
error: functions with the "x86-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:58:5
+ --> $DIR/cannot-be-called.rs:60:5
|
-LL | x86();
- | ^^^^^
+LL | x86(&raw const BYTE);
+ | ^^^^^^^^^^^^^^^^^^^^
|
note: an `extern "x86-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:58:5
+ --> $DIR/cannot-be-called.rs:60:5
|
-LL | x86();
- | ^^^^^
+LL | x86(&raw const BYTE);
+ | ^^^^^^^^^^^^^^^^^^^^
error: functions with the "x86-interrupt" ABI cannot be called
- --> $DIR/cannot-be-called.rs:90:5
+ --> $DIR/cannot-be-called.rs:92:5
|
LL | f()
| ^^^
|
note: an `extern "x86-interrupt"` function can only be called using inline assembly
- --> $DIR/cannot-be-called.rs:90:5
+ --> $DIR/cannot-be-called.rs:92:5
|
LL | f()
| ^^^
diff --git a/tests/ui/abi/cannot-be-coroutine.i686.stderr b/tests/ui/abi/cannot-be-coroutine.i686.stderr
index 8c9292b6a3246..230847ff2695f 100644
--- a/tests/ui/abi/cannot-be-coroutine.i686.stderr
+++ b/tests/ui/abi/cannot-be-coroutine.i686.stderr
@@ -1,13 +1,13 @@
error: functions with the "x86-interrupt" ABI cannot be `async`
--> $DIR/cannot-be-coroutine.rs:52:1
|
-LL | async extern "x86-interrupt" fn x86() {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | async extern "x86-interrupt" fn x86(_p: *mut ()) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `async` keyword from this definition
|
-LL - async extern "x86-interrupt" fn x86() {
-LL + extern "x86-interrupt" fn x86() {
+LL - async extern "x86-interrupt" fn x86(_p: *mut ()) {
+LL + extern "x86-interrupt" fn x86(_p: *mut ()) {
|
error: requires `ResumeTy` lang_item
diff --git a/tests/ui/abi/cannot-be-coroutine.rs b/tests/ui/abi/cannot-be-coroutine.rs
index 7270a55f69ec5..e3d3d45c632f1 100644
--- a/tests/ui/abi/cannot-be-coroutine.rs
+++ b/tests/ui/abi/cannot-be-coroutine.rs
@@ -49,6 +49,6 @@ async extern "riscv-interrupt-s" fn riscv_s() {
//[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be `async`
}
-async extern "x86-interrupt" fn x86() {
+async extern "x86-interrupt" fn x86(_p: *mut ()) {
//[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be `async`
}
diff --git a/tests/ui/abi/cannot-be-coroutine.x64.stderr b/tests/ui/abi/cannot-be-coroutine.x64.stderr
index 8c9292b6a3246..230847ff2695f 100644
--- a/tests/ui/abi/cannot-be-coroutine.x64.stderr
+++ b/tests/ui/abi/cannot-be-coroutine.x64.stderr
@@ -1,13 +1,13 @@
error: functions with the "x86-interrupt" ABI cannot be `async`
--> $DIR/cannot-be-coroutine.rs:52:1
|
-LL | async extern "x86-interrupt" fn x86() {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | async extern "x86-interrupt" fn x86(_p: *mut ()) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `async` keyword from this definition
|
-LL - async extern "x86-interrupt" fn x86() {
-LL + extern "x86-interrupt" fn x86() {
+LL - async extern "x86-interrupt" fn x86(_p: *mut ()) {
+LL + extern "x86-interrupt" fn x86(_p: *mut ()) {
|
error: requires `ResumeTy` lang_item
diff --git a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr
index 8c9292b6a3246..230847ff2695f 100644
--- a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr
+++ b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr
@@ -1,13 +1,13 @@
error: functions with the "x86-interrupt" ABI cannot be `async`
--> $DIR/cannot-be-coroutine.rs:52:1
|
-LL | async extern "x86-interrupt" fn x86() {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | async extern "x86-interrupt" fn x86(_p: *mut ()) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `async` keyword from this definition
|
-LL - async extern "x86-interrupt" fn x86() {
-LL + extern "x86-interrupt" fn x86() {
+LL - async extern "x86-interrupt" fn x86(_p: *mut ()) {
+LL + extern "x86-interrupt" fn x86(_p: *mut ()) {
|
error: requires `ResumeTy` lang_item
diff --git a/tests/ui/abi/interrupt-invalid-signature.i686.stderr b/tests/ui/abi/interrupt-invalid-signature.i686.stderr
index 86f2e097c37e1..df8e318bf0ac4 100644
--- a/tests/ui/abi/interrupt-invalid-signature.i686.stderr
+++ b/tests/ui/abi/interrupt-invalid-signature.i686.stderr
@@ -1,15 +1,31 @@
error: invalid signature for `extern "x86-interrupt"` function
- --> $DIR/interrupt-invalid-signature.rs:83:40
+ --> $DIR/interrupt-invalid-signature.rs:83:53
|
-LL | extern "x86-interrupt" fn x86_ret() -> u8 {
- | ^^
+LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 {
+ | ^^
|
= note: functions with the "x86-interrupt" ABI cannot have a return type
help: remove the return type
- --> $DIR/interrupt-invalid-signature.rs:83:40
+ --> $DIR/interrupt-invalid-signature.rs:83:53
|
-LL | extern "x86-interrupt" fn x86_ret() -> u8 {
- | ^^
+LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 {
+ | ^^
-error: aborting due to 1 previous error
+error: invalid signature for `extern "x86-interrupt"` function
+ --> $DIR/interrupt-invalid-signature.rs:89:1
+ |
+LL | extern "x86-interrupt" fn x86_0() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found 0)
+
+error: invalid signature for `extern "x86-interrupt"` function
+ --> $DIR/interrupt-invalid-signature.rs:100:33
+ |
+LL | extern "x86-interrupt" fn x86_3(_p1: *const u8, _p2: *const u8, _p3: *const u8) {
+ | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
+ |
+ = note: functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found 3)
+
+error: aborting due to 3 previous errors
diff --git a/tests/ui/abi/interrupt-invalid-signature.rs b/tests/ui/abi/interrupt-invalid-signature.rs
index e389285b06917..09bda0d5faf13 100644
--- a/tests/ui/abi/interrupt-invalid-signature.rs
+++ b/tests/ui/abi/interrupt-invalid-signature.rs
@@ -80,11 +80,27 @@ extern "riscv-interrupt-s" fn riscv_s_ret() -> u8 {
}
#[cfg(any(x64,i686))]
-extern "x86-interrupt" fn x86_ret() -> u8 {
+extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 {
//[x64,i686]~^ ERROR invalid signature
1
}
+#[cfg(any(x64,i686))]
+extern "x86-interrupt" fn x86_0() {
+ //[x64,i686]~^ ERROR invalid signature
+}
+
+#[cfg(any(x64,i686))]
+extern "x86-interrupt" fn x86_1(_p1: *const u8) { }
+
+#[cfg(any(x64,i686))]
+extern "x86-interrupt" fn x86_2(_p1: *const u8, _p2: *const u8) { }
+
+#[cfg(any(x64,i686))]
+extern "x86-interrupt" fn x86_3(_p1: *const u8, _p2: *const u8, _p3: *const u8) {
+ //[x64,i686]~^ ERROR invalid signature
+}
+
/* extern "interrupt" fnptrs with invalid signatures */
diff --git a/tests/ui/abi/interrupt-invalid-signature.x64.stderr b/tests/ui/abi/interrupt-invalid-signature.x64.stderr
index 86f2e097c37e1..df8e318bf0ac4 100644
--- a/tests/ui/abi/interrupt-invalid-signature.x64.stderr
+++ b/tests/ui/abi/interrupt-invalid-signature.x64.stderr
@@ -1,15 +1,31 @@
error: invalid signature for `extern "x86-interrupt"` function
- --> $DIR/interrupt-invalid-signature.rs:83:40
+ --> $DIR/interrupt-invalid-signature.rs:83:53
|
-LL | extern "x86-interrupt" fn x86_ret() -> u8 {
- | ^^
+LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 {
+ | ^^
|
= note: functions with the "x86-interrupt" ABI cannot have a return type
help: remove the return type
- --> $DIR/interrupt-invalid-signature.rs:83:40
+ --> $DIR/interrupt-invalid-signature.rs:83:53
|
-LL | extern "x86-interrupt" fn x86_ret() -> u8 {
- | ^^
+LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 {
+ | ^^
-error: aborting due to 1 previous error
+error: invalid signature for `extern "x86-interrupt"` function
+ --> $DIR/interrupt-invalid-signature.rs:89:1
+ |
+LL | extern "x86-interrupt" fn x86_0() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found 0)
+
+error: invalid signature for `extern "x86-interrupt"` function
+ --> $DIR/interrupt-invalid-signature.rs:100:33
+ |
+LL | extern "x86-interrupt" fn x86_3(_p1: *const u8, _p2: *const u8, _p3: *const u8) {
+ | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
+ |
+ = note: functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found 3)
+
+error: aborting due to 3 previous errors
diff --git a/tests/ui/abi/interrupt-returns-never-or-unit.rs b/tests/ui/abi/interrupt-returns-never-or-unit.rs
index 8e224229a0b17..104b36363d0cb 100644
--- a/tests/ui/abi/interrupt-returns-never-or-unit.rs
+++ b/tests/ui/abi/interrupt-returns-never-or-unit.rs
@@ -56,7 +56,7 @@ extern "riscv-interrupt-s" fn riscv_s_ret_never() -> ! {
}
#[cfg(any(x64,i686))]
-extern "x86-interrupt" fn x86_ret_never() -> ! {
+extern "x86-interrupt" fn x86_ret_never(_p: *const u8) -> ! {
loop {}
}
@@ -83,7 +83,7 @@ extern "riscv-interrupt-s" fn riscv_s_ret_unit() -> () {
}
#[cfg(any(x64,i686))]
-extern "x86-interrupt" fn x86_ret_unit() -> () {
+extern "x86-interrupt" fn x86_ret_unit(_x: *const u8) -> () {
()
}
diff --git a/tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.rs b/tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.rs
new file mode 100644
index 0000000000000..8ad244568a3ee
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.rs
@@ -0,0 +1,15 @@
+#![feature(explicit_tail_calls)]
+#![expect(incomplete_features)]
+
+fn foo() -> for<'a> fn(&'a i32) {
+ become bar();
+ //~^ ERROR mismatched signatures
+}
+
+fn bar() -> fn(&'static i32) {
+ dummy
+}
+
+fn dummy(_: &i32) {}
+
+fn main() {}
diff --git a/tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.stderr b/tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.stderr
new file mode 100644
index 0000000000000..f6594580ba52d
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.stderr
@@ -0,0 +1,12 @@
+error: mismatched signatures
+ --> $DIR/ret-ty-hr-mismatch.rs:5:5
+ |
+LL | become bar();
+ | ^^^^^^^^^^^^
+ |
+ = note: `become` requires caller and callee to have matching signatures
+ = note: caller signature: `fn() -> for<'a> fn(&'a i32)`
+ = note: callee signature: `fn() -> fn(&'static i32)`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/explicit-tail-calls/ret-ty-modulo-anonymization.rs b/tests/ui/explicit-tail-calls/ret-ty-modulo-anonymization.rs
new file mode 100644
index 0000000000000..0cd4e204278ac
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/ret-ty-modulo-anonymization.rs
@@ -0,0 +1,16 @@
+// Ensure that we anonymize the output of a function for tail call signature compatibility.
+
+//@ check-pass
+
+#![feature(explicit_tail_calls)]
+#![expect(incomplete_features)]
+
+fn foo() -> for<'a> fn(&'a ()) {
+ become bar();
+}
+
+fn bar() -> for<'b> fn(&'b ()) {
+ todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs
index c4fdb5f427ca5..0abdf0c5309bc 100644
--- a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs
+++ b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs
@@ -7,22 +7,22 @@
extern crate minicore;
use minicore::*;
-extern "x86-interrupt" fn f7() {} //~ ERROR "x86-interrupt" ABI is experimental
+extern "x86-interrupt" fn f7(_p: *const u8) {} //~ ERROR "x86-interrupt" ABI is experimental
trait Tr {
- extern "x86-interrupt" fn m7(); //~ ERROR "x86-interrupt" ABI is experimental
- extern "x86-interrupt" fn dm7() {} //~ ERROR "x86-interrupt" ABI is experimental
+ extern "x86-interrupt" fn m7(_p: *const u8); //~ ERROR "x86-interrupt" ABI is experimental
+ extern "x86-interrupt" fn dm7(_p: *const u8) {} //~ ERROR "x86-interrupt" ABI is experimental
}
struct S;
// Methods in trait impl
impl Tr for S {
- extern "x86-interrupt" fn m7() {} //~ ERROR "x86-interrupt" ABI is experimental
+ extern "x86-interrupt" fn m7(_p: *const u8) {} //~ ERROR "x86-interrupt" ABI is experimental
}
// Methods in inherent impl
impl S {
- extern "x86-interrupt" fn im7() {} //~ ERROR "x86-interrupt" ABI is experimental
+ extern "x86-interrupt" fn im7(_p: *const u8) {} //~ ERROR "x86-interrupt" ABI is experimental
}
type A7 = extern "x86-interrupt" fn(); //~ ERROR "x86-interrupt" ABI is experimental
diff --git a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr
index 67211d402c6c9..b53917dda610f 100644
--- a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr
+++ b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr
@@ -1,7 +1,7 @@
error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change
--> $DIR/feature-gate-abi-x86-interrupt.rs:10:8
|
-LL | extern "x86-interrupt" fn f7() {}
+LL | extern "x86-interrupt" fn f7(_p: *const u8) {}
| ^^^^^^^^^^^^^^^
|
= note: see issue #40180 for more information
@@ -11,7 +11,7 @@ LL | extern "x86-interrupt" fn f7() {}
error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change
--> $DIR/feature-gate-abi-x86-interrupt.rs:12:12
|
-LL | extern "x86-interrupt" fn m7();
+LL | extern "x86-interrupt" fn m7(_p: *const u8);
| ^^^^^^^^^^^^^^^
|
= note: see issue #40180 for more information
@@ -21,7 +21,7 @@ LL | extern "x86-interrupt" fn m7();
error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change
--> $DIR/feature-gate-abi-x86-interrupt.rs:13:12
|
-LL | extern "x86-interrupt" fn dm7() {}
+LL | extern "x86-interrupt" fn dm7(_p: *const u8) {}
| ^^^^^^^^^^^^^^^
|
= note: see issue #40180 for more information
@@ -31,7 +31,7 @@ LL | extern "x86-interrupt" fn dm7() {}
error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change
--> $DIR/feature-gate-abi-x86-interrupt.rs:20:12
|
-LL | extern "x86-interrupt" fn m7() {}
+LL | extern "x86-interrupt" fn m7(_p: *const u8) {}
| ^^^^^^^^^^^^^^^
|
= note: see issue #40180 for more information
@@ -41,7 +41,7 @@ LL | extern "x86-interrupt" fn m7() {}
error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change
--> $DIR/feature-gate-abi-x86-interrupt.rs:25:12
|
-LL | extern "x86-interrupt" fn im7() {}
+LL | extern "x86-interrupt" fn im7(_p: *const u8) {}
| ^^^^^^^^^^^^^^^
|
= note: see issue #40180 for more information
diff --git a/tests/ui/trait-bounds/trait-bound-adt-issue-145611.rs b/tests/ui/trait-bounds/trait-bound-adt-issue-145611.rs
new file mode 100644
index 0000000000000..74551ce493f94
--- /dev/null
+++ b/tests/ui/trait-bounds/trait-bound-adt-issue-145611.rs
@@ -0,0 +1,11 @@
+// This test is for regression of issue #145611
+// There should not be cycle error in effective_visibilities query.
+
+trait LocalTrait {}
+struct SomeType;
+fn impls_trait() {}
+fn foo() -> impl Sized {
+ impls_trait::(); //~ ERROR the trait bound `SomeType: LocalTrait` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/trait-bound-adt-issue-145611.stderr b/tests/ui/trait-bounds/trait-bound-adt-issue-145611.stderr
new file mode 100644
index 0000000000000..21a2cce20cb82
--- /dev/null
+++ b/tests/ui/trait-bounds/trait-bound-adt-issue-145611.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `SomeType: LocalTrait` is not satisfied
+ --> $DIR/trait-bound-adt-issue-145611.rs:8:19
+ |
+LL | impls_trait::();
+ | ^^^^^^^^ the trait `LocalTrait` is not implemented for `SomeType`
+ |
+help: this trait has no implementations, consider adding one
+ --> $DIR/trait-bound-adt-issue-145611.rs:4:1
+ |
+LL | trait LocalTrait {}
+ | ^^^^^^^^^^^^^^^^
+note: required by a bound in `impls_trait`
+ --> $DIR/trait-bound-adt-issue-145611.rs:6:19
+ |
+LL | fn impls_trait() {}
+ | ^^^^^^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/triagebot.toml b/triagebot.toml
index 314117478480f..955b0ba2b05b6 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1603,3 +1603,8 @@ labels = ["S-waiting-on-concerns"]
# onto a different base commit
# Documentation at: https://forge.rust-lang.org/triagebot/range-diff.html
[range-diff]
+
+# Adds at the end of a review body a link to view the changes that happened
+# since the review
+# Documentation at: https://forge.rust-lang.org/triagebot/review-changes-since.html
+[review-changes-since]