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]