diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 84ca9bad2c144..7ac2dff12f756 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -124,8 +124,13 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { // by using `ty_vid rel B` and then finally and end by equating `ty_vid` to // the opaque. let mut enable_subtyping = |ty, opaque_is_expected| { - let ty_vid = infcx.next_ty_var_id_in_universe(self.span(), ty::UniverseIndex::ROOT); - + // We create the fresh inference variable in the highest universe. + // In theory we could limit it to the highest universe in the args of + // the opaque but that isn't really worth the effort. + // + // We'll make sure that the opaque type can actually name everything + // in its hidden type later on. + let ty_vid = infcx.next_ty_vid(self.span()); let variance = if opaque_is_expected { self.ambient_variance } else { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 2d91ae64e2dd2..4a7de7d2e69e2 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -471,6 +471,15 @@ pub(crate) unsafe fn create_module<'ll>( } } + if sess.opts.unstable_opts.indirect_branch_cs_prefix { + llvm::add_module_flag_u32( + llmod, + llvm::ModuleFlagMergeBehavior::Override, + "indirect_branch_cs_prefix", + 1, + ); + } + match (sess.opts.unstable_opts.small_data_threshold, sess.target.small_data_threshold_support()) { // Set up the small-data optimization limit for architectures that use diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 28d2100f478cc..90f7cd43268fa 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -277,6 +277,7 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option None, // Filter out features that are not supported by the current LLVM version ("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None, ( diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 7e4341a823667..b5aa50f485125 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -180,6 +180,7 @@ fn parse_rust_feature_flag<'a>( while let Some(new_feature) = new_features.pop() { if features.insert(new_feature) { if let Some(implied_features) = inverse_implied_features.get(&new_feature) { + #[allow(rustc::potential_query_instability)] new_features.extend(implied_features) } } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 64cb934ac8d00..4cb88d44e1b11 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -27,8 +27,9 @@ use crate::{enter_trace_span, fluent_generated as fluent}; pub enum FnArg<'tcx, Prov: Provenance = CtfeProvenance> { /// Pass a copy of the given operand. Copy(OpTy<'tcx, Prov>), - /// Allow for the argument to be passed in-place: destroy the value originally stored at that place and - /// make the place inaccessible for the duration of the function call. + /// Allow for the argument to be passed in-place: destroy the value originally stored at that + /// place and make the place inaccessible for the duration of the function call. This *must* be + /// an in-memory place so that we can do the proper alias checks. InPlace(MPlaceTy<'tcx, Prov>), } @@ -379,6 +380,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + // *Before* pushing the new frame, determine whether the return destination is in memory. + // Need to use `place_to_op` to be *sure* we get the mplace if there is one. + let destination_mplace = self.place_to_op(destination)?.as_mplace_or_imm().left(); + + // Push the "raw" frame -- this leaves locals uninitialized. self.push_stack_frame_raw(instance, body, destination, cont)?; // If an error is raised here, pop the frame again to get an accurate backtrace. @@ -496,7 +502,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Protect return place for in-place return value passing. // We only need to protect anything if this is actually an in-memory place. - if let Left(mplace) = destination.as_mplace_or_local() { + if let Some(mplace) = destination_mplace { M::protect_in_place_function_argument(self, &mplace)?; } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index a8a1ac1c9809e..9681d89ce35f2 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -325,8 +325,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let _trace = enter_trace_span!( M, "instantiate_from_frame_and_normalize_erasing_regions", - "{}", - frame.instance + %frame.instance ); frame .instance @@ -583,6 +582,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { span: Span, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { + let _trace = enter_trace_span!(M, const_eval::eval_mir_constant, ?val); let const_val = val.eval(*self.tcx, self.typing_env, span).map_err(|err| { if M::ALL_CONSTS_ARE_PRECHECKED { match err { diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index e7fe4c0b34fdc..a86fdf80f601a 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -234,6 +234,12 @@ impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> { } /// A place is either an mplace or some local. + /// + /// Note that the return value can be different even for logically identical places! + /// Specifically, if a local is stored in-memory, this may return `Local` or `MPlaceTy` + /// depending on how the place was constructed. In other words, seeing `Local` here does *not* + /// imply that this place does not point to memory. Every caller must therefore always handle + /// both cases. #[inline(always)] pub fn as_mplace_or_local( &self, diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 73cc87508ef95..7cabfd961212f 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -20,7 +20,7 @@ use super::{ MemoryKind, Operand, PlaceTy, Pointer, Provenance, ReturnAction, Scalar, from_known_layout, interp_ok, throw_ub, throw_unsup, }; -use crate::errors; +use crate::{enter_trace_span, errors}; // The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread // boundary and dropped in the other thread, it would exit the span in the other thread. @@ -386,6 +386,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). for &const_ in body.required_consts() { + // We can't use `eval_mir_constant` here as that assumes that all required consts have + // already been checked, so we need a separate tracing call. + let _trace = enter_trace_span!(M, const_eval::required_consts, ?const_.const_); let c = self.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?; c.eval(*self.tcx, self.typing_env, const_.span).map_err(|err| { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index f1995b3f132f6..084d45cf2cbbf 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -4,6 +4,7 @@ use either::Either; use rustc_abi::{FIRST_VARIANT, FieldIdx}; +use rustc_data_structures::fx::FxHashSet; use rustc_index::IndexSlice; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, mir, span_bug}; @@ -389,8 +390,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Evaluate the arguments of a function call fn eval_fn_call_argument( - &self, + &mut self, op: &mir::Operand<'tcx>, + move_definitely_disjoint: bool, ) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> { interp_ok(match op { mir::Operand::Copy(_) | mir::Operand::Constant(_) => { @@ -399,24 +401,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { FnArg::Copy(op) } mir::Operand::Move(place) => { - // If this place lives in memory, preserve its location. - // We call `place_to_op` which will be an `MPlaceTy` whenever there exists - // an mplace for this place. (This is in contrast to `PlaceTy::as_mplace_or_local` - // which can return a local even if that has an mplace.) let place = self.eval_place(*place)?; - let op = self.place_to_op(&place)?; - - match op.as_mplace_or_imm() { - Either::Left(mplace) => FnArg::InPlace(mplace), - Either::Right(_imm) => { - // This argument doesn't live in memory, so there's no place - // to make inaccessible during the call. - // We rely on there not being any stray `PlaceTy` that would let the - // caller directly access this local! - // This is also crucial for tail calls, where we want the `FnArg` to - // stay valid when the old stack frame gets popped. - FnArg::Copy(op) + if move_definitely_disjoint { + // We still have to ensure that no *other* pointers are used to access this place, + // so *if* it is in memory then we have to treat it as `InPlace`. + // Use `place_to_op` to guarantee that we notice it being in memory. + let op = self.place_to_op(&place)?; + match op.as_mplace_or_imm() { + Either::Left(mplace) => FnArg::InPlace(mplace), + Either::Right(_imm) => FnArg::Copy(op), } + } else { + // We have to force this into memory to detect aliasing among `Move` arguments. + FnArg::InPlace(self.force_allocation(&place)?) } } }) @@ -425,18 +422,46 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Shared part of `Call` and `TailCall` implementation — finding and evaluating all the /// necessary information about callee and arguments to make a call. fn eval_callee_and_args( - &self, + &mut self, terminator: &mir::Terminator<'tcx>, func: &mir::Operand<'tcx>, args: &[Spanned>], ) -> InterpResult<'tcx, EvaluatedCalleeAndArgs<'tcx, M>> { let func = self.eval_operand(func, None)?; + + // Evaluating function call arguments. The tricky part here is dealing with `Move` + // arguments: we have to ensure no two such arguments alias. This would be most easily done + // by just forcing them all into memory and then doing the usual in-place argument + // protection, but then we'd force *a lot* of arguments into memory. So we do some syntactic + // pre-processing here where if all `move` arguments are syntactically distinct local + // variables (and none is indirect), we can skip the in-memory forcing. + let move_definitely_disjoint = 'move_definitely_disjoint: { + let mut previous_locals = FxHashSet::::default(); + for arg in args { + let mir::Operand::Move(place) = arg.node else { + continue; // we can skip non-`Move` arguments. + }; + if place.is_indirect_first_projection() { + // An indirect `Move` argument could alias with anything else... + break 'move_definitely_disjoint false; + } + if !previous_locals.insert(place.local) { + // This local is the base for two arguments! They might overlap. + break 'move_definitely_disjoint false; + } + } + // We found no violation so they are all definitely disjoint. + true + }; let args = args .iter() - .map(|arg| self.eval_fn_call_argument(&arg.node)) + .map(|arg| self.eval_fn_call_argument(&arg.node, move_definitely_disjoint)) .collect::>>()?; - let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); + let fn_sig_binder = { + let _trace = enter_trace_span!(M, "fn_sig", ty = ?func.layout.ty.kind()); + func.layout.ty.fn_sig(*self.tcx) + }; let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, fn_sig_binder); let extra_args = &args[fn_sig.inputs().len()..]; let extra_args = diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 5e8bee65706b8..02e3d90f4af70 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1418,7 +1418,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let _trace = enter_trace_span!( M, "validate_operand", - "recursive={recursive}, reset_provenance_and_padding={reset_provenance_and_padding}, val={val:?}" + recursive, + reset_provenance_and_padding, + ?val, ); // Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 97c47fa9b9a53..749bba5de1273 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -17,7 +17,7 @@ use std::path::Path; use std::sync::Arc; use derive_setters::Setters; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sync::{DynSend, IntoDynSyncSend}; use rustc_error_messages::{FluentArgs, SpanLabel}; use rustc_lexer; @@ -1853,7 +1853,7 @@ impl HumanEmitter { && line_idx + 1 == annotated_file.lines.len(), ); - let mut to_add = FxHashMap::default(); + let mut to_add = FxIndexMap::default(); for (depth, style) in depths { // FIXME(#120456) - is `swap_remove` correct? diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index bced02ae4dabb..8b43f852b2638 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -596,6 +596,7 @@ pub(super) fn try_match_macro_attr<'matcher, T: Tracker<'matcher>>( match result { Success(body_named_matches) => { psess.gated_spans.merge(gated_spans_snapshot); + #[allow(rustc::potential_query_instability)] named_matches.extend(body_named_matches); return Ok((i, rule, named_matches)); } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 82d4856df39c7..9ff06bda89bad 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -782,22 +782,30 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().type_variables().num_vars() } - pub fn next_ty_var(&self, span: Span) -> Ty<'tcx> { - self.next_ty_var_with_origin(TypeVariableOrigin { span, param_def_id: None }) + pub fn next_ty_vid(&self, span: Span) -> TyVid { + self.next_ty_vid_with_origin(TypeVariableOrigin { span, param_def_id: None }) } - pub fn next_ty_var_with_origin(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { - let vid = self.inner.borrow_mut().type_variables().new_var(self.universe(), origin); - Ty::new_var(self.tcx, vid) + pub fn next_ty_vid_with_origin(&self, origin: TypeVariableOrigin) -> TyVid { + self.inner.borrow_mut().type_variables().new_var(self.universe(), origin) } - pub fn next_ty_var_id_in_universe(&self, span: Span, universe: ty::UniverseIndex) -> TyVid { + pub fn next_ty_vid_in_universe(&self, span: Span, universe: ty::UniverseIndex) -> TyVid { let origin = TypeVariableOrigin { span, param_def_id: None }; self.inner.borrow_mut().type_variables().new_var(universe, origin) } + pub fn next_ty_var(&self, span: Span) -> Ty<'tcx> { + self.next_ty_var_with_origin(TypeVariableOrigin { span, param_def_id: None }) + } + + pub fn next_ty_var_with_origin(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { + let vid = self.next_ty_vid_with_origin(origin); + Ty::new_var(self.tcx, vid) + } + pub fn next_ty_var_in_universe(&self, span: Span, universe: ty::UniverseIndex) -> Ty<'tcx> { - let vid = self.next_ty_var_id_in_universe(span, universe); + let vid = self.next_ty_vid_in_universe(span, universe); Ty::new_var(self.tcx, vid) } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index c46e879b976ac..8f131f45bbddb 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -285,7 +285,9 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch .expecteds .entry(name.name) .and_modify(|v| match v { - ExpectedValues::Some(v) if !values_any_specified => { + ExpectedValues::Some(v) if !values_any_specified => + { + #[allow(rustc::potential_query_instability)] v.extend(values.clone()) } ExpectedValues::Some(_) => *v = ExpectedValues::Any, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0a764808f9538..4425877308a78 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -807,6 +807,7 @@ fn test_unstable_options_tracking_hash() { tracked!(hint_mostly_unused, true); tracked!(human_readable_cgu_names, true); tracked!(incremental_ignore_spans, true); + tracked!(indirect_branch_cs_prefix, true); tracked!(inline_mir, Some(true)); tracked!(inline_mir_hint_threshold, Some(123)); tracked!(inline_mir_threshold, Some(123)); diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 016ff17f5d7ea..e1fbe39222b66 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -1,10 +1,10 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use rustc_hir::HirId; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy}; +use rustc_hir::{Expr, ExprKind, HirId}; +use rustc_middle::ty::{self, ClauseKind, GenericArgsRef, PredicatePolarity, TraitPredicate, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::{Span, sym}; @@ -56,25 +56,6 @@ impl LateLintPass<'_> for DefaultHashTypes { } } -/// Helper function for lints that check for expressions with calls and use typeck results to -/// get the `DefId` and `GenericArgsRef` of the function. -fn typeck_results_of_method_fn<'tcx>( - cx: &LateContext<'tcx>, - expr: &hir::Expr<'_>, -) -> Option<(Span, DefId, ty::GenericArgsRef<'tcx>)> { - match expr.kind { - hir::ExprKind::MethodCall(segment, ..) - if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => - { - Some((segment.ident.span, def_id, cx.typeck_results().node_args(expr.hir_id))) - } - _ => match cx.typeck_results().node_type(expr.hir_id).kind() { - &ty::FnDef(def_id, args) => Some((expr.span, def_id, args)), - _ => None, - }, - } -} - declare_tool_lint! { /// The `potential_query_instability` lint detects use of methods which can lead to /// potential query instability, such as iterating over a `HashMap`. @@ -101,10 +82,12 @@ declare_tool_lint! { declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUERY_INFORMATION]); -impl LateLintPass<'_> for QueryStability { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) { - let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return }; - if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, args) +impl<'tcx> LateLintPass<'tcx> for QueryStability { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if let Some((callee_def_id, span, generic_args, _recv, _args)) = + get_callee_span_generic_args_and_args(cx, expr) + && let Ok(Some(instance)) = + ty::Instance::try_resolve(cx.tcx, cx.typing_env(), callee_def_id, generic_args) { let def_id = instance.def_id(); if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { @@ -113,7 +96,15 @@ impl LateLintPass<'_> for QueryStability { span, QueryInstability { query: cx.tcx.item_name(def_id) }, ); + } else if has_unstable_into_iter_predicate(cx, callee_def_id, generic_args) { + let call_span = span.with_hi(expr.span.hi()); + cx.emit_span_lint( + POTENTIAL_QUERY_INSTABILITY, + call_span, + QueryInstability { query: sym::into_iter }, + ); } + if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) { cx.emit_span_lint( UNTRACKED_QUERY_INFORMATION, @@ -125,6 +116,64 @@ impl LateLintPass<'_> for QueryStability { } } +fn has_unstable_into_iter_predicate<'tcx>( + cx: &LateContext<'tcx>, + callee_def_id: DefId, + generic_args: GenericArgsRef<'tcx>, +) -> bool { + let Some(into_iterator_def_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator) else { + return false; + }; + let Some(into_iter_fn_def_id) = cx.tcx.lang_items().into_iter_fn() else { + return false; + }; + let predicates = cx.tcx.predicates_of(callee_def_id).instantiate(cx.tcx, generic_args); + for (predicate, _) in predicates { + let ClauseKind::Trait(TraitPredicate { trait_ref, polarity: PredicatePolarity::Positive }) = + predicate.kind().skip_binder() + else { + continue; + }; + // Does the function or method require any of its arguments to implement `IntoIterator`? + if trait_ref.def_id != into_iterator_def_id { + continue; + } + let Ok(Some(instance)) = + ty::Instance::try_resolve(cx.tcx, cx.typing_env(), into_iter_fn_def_id, trait_ref.args) + else { + continue; + }; + // Does the input type's `IntoIterator` implementation have the + // `rustc_lint_query_instability` attribute on its `into_iter` method? + if cx.tcx.has_attr(instance.def_id(), sym::rustc_lint_query_instability) { + return true; + } + } + false +} + +/// Checks whether an expression is a function or method call and, if so, returns its `DefId`, +/// `Span`, `GenericArgs`, and arguments. This is a slight augmentation of a similarly named Clippy +/// function, `get_callee_generic_args_and_args`. +fn get_callee_span_generic_args_and_args<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, +) -> Option<(DefId, Span, GenericArgsRef<'tcx>, Option<&'tcx Expr<'tcx>>, &'tcx [Expr<'tcx>])> { + if let ExprKind::Call(callee, args) = expr.kind + && let callee_ty = cx.typeck_results().expr_ty(callee) + && let ty::FnDef(callee_def_id, generic_args) = callee_ty.kind() + { + return Some((*callee_def_id, callee.span, generic_args, None, args)); + } + if let ExprKind::MethodCall(segment, recv, args, _) = expr.kind + && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + { + let generic_args = cx.typeck_results().node_args(expr.hir_id); + return Some((method_def_id, segment.ident.span, generic_args, Some(recv), args)); + } + None +} + declare_tool_lint! { /// The `usage_of_ty_tykind` lint detects usages of `ty::TyKind::`, /// where `ty::` would suffice. @@ -461,33 +510,22 @@ declare_tool_lint! { declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL]); impl LateLintPass<'_> for Diagnostics { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { let collect_args_tys_and_spans = |args: &[hir::Expr<'_>], reserve_one_extra: bool| { let mut result = Vec::with_capacity(args.len() + usize::from(reserve_one_extra)); result.extend(args.iter().map(|arg| (cx.typeck_results().expr_ty(arg), arg.span))); result }; // Only check function calls and method calls. - let (span, def_id, fn_gen_args, arg_tys_and_spans) = match expr.kind { - hir::ExprKind::Call(callee, args) => { - match cx.typeck_results().node_type(callee.hir_id).kind() { - &ty::FnDef(def_id, fn_gen_args) => { - (callee.span, def_id, fn_gen_args, collect_args_tys_and_spans(args, false)) - } - _ => return, // occurs for fns passed as args - } - } - hir::ExprKind::MethodCall(_segment, _recv, args, _span) => { - let Some((span, def_id, fn_gen_args)) = typeck_results_of_method_fn(cx, expr) - else { - return; - }; - let mut args = collect_args_tys_and_spans(args, true); - args.insert(0, (cx.tcx.types.self_param, _recv.span)); // dummy inserted for `self` - (span, def_id, fn_gen_args, args) - } - _ => return, + let Some((def_id, span, fn_gen_args, recv, args)) = + get_callee_span_generic_args_and_args(cx, expr) + else { + return; }; + let mut arg_tys_and_spans = collect_args_tys_and_spans(args, recv.is_some()); + if let Some(recv) = recv { + arg_tys_and_spans.insert(0, (cx.tcx.types.self_param, recv.span)); // dummy inserted for `self` + } Self::diagnostic_outside_of_impl(cx, span, expr.hir_id, def_id, fn_gen_args); Self::untranslatable_diagnostic(cx, def_id, &arg_tys_and_spans); @@ -496,7 +534,7 @@ impl LateLintPass<'_> for Diagnostics { impl Diagnostics { // Is the type `{D,Subd}iagMessage`? - fn is_diag_message<'cx>(cx: &LateContext<'cx>, ty: MiddleTy<'cx>) -> bool { + fn is_diag_message<'cx>(cx: &LateContext<'cx>, ty: Ty<'cx>) -> bool { if let Some(adt_def) = ty.ty_adt_def() && let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did()) && matches!(name, sym::DiagMessage | sym::SubdiagMessage) @@ -510,7 +548,7 @@ impl Diagnostics { fn untranslatable_diagnostic<'cx>( cx: &LateContext<'cx>, def_id: DefId, - arg_tys_and_spans: &[(MiddleTy<'cx>, Span)], + arg_tys_and_spans: &[(Ty<'cx>, Span)], ) { let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates; diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 1bc35e599c706..3e1f48610ffc0 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -27,7 +27,7 @@ enum CanonicalizeInputKind { ParamEnv, /// When canonicalizing predicates, we don't keep `'static`. If we're /// currently outside of the trait solver and canonicalize the root goal - /// during HIR typeck, we replace each occurance of a region with a + /// during HIR typeck, we replace each occurrence of a region with a /// unique region variable. See the comment on `InferCtxt::in_hir_typeck` /// for more details. Predicate { is_hir_typeck_root_goal: bool }, diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 05b5abc3dc674..47280a936779f 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -93,6 +93,9 @@ resolve_consider_adding_a_derive = resolve_consider_adding_macro_export = consider adding a `#[macro_export]` to the macro in the imported module +resolve_consider_marking_as_pub_crate = + in case you want to use the macro within this crate only, reduce the visibility to `pub(crate)` + resolve_consider_declaring_with_pub = consider declaring type or module `{$ident}` with `pub` diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 1eb4e1199e622..214038040c951 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -474,6 +474,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { root_span, root_id, vis, + vis_span: item.vis.span, }); self.r.indeterminate_imports.push(import); @@ -966,6 +967,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { span: item.span, module_path: Vec::new(), vis, + vis_span: item.vis.span, }); if used { self.r.import_use_map.insert(import, Used::Other); @@ -1100,6 +1102,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { span, module_path: Vec::new(), vis: Visibility::Restricted(CRATE_DEF_ID), + vis_span: item.vis.span, }) }; @@ -1270,6 +1273,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { span, module_path: Vec::new(), vis, + vis_span: item.vis.span, }); self.r.import_use_map.insert(import, Used::Other); let import_binding = self.r.import(binding, import); diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index a1d62ba7a6834..63d6fa23a148d 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -775,6 +775,17 @@ pub(crate) struct ConsiderAddingMacroExport { pub(crate) span: Span, } +#[derive(Subdiagnostic)] +#[suggestion( + resolve_consider_marking_as_pub_crate, + code = "pub(crate)", + applicability = "maybe-incorrect" +)] +pub(crate) struct ConsiderMarkingAsPubCrate { + #[primary_span] + pub(crate) vis_span: Span, +} + #[derive(Subdiagnostic)] #[note(resolve_consider_marking_as_pub)] pub(crate) struct ConsiderMarkingAsPub { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7c93fdb88ee44..d3790394d2a9a 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -30,7 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates}; use crate::errors::{ CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate, CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates, - ConsiderAddingMacroExport, ConsiderMarkingAsPub, + ConsiderAddingMacroExport, ConsiderMarkingAsPub, ConsiderMarkingAsPubCrate, }; use crate::{ AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Determinacy, Finalize, ImportSuggestion, @@ -184,6 +184,9 @@ pub(crate) struct ImportData<'ra> { /// |`use foo` | `ModuleOrUniformRoot::CurrentScope` | - | pub imported_module: Cell>>, pub vis: Visibility, + + /// Span of the visibility. + pub vis_span: Span, } /// All imports are unique and allocated on a same arena, @@ -866,7 +869,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } ImportKind::Glob { .. } => { // FIXME: Use mutable resolver directly as a hack, this should be an output of - // specualtive resolution. + // speculative resolution. self.get_mut_unchecked().resolve_glob_import(import); return 0; } @@ -903,7 +906,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); // FIXME: Use mutable resolver directly as a hack, this should be an output of - // specualtive resolution. + // speculative resolution. this.get_mut_unchecked().define_binding_local( parent, target, @@ -917,7 +920,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if target.name != kw::Underscore { let key = BindingKey::new(target, ns); // FIXME: Use mutable resolver directly as a hack, this should be an output of - // specualtive resolution. + // speculative resolution. this.get_mut_unchecked().update_local_resolution( parent, key, @@ -1368,6 +1371,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { err.subdiagnostic( ConsiderAddingMacroExport { span: binding.span, }); + err.subdiagnostic( ConsiderMarkingAsPubCrate { + vis_span: import.vis_span, + }); } _ => { err.subdiagnostic( ConsiderMarkingAsPub { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5200f9340e115..679e663f88614 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4270,7 +4270,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if path.len() == 2 && let [segment] = prefix_path { - // Delay to check whether methond name is an associated function or not + // Delay to check whether method name is an associated function or not // ``` // let foo = Foo {}; // foo::bar(); // possibly suggest to foo.bar(); diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index 528c52eace7cb..80754964c43d7 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -49,6 +49,8 @@ session_hexadecimal_float_literal_not_supported = hexadecimal float literal is n session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target .note = compatible flavors are: {$compatible_list} +session_indirect_branch_cs_prefix_requires_x86_or_x86_64 = `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64 + session_instrumentation_not_supported = {$us} instrumentation is not supported for this target session_int_literal_too_large = integer literal is too large diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index bf95014843d23..9471807df0188 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -471,6 +471,10 @@ pub(crate) struct FunctionReturnRequiresX86OrX8664; #[diag(session_function_return_thunk_extern_requires_non_large_code_model)] pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel; +#[derive(Diagnostic)] +#[diag(session_indirect_branch_cs_prefix_requires_x86_or_x86_64)] +pub(crate) struct IndirectBranchCsPrefixRequiresX86OrX8664; + #[derive(Diagnostic)] #[diag(session_unsupported_regparm)] pub(crate) struct UnsupportedRegparm { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 0e112edc73316..6d5be2d92cd2a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2295,6 +2295,8 @@ options! { - hashes of green query instances - hash collisions of query keys - hash collisions when creating dep-nodes"), + indirect_branch_cs_prefix: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], + "add `cs` prefix to `call` and `jmp` to indirect thunks (default: no)"), inline_llvm: bool = (true, parse_bool, [TRACKED], "enable LLVM inlining (default: yes)"), inline_mir: Option = (None, parse_opt_bool, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c6956cf5f23b5..c8f4b511a7ef3 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1368,6 +1368,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } + if sess.opts.unstable_opts.indirect_branch_cs_prefix { + if sess.target.arch != "x86" && sess.target.arch != "x86_64" { + sess.dcx().emit_err(errors::IndirectBranchCsPrefixRequiresX86OrX8664); + } + } + if let Some(regparm) = sess.opts.unstable_opts.regparm { if regparm > 3 { sess.dcx().emit_err(errors::UnsupportedRegparm { regparm }); diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 507e938d5cce4..e45300b59cc73 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -767,6 +767,7 @@ static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start + ("32s", Unstable(sym::loongarch_target_feature), &[]), ("d", Stable, &["f"]), ("div32", Unstable(sym::loongarch_target_feature), &[]), ("f", Stable, &[]), diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 7d41ae45093ea..605ba42c541fa 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -3,164 +3,78 @@ use crate::fmt::NumBuffer; use crate::mem::MaybeUninit; use crate::num::fmt as numfmt; -use crate::ops::{Div, Rem, Sub}; use crate::{fmt, ptr, slice, str}; -#[doc(hidden)] -trait DisplayInt: - PartialEq + PartialOrd + Div + Rem + Sub + Copy -{ - fn zero() -> Self; - fn from_u8(u: u8) -> Self; - fn to_u8(&self) -> u8; - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32; - fn to_u64(&self) -> u64; - fn to_u128(&self) -> u128; -} +/// Formatting of integers with a non-decimal radix. +macro_rules! radix_integer { + (fmt::$Trait:ident for $Signed:ident and $Unsigned:ident, $prefix:literal, $dig_tab:literal) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::$Trait for $Unsigned { + /// Format unsigned integers in the radix. + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Check macro arguments at compile time. + const { + assert!($Unsigned::MIN == 0, "need unsigned"); + assert!($dig_tab.is_ascii(), "need single-byte entries"); + } -macro_rules! impl_int { - ($($t:ident)*) => ( - $(impl DisplayInt for $t { - fn zero() -> Self { 0 } - fn from_u8(u: u8) -> Self { u as Self } - fn to_u8(&self) -> u8 { *self as u8 } - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32 { *self as u32 } - fn to_u64(&self) -> u64 { *self as u64 } - fn to_u128(&self) -> u128 { *self as u128 } - })* - ) -} + // ASCII digits in ascending order are used as a lookup table. + const DIG_TAB: &[u8] = $dig_tab; + const BASE: $Unsigned = DIG_TAB.len() as $Unsigned; + const MAX_DIG_N: usize = $Unsigned::MAX.ilog(BASE) as usize + 1; -impl_int! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize -} + // Buffer digits of self with right alignment. + let mut buf = [MaybeUninit::::uninit(); MAX_DIG_N]; + // Count the number of bytes in buf that are not initialized. + let mut offset = buf.len(); -/// A type that represents a specific radix -/// -/// # Safety -/// -/// `digit` must return an ASCII character. -#[doc(hidden)] -unsafe trait GenericRadix: Sized { - /// The number of digits. - const BASE: u8; - - /// A radix-specific prefix string. - const PREFIX: &'static str; - - /// Converts an integer to corresponding radix digit. - fn digit(x: u8) -> u8; - - /// Format an integer using the radix using a formatter. - fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // The radix can be as low as 2, so we need a buffer of at least 128 - // characters for a base 2 number. - let zero = T::zero(); - let is_nonnegative = x >= zero; - let mut buf = [MaybeUninit::::uninit(); 128]; - let mut offset = buf.len(); - let base = T::from_u8(Self::BASE); - if is_nonnegative { - // Accumulate each digit of the number from the least significant - // to the most significant figure. - loop { - let n = x % base; // Get the current place value. - x = x / base; // Deaccumulate the number. - offset -= 1; - buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer. - if x == zero { - // No more digits left to accumulate. - break; - }; - } - } else { - // Do the same as above, but accounting for two's complement. - loop { - let n = zero - (x % base); // Get the current place value. - x = x / base; // Deaccumulate the number. - offset -= 1; - buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer. - if x == zero { - // No more digits left to accumulate. - break; - }; - } - } - // SAFETY: Starting from `offset`, all elements of the slice have been set. - let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) }; - f.pad_integral(is_nonnegative, Self::PREFIX, buf_slice) - } -} + // Accumulate each digit of the number from the least + // significant to the most significant figure. + let mut remain = *self; + loop { + let digit = remain % BASE; + remain /= BASE; -/// A binary (base 2) radix -#[derive(Clone, PartialEq)] -struct Binary; - -/// An octal (base 8) radix -#[derive(Clone, PartialEq)] -struct Octal; - -/// A hexadecimal (base 16) radix, formatted with lower-case characters -#[derive(Clone, PartialEq)] -struct LowerHex; - -/// A hexadecimal (base 16) radix, formatted with upper-case characters -#[derive(Clone, PartialEq)] -struct UpperHex; - -macro_rules! radix { - ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => { - unsafe impl GenericRadix for $T { - const BASE: u8 = $base; - const PREFIX: &'static str = $prefix; - fn digit(x: u8) -> u8 { - match x { - $($x => $conv,)+ - x => panic!("number not in the range 0..={}: {}", Self::BASE - 1, x), + offset -= 1; + // SAFETY: `remain` will reach 0 and we will break before `offset` wraps + unsafe { core::hint::assert_unchecked(offset < buf.len()) } + buf[offset].write(DIG_TAB[digit as usize]); + if remain == 0 { + break; + } } + + // SAFETY: Starting from `offset`, all elements of the slice have been set. + let digits = unsafe { slice_buffer_to_str(&buf, offset) }; + f.pad_integral(true, $prefix, digits) } } - } -} -radix! { Binary, 2, "0b", x @ 0 ..= 1 => b'0' + x } -radix! { Octal, 8, "0o", x @ 0 ..= 7 => b'0' + x } -radix! { LowerHex, 16, "0x", x @ 0 ..= 9 => b'0' + x, x @ 10 ..= 15 => b'a' + (x - 10) } -radix! { UpperHex, 16, "0x", x @ 0 ..= 9 => b'0' + x, x @ 10 ..= 15 => b'A' + (x - 10) } - -macro_rules! int_base { - (fmt::$Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::$Trait for $T { + impl fmt::$Trait for $Signed { + /// Format signed integers in the two’s-complement form. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - $Radix.fmt_int(*self as $U, f) + fmt::$Trait::fmt(&self.cast_unsigned(), f) } } }; } -macro_rules! integer { - ($Int:ident, $Uint:ident) => { - int_base! { fmt::Binary for $Int as $Uint -> Binary } - int_base! { fmt::Octal for $Int as $Uint -> Octal } - int_base! { fmt::LowerHex for $Int as $Uint -> LowerHex } - int_base! { fmt::UpperHex for $Int as $Uint -> UpperHex } - - int_base! { fmt::Binary for $Uint as $Uint -> Binary } - int_base! { fmt::Octal for $Uint as $Uint -> Octal } - int_base! { fmt::LowerHex for $Uint as $Uint -> LowerHex } - int_base! { fmt::UpperHex for $Uint as $Uint -> UpperHex } +/// Formatting of integers with a non-decimal radix. +macro_rules! radix_integers { + ($Signed:ident, $Unsigned:ident) => { + radix_integer! { fmt::Binary for $Signed and $Unsigned, "0b", b"01" } + radix_integer! { fmt::Octal for $Signed and $Unsigned, "0o", b"01234567" } + radix_integer! { fmt::LowerHex for $Signed and $Unsigned, "0x", b"0123456789abcdef" } + radix_integer! { fmt::UpperHex for $Signed and $Unsigned, "0x", b"0123456789ABCDEF" } }; } -integer! { isize, usize } -integer! { i8, u8 } -integer! { i16, u16 } -integer! { i32, u32 } -integer! { i64, u64 } -integer! { i128, u128 } +radix_integers! { isize, usize } +radix_integers! { i8, u8 } +radix_integers! { i16, u16 } +radix_integers! { i32, u32 } +radix_integers! { i64, u64 } +radix_integers! { i128, u128 } macro_rules! impl_Debug { ($($T:ident)*) => { @@ -205,16 +119,21 @@ unsafe fn slice_buffer_to_str(buf: &[MaybeUninit], offset: usize) -> &str { } macro_rules! impl_Display { - ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => { + ($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => { $( + const _: () = { + assert!($Signed::BITS <= $T::BITS, "need lossless conversion"); + assert!($Unsigned::BITS <= $T::BITS, "need lossless conversion"); + }; + #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Display for $unsigned { + impl fmt::Display for $Unsigned { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[cfg(not(feature = "optimize_for_size"))] { - const MAX_DEC_N: usize = $unsigned::MAX.ilog10() as usize + 1; - // Buffer decimals for $unsigned with right alignment. + const MAX_DEC_N: usize = $Unsigned::MAX.ilog10() as usize + 1; + // Buffer decimals for self with right alignment. let mut buf = [MaybeUninit::::uninit(); MAX_DEC_N]; // SAFETY: `buf` is always big enough to contain all the digits. @@ -222,18 +141,20 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - $gen_name(self.$conv_fn(), true, f) + // Lossless conversion (with as) is asserted at the top of + // this macro. + ${concat($fmt_fn, _small)}(*self as $T, true, f) } } } #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Display for $signed { + impl fmt::Display for $Signed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[cfg(not(feature = "optimize_for_size"))] { - const MAX_DEC_N: usize = $unsigned::MAX.ilog10() as usize + 1; - // Buffer decimals for $unsigned with right alignment. + const MAX_DEC_N: usize = $Unsigned::MAX.ilog10() as usize + 1; + // Buffer decimals for self with right alignment. let mut buf = [MaybeUninit::::uninit(); MAX_DEC_N]; // SAFETY: `buf` is always big enough to contain all the digits. @@ -241,13 +162,15 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - return $gen_name(self.unsigned_abs().$conv_fn(), *self >= 0, f); + // Lossless conversion (with as) is asserted at the top of + // this macro. + return ${concat($fmt_fn, _small)}(self.unsigned_abs() as $T, *self >= 0, f); } } } #[cfg(not(feature = "optimize_for_size"))] - impl $unsigned { + impl $Unsigned { #[doc(hidden)] #[unstable( feature = "fmt_internals", @@ -268,7 +191,7 @@ macro_rules! impl_Display { let mut remain = self; // Format per four digits from the lookup table. - // Four digits need a 16-bit $unsigned or wider. + // Four digits need a 16-bit $Unsigned or wider. while size_of::() > 1 && remain > 999.try_into().expect("branch is not hit for types that cannot fit 999 (u8)") { // SAFETY: All of the decimals fit in buf due to MAX_DEC_N // and the while condition ensures at least 4 more decimals. @@ -327,7 +250,7 @@ macro_rules! impl_Display { } } - impl $signed { + impl $Signed { /// Allows users to write an integer (in signed decimal format) into a variable `buf` of /// type [`NumBuffer`] that is passed by the caller by mutable reference. /// @@ -337,15 +260,15 @@ macro_rules! impl_Display { /// #![feature(int_format_into)] /// use core::fmt::NumBuffer; /// - #[doc = concat!("let n = 0", stringify!($signed), ";")] + #[doc = concat!("let n = 0", stringify!($Signed), ";")] /// let mut buf = NumBuffer::new(); /// assert_eq!(n.format_into(&mut buf), "0"); /// - #[doc = concat!("let n1 = 32", stringify!($signed), ";")] + #[doc = concat!("let n1 = 32", stringify!($Signed), ";")] /// assert_eq!(n1.format_into(&mut buf), "32"); /// - #[doc = concat!("let n2 = ", stringify!($signed::MAX), ";")] - #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($signed::MAX), ".to_string());")] + #[doc = concat!("let n2 = ", stringify!($Signed::MAX), ";")] + #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($Signed::MAX), ".to_string());")] /// ``` #[unstable(feature = "int_format_into", issue = "138215")] pub fn format_into(self, buf: &mut NumBuffer) -> &str { @@ -358,7 +281,9 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.unsigned_abs().$conv_fn(), &mut buf.buf); + // Lossless conversion (with as) is asserted at the top of + // this macro. + offset = ${concat($fmt_fn, _in_buf_small)}(self.unsigned_abs() as $T, &mut buf.buf); } // Only difference between signed and unsigned are these 4 lines. if self < 0 { @@ -370,7 +295,7 @@ macro_rules! impl_Display { } } - impl $unsigned { + impl $Unsigned { /// Allows users to write an integer (in signed decimal format) into a variable `buf` of /// type [`NumBuffer`] that is passed by the caller by mutable reference. /// @@ -380,15 +305,15 @@ macro_rules! impl_Display { /// #![feature(int_format_into)] /// use core::fmt::NumBuffer; /// - #[doc = concat!("let n = 0", stringify!($unsigned), ";")] + #[doc = concat!("let n = 0", stringify!($Unsigned), ";")] /// let mut buf = NumBuffer::new(); /// assert_eq!(n.format_into(&mut buf), "0"); /// - #[doc = concat!("let n1 = 32", stringify!($unsigned), ";")] + #[doc = concat!("let n1 = 32", stringify!($Unsigned), ";")] /// assert_eq!(n1.format_into(&mut buf), "32"); /// - #[doc = concat!("let n2 = ", stringify!($unsigned::MAX), ";")] - #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($unsigned::MAX), ".to_string());")] + #[doc = concat!("let n2 = ", stringify!($Unsigned::MAX), ";")] + #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($Unsigned::MAX), ".to_string());")] /// ``` #[unstable(feature = "int_format_into", issue = "138215")] pub fn format_into(self, buf: &mut NumBuffer) -> &str { @@ -401,7 +326,9 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.$conv_fn(), &mut buf.buf); + // Lossless conversion (with as) is asserted at the top of + // this macro. + offset = ${concat($fmt_fn, _in_buf_small)}(self as $T, &mut buf.buf); } // SAFETY: Starting from `offset`, all elements of the slice have been set. unsafe { slice_buffer_to_str(&buf.buf, offset) } @@ -412,7 +339,7 @@ macro_rules! impl_Display { )* #[cfg(feature = "optimize_for_size")] - fn ${concat(_inner_slow_integer_to_str, $gen_name)}(mut n: $u, buf: &mut [MaybeUninit::]) -> usize { + fn ${concat($fmt_fn, _in_buf_small)}(mut n: $T, buf: &mut [MaybeUninit::]) -> usize { let mut curr = buf.len(); // SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning @@ -433,11 +360,11 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] - fn $gen_name(n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { - const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1; + fn ${concat($fmt_fn, _small)}(n: $T, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const MAX_DEC_N: usize = $T::MAX.ilog(10) as usize + 1; let mut buf = [MaybeUninit::::uninit(); MAX_DEC_N]; - let offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(n, &mut buf); + let offset = ${concat($fmt_fn, _in_buf_small)}(n, &mut buf); // SAFETY: Starting from `offset`, all elements of the slice have been set. let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) }; f.pad_integral(is_nonnegative, "", buf_slice) @@ -446,9 +373,9 @@ macro_rules! impl_Display { } macro_rules! impl_Exp { - ($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => { - fn $name( - mut n: $u, + ($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => { + fn $fmt_fn( + mut n: $T, is_nonnegative: bool, upper: bool, f: &mut fmt::Formatter<'_> @@ -582,32 +509,41 @@ macro_rules! impl_Exp { $( #[stable(feature = "integer_exp_format", since = "1.42.0")] - impl fmt::LowerExp for $t { - #[allow(unused_comparisons)] + impl fmt::LowerExp for $Signed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let is_nonnegative = *self >= 0; let n = if is_nonnegative { - self.$conv_fn() + *self as $T } else { - // convert the negative num to positive by summing 1 to its 2s complement - (!self.$conv_fn()).wrapping_add(1) + self.unsigned_abs() as $T }; - $name(n, is_nonnegative, false, f) + $fmt_fn(n, is_nonnegative, false, f) + } + } + #[stable(feature = "integer_exp_format", since = "1.42.0")] + impl fmt::LowerExp for $Unsigned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + $fmt_fn(*self as $T, true, false, f) } })* + $( #[stable(feature = "integer_exp_format", since = "1.42.0")] - impl fmt::UpperExp for $t { - #[allow(unused_comparisons)] + impl fmt::UpperExp for $Signed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let is_nonnegative = *self >= 0; let n = if is_nonnegative { - self.$conv_fn() + *self as $T } else { - // convert the negative num to positive by summing 1 to its 2s complement - (!self.$conv_fn()).wrapping_add(1) + self.unsigned_abs() as $T }; - $name(n, is_nonnegative, true, f) + $fmt_fn(n, is_nonnegative, true, f) + } + } + #[stable(feature = "integer_exp_format", since = "1.42.0")] + impl fmt::UpperExp for $Unsigned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + $fmt_fn(*self as $T, true, true, f) } })* }; @@ -623,37 +559,20 @@ impl_Debug! { #[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] mod imp { use super::*; - impl_Display!( - i8, u8, - i16, u16, - i32, u32, - i64, u64, - isize, usize, - ; as u64 via to_u64 named fmt_u64 - ); - impl_Exp!( - i8, u8, i16, u16, i32, u32, i64, u64, usize, isize - as u64 via to_u64 named exp_u64 - ); + impl_Display!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into display_u64); + impl_Exp!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into exp_u64); } #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] mod imp { use super::*; - impl_Display!( - i8, u8, - i16, u16, - i32, u32, - isize, usize, - ; as u32 via to_u32 named fmt_u32); - impl_Display!( - i64, u64, - ; as u64 via to_u64 named fmt_u64); - - impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32); - impl_Exp!(i64, u64 as u64 via to_u64 named exp_u64); + impl_Display!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into display_u32); + impl_Display!(i64, u64; as u64 into display_u64); + + impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into exp_u32); + impl_Exp!(i64, u64; as u64 into exp_u64); } -impl_Exp!(i128, u128 as u128 via to_u128 named exp_u128); +impl_Exp!(i128, u128; as u128 into exp_u128); const U128_MAX_DEC_N: usize = u128::MAX.ilog10() as usize + 1; diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 1844cd9808268..3118a6e5ca62e 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -124,6 +124,8 @@ macro_rules! from_str_float_impl { /// * '2.5E-10' /// * '5.' /// * '.5', or, equivalently, '0.5' + /// * '7' + /// * '007' /// * 'inf', '-inf', '+infinity', 'NaN' /// /// Note that alphabetical characters are not case-sensitive. diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index bd2f7445612a7..dbcccdf497c2c 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2494,8 +2494,7 @@ macro_rules! int_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `i32` is used here. + /// Please note that this example is shared among integer types, which is why `i32` is used. /// /// ``` /// #![feature(bigint_helper_methods)] @@ -2525,8 +2524,7 @@ macro_rules! int_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `i32` is used here. + /// Please note that this example is shared among integer types, which is why `i32` is used. /// /// ``` /// #![feature(bigint_helper_methods)] @@ -2563,8 +2561,7 @@ macro_rules! int_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `i32` is used here. + /// Please note that this example is shared among integer types, which is why `i32` is used. /// /// ``` /// #![feature(bigint_helper_methods)] diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs index c7040721b9353..365a82a57e0b9 100644 --- a/library/core/src/num/saturating.rs +++ b/library/core/src/num/saturating.rs @@ -729,8 +729,8 @@ macro_rules! saturating_int_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `i16` is used here. + /// Please note that this example is shared among integer types, which is why `i16` + /// is used. /// /// ``` /// use std::num::Saturating; diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 0afad09bdc6b8..186c6f32cffaa 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2115,8 +2115,7 @@ macro_rules! uint_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `u8` is used here. + /// Please note that this example is shared among integer types, which is why `u8` is used. /// /// ``` /// assert_eq!(10u8.wrapping_mul(12), 120); @@ -2606,8 +2605,8 @@ macro_rules! uint_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. + /// Please note that this example is shared among integer types, which is why why `u32` + /// is used. /// /// ``` /// assert_eq!(5u32.overflowing_mul(2), (10, false)); @@ -2633,8 +2632,7 @@ macro_rules! uint_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. + /// Please note that this example is shared among integer types, which is why `u32` is used. /// /// ``` /// #![feature(bigint_helper_methods)] @@ -2664,8 +2662,7 @@ macro_rules! uint_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. + /// Please note that this example is shared among integer types, which is why `u32` is used. /// /// ``` /// #![feature(bigint_helper_methods)] diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 9ccad4b6459cd..881fe615f800f 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -765,8 +765,8 @@ macro_rules! wrapping_int_impl { /// /// # Examples /// - /// Please note that this example is shared between integer types. - /// Which explains why `i16` is used here. + /// Please note that this example is shared among integer types, which is why `i16` + /// is used. /// /// Basic usage: /// diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 49dbdeb1a6d1c..191fe7711f97a 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -1,5 +1,6 @@ +//! Unicode internals used in liballoc and libstd. Not public API. #![unstable(feature = "unicode_internals", issue = "none")] -#![allow(missing_docs)] +#![doc(hidden)] // for use in alloc, not re-exported in std. #[rustfmt::skip] @@ -31,5 +32,4 @@ mod unicode_data; /// /// The version numbering scheme is explained in /// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4). -#[stable(feature = "unicode_version", since = "1.45.0")] pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION; diff --git a/library/coretests/benches/fmt.rs b/library/coretests/benches/fmt.rs index ee8e981b46b97..f45b921b93933 100644 --- a/library/coretests/benches/fmt.rs +++ b/library/coretests/benches/fmt.rs @@ -162,3 +162,183 @@ fn write_u8_min(bh: &mut Bencher) { black_box(format!("{}", black_box(u8::MIN))); }); } + +#[bench] +fn write_i8_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i8)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i8)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i8)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i8 << 4)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i16_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i16)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i16)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i16)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i16 << 8)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i32_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i32)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i32)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i32)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i32 << 16)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i64_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i64)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i64)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i64)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i64 << 32)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i128_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i128)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i128)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i128)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i128 << 64)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i8_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i8)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i8)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i8)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i8 << 4)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i16_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i16)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i16)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i16)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i16 << 8)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i32_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i32)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i32)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i32)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i32 << 16)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i64_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i64)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i64)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i64)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i64 << 32)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i128_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i128)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i128)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i128)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i128 << 64)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i8_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i8)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i8)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i8)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i8 << 4)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i16_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i16)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i16)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i16)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i16 << 8)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i32_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i32)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i32)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i32)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i32 << 16)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i64_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i64)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i64)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i64)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i64 << 32)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i128_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i128)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i128)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i128)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i128 << 64)).unwrap(); + black_box(&mut buf).clear(); + }); +} diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index d4a584f4d14ff..1ed4f2f9f0c66 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3156,6 +3156,25 @@ pub fn set_permissions>(path: P, perm: Permissions) -> io::Result fs_imp::set_permissions(path.as_ref(), perm.0) } +/// Set the permissions of a file, unless it is a symlink. +/// +/// Note that the non-final path elements are allowed to be symlinks. +/// +/// # Platform-specific behavior +/// +/// Currently unimplemented on Windows. +/// +/// On Unix platforms, this results in a [`FilesystemLoop`] error if the last element is a symlink. +/// +/// This behavior may change in the future. +/// +/// [`FilesystemLoop`]: crate::io::ErrorKind::FilesystemLoop +#[doc(alias = "chmod", alias = "SetFileAttributes")] +#[unstable(feature = "set_permissions_nofollow", issue = "141607")] +pub fn set_permissions_nofollow>(path: P, perm: Permissions) -> io::Result<()> { + fs_imp::set_permissions_nofollow(path.as_ref(), perm) +} + impl DirBuilder { /// Creates a new set of options with default mode/security settings for all /// platforms and also non-recursive. diff --git a/library/std/src/sync/nonpoison/mutex.rs b/library/std/src/sync/nonpoison/mutex.rs index b6861c78f001d..fd1e671d7a3d3 100644 --- a/library/std/src/sync/nonpoison/mutex.rs +++ b/library/std/src/sync/nonpoison/mutex.rs @@ -100,7 +100,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { lock: &'a Mutex, } -/// A [`MutexGuard`] is not `Send` to maximize platform portablity. +/// A [`MutexGuard`] is not `Send` to maximize platform portability. /// /// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to /// release mutex locks on the same thread they were acquired. diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 6205c4fa4ca4b..720c212c65cf7 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -279,7 +279,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { poison: poison::Guard, } -/// A [`MutexGuard`] is not `Send` to maximize platform portablity. +/// A [`MutexGuard`] is not `Send` to maximize platform portability. /// /// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to /// release mutex locks on the same thread they were acquired. diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index d9740e15789aa..dbd782f501809 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -114,6 +114,21 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> { with_native_path(path, &|path| imp::set_perm(path, perm.clone())) } +#[cfg(unix)] +pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> { + use crate::fs::OpenOptions; + use crate::os::unix::fs::OpenOptionsExt; + + OpenOptions::new().custom_flags(libc::O_NOFOLLOW).open(path)?.set_permissions(perm) +} + +#[cfg(not(unix))] +pub fn set_permissions_nofollow(_path: &Path, _perm: crate::fs::Permissions) -> io::Result<()> { + crate::unimplemented!( + "`set_permissions_nofollow` is currently only implemented on Unix platforms" + ) +} + pub fn canonicalize(path: &Path) -> io::Result { with_native_path(path, &imp::canonicalize) } diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 8ec0a0e33023f..6324c1a232af4 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -1,7 +1,7 @@ #![allow(unsafe_op_in_unsafe_fn)] /// The configure builtins provides runtime support compiler-builtin features -/// which require dynamic intialization to work as expected, e.g. aarch64 +/// which require dynamic initialization to work as expected, e.g. aarch64 /// outline-atomics. mod configure_builtins; diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index b7c71b76ee8c5..36ce3f7ef962e 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -188,7 +188,7 @@ pub(crate) mod system_time_internal { Duration::new(epoch, t.nanosecond) } - /// This algorithm is a modifed version of the one described in the post: + /// This algorithm is a modified version of the one described in the post: /// https://howardhinnant.github.io/date_algorithms.html#clive_from_days /// /// The changes are to use 1900-01-01-00:00:00 with timezone -1440 as anchor instead of UNIX @@ -197,7 +197,7 @@ pub(crate) mod system_time_internal { // Check timzone validity assert!(timezone <= 1440 && timezone >= -1440); - // FIXME(#126043): use checked_sub_signed once stablized + // FIXME(#126043): use checked_sub_signed once stabilized let secs = dur.as_secs().checked_add_signed((-timezone as i64) * SECS_IN_MINUTE as i64).unwrap(); diff --git a/library/std_detect/src/detect/arch/loongarch.rs b/library/std_detect/src/detect/arch/loongarch.rs index 68fc600fa8e79..d5a442fbbb8a4 100644 --- a/library/std_detect/src/detect/arch/loongarch.rs +++ b/library/std_detect/src/detect/arch/loongarch.rs @@ -8,6 +8,7 @@ features! { /// Checks if `loongarch` feature is enabled. /// Supported arguments are: /// + /// * `"32s"` /// * `"f"` /// * `"d"` /// * `"frecipe"` @@ -22,6 +23,8 @@ features! { /// * `"lvz"` /// * `"ual"` #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] + @FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] _32s: "32s"; + /// 32S @FEATURE: #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] f: "f"; /// F @FEATURE: #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] d: "d"; diff --git a/library/std_detect/src/detect/os/linux/loongarch.rs b/library/std_detect/src/detect/os/linux/loongarch.rs index e97fda11d08fc..74415266f8b15 100644 --- a/library/std_detect/src/detect/os/linux/loongarch.rs +++ b/library/std_detect/src/detect/os/linux/loongarch.rs @@ -17,22 +17,21 @@ pub(crate) fn detect_features() -> cache::Initializer { // The values are part of the platform-specific [cpucfg] // // [cpucfg]: LoongArch Reference Manual Volume 1: Basic Architecture v1.1 + let cpucfg1: usize; let cpucfg2: usize; - unsafe { - asm!( - "cpucfg {}, {}", - out(reg) cpucfg2, in(reg) 2, - options(pure, nomem, preserves_flags, nostack) - ); - } let cpucfg3: usize; unsafe { asm!( "cpucfg {}, {}", + "cpucfg {}, {}", + "cpucfg {}, {}", + out(reg) cpucfg1, in(reg) 1, + out(reg) cpucfg2, in(reg) 2, out(reg) cpucfg3, in(reg) 3, options(pure, nomem, preserves_flags, nostack) ); } + enable_feature(&mut value, Feature::_32s, bit::test(cpucfg1, 0) || bit::test(cpucfg1, 1)); enable_feature(&mut value, Feature::frecipe, bit::test(cpucfg2, 25)); enable_feature(&mut value, Feature::div32, bit::test(cpucfg2, 26)); enable_feature(&mut value, Feature::lam_bh, bit::test(cpucfg2, 27)); diff --git a/library/std_detect/tests/macro_trailing_commas.rs b/library/std_detect/tests/macro_trailing_commas.rs index 2fee0abdd575b..6072ddf5ac45e 100644 --- a/library/std_detect/tests/macro_trailing_commas.rs +++ b/library/std_detect/tests/macro_trailing_commas.rs @@ -69,6 +69,8 @@ fn aarch64() { #[test] #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] fn loongarch() { + let _ = is_loongarch_feature_detected!("32s"); + let _ = is_loongarch_feature_detected!("32s",); let _ = is_loongarch_feature_detected!("lsx"); let _ = is_loongarch_feature_detected!("lsx",); } diff --git a/src/ci/docker/host-x86_64/tidy/Dockerfile b/src/ci/docker/host-x86_64/tidy/Dockerfile index ee1ae5410ee81..c8558689d3ba9 100644 --- a/src/ci/docker/host-x86_64/tidy/Dockerfile +++ b/src/ci/docker/host-x86_64/tidy/Dockerfile @@ -45,4 +45,4 @@ RUN bash -c 'npm install -g eslint@$(cat /tmp/eslint.version)' # NOTE: intentionally uses python2 for x.py so we can test it still works. # validate-toolstate only runs in our CI, so it's ok for it to only support python3. ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 \ - src/tools/tidy tidyselftest --extra-checks=py,cpp,js + src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index a0acfdf0e4ab5..28d3dc32a63ee 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -534,10 +534,10 @@ tests, and will reject patches that fail to build or pass the testsuite on a target. We hold tier 1 targets to our highest standard of requirements. A proposed new tier 1 target must be reviewed and approved by the compiler team -based on these requirements. In addition, the release team must approve the -viability and value of supporting the target. For a tier 1 target, this will +based on these requirements. In addition, the infra team must approve the +viability of supporting the target. For a tier 1 target, this will typically take place via a full RFC proposing the target, to be jointly -reviewed and approved by the compiler team and release team. +reviewed and approved by the compiler team and infra team. In addition, the infrastructure team must approve the integration of the target into Continuous Integration (CI), and the tier 1 CI-related requirements. This @@ -617,7 +617,7 @@ including the infrastructure team in the RFC proposing the target. A tier 1 target may be demoted if it no longer meets these requirements but still meets the requirements for a lower tier. Any proposal for demotion of a tier 1 target requires a full RFC process, with approval by the compiler and -release teams. Any such proposal will be communicated widely to the Rust +infra teams. Any such proposal will be communicated widely to the Rust community, both when initially proposed and before being dropped from a stable release. A tier 1 target is highly unlikely to be directly removed without first being demoted to tier 2 or tier 3. (The amount of time between such @@ -628,7 +628,7 @@ planned and scheduled action.) Raising the baseline expectations of a tier 1 target (such as the minimum CPU features or OS version required) requires the approval of the compiler and -release teams, and should be widely communicated as well, but does not +infra teams, and should be widely communicated as well, but does not necessarily require a full RFC. ### Tier 1 with host tools @@ -638,11 +638,11 @@ host (such as `rustc` and `cargo`). This allows the target to be used as a development platform, not just a compilation target. A proposed new tier 1 target with host tools must be reviewed and approved by -the compiler team based on these requirements. In addition, the release team -must approve the viability and value of supporting host tools for the target. +the compiler team based on these requirements. In addition, the infra team +must approve the viability of supporting host tools for the target. For a tier 1 target, this will typically take place via a full RFC proposing the target, to be jointly reviewed and approved by the compiler team and -release team. +infra team. In addition, the infrastructure team must approve the integration of the target's host tools into Continuous Integration (CI), and the CI-related @@ -697,7 +697,7 @@ target with host tools may be demoted (including having its host tools dropped, or being demoted to tier 2 with host tools) if it no longer meets these requirements but still meets the requirements for a lower tier. Any proposal for demotion of a tier 1 target (with or without host tools) requires a full -RFC process, with approval by the compiler and release teams. Any such proposal +RFC process, with approval by the compiler and infra teams. Any such proposal will be communicated widely to the Rust community, both when initially proposed and before being dropped from a stable release. diff --git a/src/doc/unstable-book/src/compiler-flags/indirect-branch-cs-prefix.md b/src/doc/unstable-book/src/compiler-flags/indirect-branch-cs-prefix.md new file mode 100644 index 0000000000000..040e2d4170131 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/indirect-branch-cs-prefix.md @@ -0,0 +1,19 @@ +# `indirect-branch-cs-prefix` + +The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/116852. + +------------------------ + +Option `-Zindirect-branch-cs-prefix` controls whether a `cs` prefix is added to +`call` and `jmp` to indirect thunks. + +It is equivalent to [Clang]'s and [GCC]'s `-mindirect-branch-cs-prefix`. The +Linux kernel uses it for RETPOLINE builds. For details, see +[LLVM commit 6f867f910283] ("[X86] Support ``-mindirect-branch-cs-prefix`` for +call and jmp to indirect thunk") which introduces the feature. + +Only x86 and x86_64 are supported. + +[Clang]: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mindirect-branch-cs-prefix +[GCC]: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mindirect-branch-cs-prefix +[LLVM commit 6f867f910283]: https://github.com/llvm/llvm-project/commit/6f867f9102838ebe314c1f3661fdf95700386e5a diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 57f9f16751da4..cb6837dd6140d 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -47,7 +47,7 @@ pub(crate) struct Cache { /// Similar to `paths`, but only holds external paths. This is only used for /// generating explicit hyperlinks to other crates. - pub(crate) external_paths: FxHashMap, ItemType)>, + pub(crate) external_paths: FxIndexMap, ItemType)>, /// Maps local `DefId`s of exported types to fully qualified paths. /// Unlike 'paths', this mapping ignores any renames that occur diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index af43fd48dd156..20fc6b75d3773 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1649,7 +1649,7 @@ function preLoadCss(cssUrl) { ["⏎", "Go to active search result"], ["+", "Expand all sections"], ["-", "Collapse all sections"], - // for the sake of brevity, we don't say "inherint impl blocks", + // for the sake of brevity, we don't say "inherit impl blocks", // although that would be more correct, // since trait impl blocks are collapsed by - ["_", "Collapse all sections, including impl blocks"], diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 49021b1c4a2c4..4cad36cf3831c 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1111,6 +1111,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { // For foreign items, try to see if we can emulate them. if ecx.tcx.is_foreign_item(instance.def_id()) { + let _trace = enter_trace_span!("emulate_foreign_item"); // An external function call that does not have a MIR body. We either find MIR elsewhere // or emulate its effect. // This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need @@ -1123,6 +1124,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { } // Otherwise, load the MIR. + let _trace = enter_trace_span!("load_mir"); interp_ok(Some((ecx.load_mir(instance.def, None)?, instance))) } diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs new file mode 100644 index 0000000000000..b91a41d7650e1 --- /dev/null +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs @@ -0,0 +1,34 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows +// Validation forces more things into memory, which we can't have here. +//@compile-flags: -Zmiri-disable-validation +#![feature(custom_mir, core_intrinsics)] +use std::intrinsics::mir::*; + +pub struct S(i32); + +#[custom_mir(dialect = "runtime", phase = "optimized")] +fn main() { + mir! { + let _unit: (); + { + let staging = S(42); // This forces `staging` into memory... + let non_copy = staging; // ... so we move it to a non-inmemory local here. + // This specifically uses a type with scalar representation to tempt Miri to use the + // efficient way of storing local variables (outside adressable memory). + Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) + //~[stack]^ ERROR: not granting access + //~[tree]| ERROR: /read access .* forbidden/ + } + after_call = { + Return() + } + } +} + +pub fn callee(x: S, mut y: S) { + // With the setup above, if `x` and `y` are both moved, + // then writing to `y` will change the value stored in `x`! + y.0 = 0; + assert_eq!(x.0, 42); +} diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr new file mode 100644 index 0000000000000..0c1100cae63de --- /dev/null +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: not granting access to tag because that would remove [Unique for ] which is strongly protected + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information +help: was created here, as the root tag for ALLOC + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: is this argument + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | y.0 = 0; + | ^^^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr new file mode 100644 index 0000000000000..f376c30c87927 --- /dev/null +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr @@ -0,0 +1,33 @@ +error: Undefined Behavior: read access through (root of the allocation) at ALLOC[0x0] is forbidden + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag (root of the allocation) is foreign to the protected tag (i.e., it is not a child) + = help: this foreign read access would cause the protected tag (currently Active) to become Disabled + = help: protected tags must never be Disabled +help: the accessed tag was created here + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the protected tag was created here, in the initial state Reserved + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | y.0 = 0; + | ^^^^^^^ +help: the protected tag later transitioned to Active due to a child write access at offsets [0x0..0x4] + --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + | +LL | y.0 = 0; + | ^^^^^^^ + = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference + = note: BACKTRACE (of the first span): + = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr index 2409154725846..d478568ceaeb5 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr @@ -11,8 +11,8 @@ LL | unsafe { ptr.read() }; note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Uninitialized memory occurred at ALLOC[0x0..0x4], in this allocation: ALLOC (stack variable, size: 4, align: 4) { diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.rs index a6e0134bd173f..dc22e129e18a2 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.rs +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.rs @@ -10,11 +10,11 @@ use std::intrinsics::mir::*; pub fn main() { mir! { { - let x = 0; - let ptr = &raw mut x; + let _x = 0; + let ptr = &raw mut _x; // We arrange for `myfun` to have a pointer that aliases // its return place. Even just reading from that pointer is UB. - Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) } after_call = { @@ -25,7 +25,7 @@ pub fn main() { fn myfun(ptr: *mut i32) -> i32 { unsafe { ptr.read() }; - //~[stack]^ ERROR: not granting access + //~[stack]^ ERROR: does not exist in the borrow stack //~[tree]| ERROR: /read access .* forbidden/ //~[none]| ERROR: uninitialized // Without an aliasing model, reads are "fine" but at least they return uninit data. diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr index 77cc0332a1c42..86adbab353b48 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: not granting access to tag because that would remove [Unique for ] which is strongly protected +error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | LL | unsafe { ptr.read() }; - | ^^^^^^^^^^ Undefined Behavior occurred here + | ^^^^^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -11,12 +11,12 @@ help: was created by a SharedReadWrite retag at offsets [0x0..0x4] | LL | / mir! { LL | | { -LL | | let x = 0; -LL | | let ptr = &raw mut x; +LL | | let _x = 0; +LL | | let ptr = &raw mut _x; ... | LL | | } | |_____^ -help: is this argument +help: was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | LL | unsafe { ptr.read() }; @@ -26,8 +26,8 @@ LL | unsafe { ptr.read() }; note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr index bae3819c97977..a1cf0b730eba1 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr @@ -13,8 +13,8 @@ help: the accessed tag was created here | LL | / mir! { LL | | { -LL | | let x = 0; -LL | | let ptr = &raw mut x; +LL | | let _x = 0; +LL | | let ptr = &raw mut _x; ... | LL | | } | |_____^ @@ -34,8 +34,8 @@ LL | unsafe { ptr.read() }; note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.rs index 6155e925c4b99..2fddaf37235b2 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.rs +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.rs @@ -14,7 +14,7 @@ pub fn main() { let ptr = &raw mut _x; // We arrange for `myfun` to have a pointer that aliases // its return place. Writing to that pointer is UB. - Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) } after_call = { @@ -26,7 +26,7 @@ pub fn main() { fn myfun(ptr: *mut i32) -> i32 { // This overwrites the return place, which shouldn't be possible through another pointer. unsafe { ptr.write(0) }; - //~[stack]^ ERROR: strongly protected + //~[stack]^ ERROR: does not exist in the borrow stack //~[tree]| ERROR: /write access .* forbidden/ 13 } diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr index 828b2339f8c0d..faae6172d7510 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: not granting access to tag because that would remove [Unique for ] which is strongly protected +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^ Undefined Behavior occurred here + | ^^^^^^^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -16,7 +16,7 @@ LL | | let ptr = &raw mut _x; ... | LL | | } | |_____^ -help: is this argument +help: was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | LL | unsafe { ptr.write(0) }; @@ -26,8 +26,8 @@ LL | unsafe { ptr.write(0) }; note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr index e0df9370fee80..01d15f38af6df 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr @@ -34,8 +34,8 @@ LL | unsafe { ptr.write(0) }; note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs index 37ee7ae1b0dc0..5f3ecb6502273 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs @@ -16,7 +16,7 @@ pub fn main() { let ptr = &raw mut _x; // We arrange for `myfun` to have a pointer that aliases // its return place. Writing to that pointer is UB. - Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) } after_call = { @@ -32,7 +32,7 @@ fn myfun(ptr: *mut i32) -> i32 { fn myfun2(ptr: *mut i32) -> i32 { // This overwrites the return place, which shouldn't be possible through another pointer. unsafe { ptr.write(0) }; - //~[stack]^ ERROR: strongly protected + //~[stack]^ ERROR: does not exist in the borrow stack //~[tree]| ERROR: /write access .* forbidden/ 13 } diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr index f5183cfaf5b07..1a18857bb1755 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: not granting access to tag because that would remove [Unique for ] which is strongly protected +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^ Undefined Behavior occurred here + | ^^^^^^^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -16,18 +16,18 @@ LL | | let ptr = &raw mut _x; ... | LL | | } | |_____^ -help: is this argument +help: was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | -LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | become myfun2(ptr) + | ^^^^^^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): = note: inside `myfun2` at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr index fa03ed6869bc4..812ddb94a735b 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr @@ -34,8 +34,8 @@ LL | unsafe { ptr.write(0) }; note: inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | -LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index f90f716cd9501..31169ec596775 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -41,7 +41,6 @@ const RUFF_CONFIG_PATH: &[&str] = &["src", "tools", "tidy", "config", "ruff.toml const RUFF_CACHE_PATH: &[&str] = &["cache", "ruff_cache"]; const PIP_REQ_PATH: &[&str] = &["src", "tools", "tidy", "config", "requirements.txt"]; -// this must be kept in sync with with .github/workflows/spellcheck.yml const SPELLCHECK_DIRS: &[&str] = &["compiler", "library", "src/bootstrap", "src/librustdoc"]; pub fn check( @@ -51,6 +50,7 @@ pub fn check( librustdoc_path: &Path, tools_path: &Path, npm: &Path, + cargo: &Path, bless: bool, extra_checks: Option<&str>, pos_args: &[String], @@ -63,6 +63,7 @@ pub fn check( librustdoc_path, tools_path, npm, + cargo, bless, extra_checks, pos_args, @@ -78,6 +79,7 @@ fn check_impl( librustdoc_path: &Path, tools_path: &Path, npm: &Path, + cargo: &Path, bless: bool, extra_checks: Option<&str>, pos_args: &[String], @@ -293,7 +295,7 @@ fn check_impl( } else { eprintln!("spellcheck files"); } - spellcheck_runner(&args)?; + spellcheck_runner(root_path, &outdir, &cargo, &args)?; } if js_lint || js_typecheck { @@ -576,34 +578,25 @@ fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { if status.success() { Ok(()) } else { Err(Error::FailedCheck("shellcheck")) } } -/// Check that spellchecker is installed then run it at the given path -fn spellcheck_runner(args: &[&str]) -> Result<(), Error> { - // sync version with .github/workflows/spellcheck.yml - let expected_version = "typos-cli 1.34.0"; - match Command::new("typos").arg("--version").output() { - Ok(o) => { - let stdout = String::from_utf8_lossy(&o.stdout); - if stdout.trim() != expected_version { - return Err(Error::Version { - program: "typos", - required: expected_version, - installed: stdout.trim().to_string(), - }); +/// Ensure that spellchecker is installed then run it at the given path +fn spellcheck_runner( + src_root: &Path, + outdir: &Path, + cargo: &Path, + args: &[&str], +) -> Result<(), Error> { + let bin_path = + crate::ensure_version_or_cargo_install(outdir, cargo, "typos-cli", "typos", "1.34.0")?; + match Command::new(bin_path).current_dir(src_root).args(args).status() { + Ok(status) => { + if status.success() { + Ok(()) + } else { + Err(Error::FailedCheck("typos")) } } - Err(e) if e.kind() == io::ErrorKind::NotFound => { - return Err(Error::MissingReq( - "typos", - "spellcheck file checks", - // sync version with .github/workflows/spellcheck.yml - Some("install tool via `cargo install typos-cli@1.34.0`".to_owned()), - )); - } - Err(e) => return Err(e.into()), + Err(err) => Err(Error::Generic(format!("failed to run typos tool: {err:?}"))), } - - let status = Command::new("typos").args(args).status()?; - if status.success() { Ok(()) } else { Err(Error::FailedCheck("typos")) } } /// Check git for tracked files matching an extension diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 4ea9d051ddb5e..37713cbf75e9b 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -4,7 +4,9 @@ //! to be used by tools. use std::ffi::OsStr; +use std::path::{Path, PathBuf}; use std::process::Command; +use std::{env, io}; use build_helper::ci::CiEnv; use build_helper::git::{GitConfig, get_closest_upstream_commit}; @@ -180,6 +182,70 @@ pub fn files_modified(ci_info: &CiInfo, pred: impl Fn(&str) -> bool) -> bool { !v.is_empty() } +/// If the given executable is installed with the given version, use that, +/// otherwise install via cargo. +pub fn ensure_version_or_cargo_install( + build_dir: &Path, + cargo: &Path, + pkg_name: &str, + bin_name: &str, + version: &str, +) -> io::Result { + // ignore the process exit code here and instead just let the version number check fail. + // we also importantly don't return if the program wasn't installed, + // instead we want to continue to the fallback. + 'ck: { + // FIXME: rewrite as if-let chain once this crate is 2024 edition. + let Ok(output) = Command::new(bin_name).arg("--version").output() else { + break 'ck; + }; + let Ok(s) = str::from_utf8(&output.stdout) else { + break 'ck; + }; + let Some(v) = s.trim().split_whitespace().last() else { + break 'ck; + }; + if v == version { + return Ok(PathBuf::from(bin_name)); + } + } + + let tool_root_dir = build_dir.join("misc-tools"); + let tool_bin_dir = tool_root_dir.join("bin"); + eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); + // use --force to ensure that if the required version is bumped, we update it. + // use --target-dir to ensure we have a build cache so repeated invocations aren't slow. + // modify PATH so that cargo doesn't print a warning telling the user to modify the path. + let cargo_exit_code = Command::new(cargo) + .args(["install", "--locked", "--force", "--quiet"]) + .arg("--root") + .arg(&tool_root_dir) + .arg("--target-dir") + .arg(tool_root_dir.join("target")) + .arg(format!("{pkg_name}@{version}")) + .env( + "PATH", + env::join_paths( + env::split_paths(&env::var("PATH").unwrap()) + .chain(std::iter::once(tool_bin_dir.clone())), + ) + .expect("build dir contains invalid char"), + ) + .env("RUSTFLAGS", "-Copt-level=0") + .spawn()? + .wait()?; + if !cargo_exit_code.success() { + return Err(io::Error::other("cargo install failed")); + } + let bin_path = tool_bin_dir.join(bin_name); + assert!( + matches!(bin_path.try_exists(), Ok(true)), + "cargo install did not produce the expected binary" + ); + eprintln!("finished building tool {bin_name}"); + Ok(bin_path) +} + pub mod alphabetical; pub mod bins; pub mod debug_artifacts; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index cd2567ddb64bf..bfe30258915ea 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -184,6 +184,7 @@ fn main() { &librustdoc_path, &tools_path, &npm, + &cargo, bless, extra_checks, pos_args diff --git a/tests/assembly-llvm/x86_64-indirect-branch-cs-prefix.rs b/tests/assembly-llvm/x86_64-indirect-branch-cs-prefix.rs new file mode 100644 index 0000000000000..8e4470ee4514c --- /dev/null +++ b/tests/assembly-llvm/x86_64-indirect-branch-cs-prefix.rs @@ -0,0 +1,27 @@ +// Test that the `cs` prefix is (not) added into a `call` and a `jmp` to the +// indirect thunk when the `-Zindirect-branch-cs-prefix` flag is (not) set. + +//@ revisions: unset set +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 -Cunsafe-allow-abi-mismatch=retpoline,retpoline-external-thunk,indirect-branch-cs-prefix -Zretpoline-external-thunk +//@ [set] compile-flags: -Zindirect-branch-cs-prefix +//@ only-x86_64 +//@ ignore-apple Symbol is called `___x86_indirect_thunk` (Darwin's extra underscore) + +#![crate_type = "lib"] + +// CHECK-LABEL: foo: +#[no_mangle] +pub fn foo(g: fn()) { + // unset-NOT: cs + // unset: callq {{__x86_indirect_thunk.*}} + // set: cs + // set-NEXT: callq {{__x86_indirect_thunk.*}} + g(); + + // unset-NOT: cs + // unset: jmp {{__x86_indirect_thunk.*}} + // set: cs + // set-NEXT: jmp {{__x86_indirect_thunk.*}} + g(); +} diff --git a/tests/codegen-llvm/indirect-branch-cs-prefix.rs b/tests/codegen-llvm/indirect-branch-cs-prefix.rs new file mode 100644 index 0000000000000..df25008d5f09b --- /dev/null +++ b/tests/codegen-llvm/indirect-branch-cs-prefix.rs @@ -0,0 +1,18 @@ +// Test that the `indirect_branch_cs_prefix` module attribute is (not) +// emitted when the `-Zindirect-branch-cs-prefix` flag is (not) set. + +//@ add-core-stubs +//@ revisions: unset set +//@ needs-llvm-components: x86 +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ [set] compile-flags: -Zindirect-branch-cs-prefix + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// unset-NOT: !{{[0-9]+}} = !{i32 4, !"indirect_branch_cs_prefix", i32 1} +// set: !{{[0-9]+}} = !{i32 4, !"indirect_branch_cs_prefix", i32 1} diff --git a/tests/ui-fulldeps/internal-lints/query_stability.rs b/tests/ui-fulldeps/internal-lints/query_stability.rs index 7b897fabd2d80..92c1d6bf7f8e9 100644 --- a/tests/ui-fulldeps/internal-lints/query_stability.rs +++ b/tests/ui-fulldeps/internal-lints/query_stability.rs @@ -1,4 +1,5 @@ //@ compile-flags: -Z unstable-options +//@ ignore-stage1 #![feature(rustc_private)] #![deny(rustc::potential_query_instability)] @@ -34,4 +35,16 @@ fn main() { //~^ ERROR using `values_mut` can result in unstable query results *val = *val + 10; } + + FxHashMap::::default().extend(x); + //~^ ERROR using `into_iter` can result in unstable query results +} + +fn hide_into_iter(x: impl IntoIterator) -> impl Iterator { + x.into_iter() +} + +fn take(map: std::collections::HashMap) { + _ = hide_into_iter(map); + //~^ ERROR using `into_iter` can result in unstable query results } diff --git a/tests/ui-fulldeps/internal-lints/query_stability.stderr b/tests/ui-fulldeps/internal-lints/query_stability.stderr index 43b156dc20a3c..e5bb0453f90d5 100644 --- a/tests/ui-fulldeps/internal-lints/query_stability.stderr +++ b/tests/ui-fulldeps/internal-lints/query_stability.stderr @@ -1,18 +1,18 @@ error: using `drain` can result in unstable query results - --> $DIR/query_stability.rs:13:16 + --> $DIR/query_stability.rs:14:16 | LL | for _ in x.drain() {} | ^^^^^ | = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale note: the lint level is defined here - --> $DIR/query_stability.rs:4:9 + --> $DIR/query_stability.rs:5:9 | LL | #![deny(rustc::potential_query_instability)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `iter` can result in unstable query results - --> $DIR/query_stability.rs:16:16 + --> $DIR/query_stability.rs:17:16 | LL | for _ in x.iter() {} | ^^^^ @@ -20,7 +20,7 @@ LL | for _ in x.iter() {} = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale error: using `iter_mut` can result in unstable query results - --> $DIR/query_stability.rs:19:36 + --> $DIR/query_stability.rs:20:36 | LL | for _ in Some(&mut x).unwrap().iter_mut() {} | ^^^^^^^^ @@ -28,7 +28,7 @@ LL | for _ in Some(&mut x).unwrap().iter_mut() {} = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale error: using `into_iter` can result in unstable query results - --> $DIR/query_stability.rs:22:14 + --> $DIR/query_stability.rs:23:14 | LL | for _ in x {} | ^ @@ -36,7 +36,7 @@ LL | for _ in x {} = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale error: using `keys` can result in unstable query results - --> $DIR/query_stability.rs:26:15 + --> $DIR/query_stability.rs:27:15 | LL | let _ = x.keys(); | ^^^^ @@ -44,7 +44,7 @@ LL | let _ = x.keys(); = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale error: using `values` can result in unstable query results - --> $DIR/query_stability.rs:29:15 + --> $DIR/query_stability.rs:30:15 | LL | let _ = x.values(); | ^^^^^^ @@ -52,12 +52,28 @@ LL | let _ = x.values(); = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale error: using `values_mut` can result in unstable query results - --> $DIR/query_stability.rs:33:18 + --> $DIR/query_stability.rs:34:18 | LL | for val in x.values_mut() { | ^^^^^^^^^^ | = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale -error: aborting due to 7 previous errors +error: using `into_iter` can result in unstable query results + --> $DIR/query_stability.rs:39:38 + | +LL | FxHashMap::::default().extend(x); + | ^^^^^^^^^ + | + = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale + +error: using `into_iter` can result in unstable query results + --> $DIR/query_stability.rs:48:9 + | +LL | _ = hide_into_iter(map); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale + +error: aborting due to 9 previous errors diff --git a/tests/ui/issues/issue-8498.rs b/tests/ui/array-slice-vec/matching-on-vector-slice-option-8498.rs similarity index 91% rename from tests/ui/issues/issue-8498.rs rename to tests/ui/array-slice-vec/matching-on-vector-slice-option-8498.rs index 92904e2198f68..e243a247ed518 100644 --- a/tests/ui/issues/issue-8498.rs +++ b/tests/ui/array-slice-vec/matching-on-vector-slice-option-8498.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8498 //@ run-pass pub fn main() { diff --git a/tests/ui/issues/issue-7784.rs b/tests/ui/array-slice-vec/pattern-matching-fixed-length-vectors-7784.rs similarity index 93% rename from tests/ui/issues/issue-7784.rs rename to tests/ui/array-slice-vec/pattern-matching-fixed-length-vectors-7784.rs index 90b88ae572764..7d987e92b63aa 100644 --- a/tests/ui/issues/issue-7784.rs +++ b/tests/ui/array-slice-vec/pattern-matching-fixed-length-vectors-7784.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7784 //@ run-pass use std::ops::Add; diff --git a/tests/ui/issues/issue-78622.rs b/tests/ui/associated-consts/ambiguous-associated-type-error-78622.rs similarity index 67% rename from tests/ui/issues/issue-78622.rs rename to tests/ui/associated-consts/ambiguous-associated-type-error-78622.rs index c00fd26606367..9763be1ecb219 100644 --- a/tests/ui/issues/issue-78622.rs +++ b/tests/ui/associated-consts/ambiguous-associated-type-error-78622.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78622 #![crate_type = "lib"] struct S; diff --git a/tests/ui/issues/issue-78622.stderr b/tests/ui/associated-consts/ambiguous-associated-type-error-78622.stderr similarity index 87% rename from tests/ui/issues/issue-78622.stderr rename to tests/ui/associated-consts/ambiguous-associated-type-error-78622.stderr index 432913a0fc9c1..4dff1364af777 100644 --- a/tests/ui/issues/issue-78622.stderr +++ b/tests/ui/associated-consts/ambiguous-associated-type-error-78622.stderr @@ -1,5 +1,5 @@ error[E0223]: ambiguous associated type - --> $DIR/issue-78622.rs:5:5 + --> $DIR/ambiguous-associated-type-error-78622.rs:6:5 | LL | S::A:: {} | ^^^^ diff --git a/tests/ui/issues/issue-78957.rs b/tests/ui/attributes/invalid-attributes-on-const-params-78957.rs similarity index 95% rename from tests/ui/issues/issue-78957.rs rename to tests/ui/attributes/invalid-attributes-on-const-params-78957.rs index 2ff92612e1852..106b9ae269068 100644 --- a/tests/ui/issues/issue-78957.rs +++ b/tests/ui/attributes/invalid-attributes-on-const-params-78957.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78957 #![deny(unused_attributes)] use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-78957.stderr b/tests/ui/attributes/invalid-attributes-on-const-params-78957.stderr similarity index 80% rename from tests/ui/issues/issue-78957.stderr rename to tests/ui/attributes/invalid-attributes-on-const-params-78957.stderr index d271b1840fb5a..f8010b4ea687c 100644 --- a/tests/ui/issues/issue-78957.stderr +++ b/tests/ui/attributes/invalid-attributes-on-const-params-78957.stderr @@ -1,5 +1,5 @@ error: `#[inline]` attribute cannot be used on function params - --> $DIR/issue-78957.rs:5:16 + --> $DIR/invalid-attributes-on-const-params-78957.rs:6:16 | LL | pub struct Foo<#[inline] const N: usize>; | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | pub struct Foo<#[inline] const N: usize>; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on function params - --> $DIR/issue-78957.rs:13:17 + --> $DIR/invalid-attributes-on-const-params-78957.rs:14:17 | LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); | ^^^^^^^^^ @@ -15,7 +15,7 @@ LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on function params - --> $DIR/issue-78957.rs:21:17 + --> $DIR/invalid-attributes-on-const-params-78957.rs:22:17 | LL | pub struct Foo3<#[inline] T>(PhantomData); | ^^^^^^^^^ @@ -23,25 +23,25 @@ LL | pub struct Foo3<#[inline] T>(PhantomData); = help: `#[inline]` can only be applied to functions error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-78957.rs:10:23 + --> $DIR/invalid-attributes-on-const-params-78957.rs:11:23 | LL | pub struct Baz<#[repr(C)] const N: usize>; | ^ -------------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-78957.rs:18:24 + --> $DIR/invalid-attributes-on-const-params-78957.rs:19:24 | LL | pub struct Baz2<#[repr(C)] 'a>(PhantomData<&'a ()>); | ^ -- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-78957.rs:26:24 + --> $DIR/invalid-attributes-on-const-params-78957.rs:27:24 | LL | pub struct Baz3<#[repr(C)] T>(PhantomData); | ^ - not a struct, enum, or union error: `#[cold]` attribute cannot be used on function params - --> $DIR/issue-78957.rs:7:16 + --> $DIR/invalid-attributes-on-const-params-78957.rs:8:16 | LL | pub struct Bar<#[cold] const N: usize>; | ^^^^^^^ @@ -49,13 +49,13 @@ LL | pub struct Bar<#[cold] const N: usize>; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[cold]` can only be applied to functions note: the lint level is defined here - --> $DIR/issue-78957.rs:1:9 + --> $DIR/invalid-attributes-on-const-params-78957.rs:2:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ error: `#[cold]` attribute cannot be used on function params - --> $DIR/issue-78957.rs:15:17 + --> $DIR/invalid-attributes-on-const-params-78957.rs:16:17 | LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); | ^^^^^^^ @@ -64,7 +64,7 @@ LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); = help: `#[cold]` can only be applied to functions error: `#[cold]` attribute cannot be used on function params - --> $DIR/issue-78957.rs:23:17 + --> $DIR/invalid-attributes-on-const-params-78957.rs:24:17 | LL | pub struct Bar3<#[cold] T>(PhantomData); | ^^^^^^^ diff --git a/tests/ui/issues/issue-77218/issue-77218.fixed b/tests/ui/binding/invalid-assignment-in-while-loop-77218.fixed similarity index 73% rename from tests/ui/issues/issue-77218/issue-77218.fixed rename to tests/ui/binding/invalid-assignment-in-while-loop-77218.fixed index 6ce9dd1c2c57a..aa662ead21ac8 100644 --- a/tests/ui/issues/issue-77218/issue-77218.fixed +++ b/tests/ui/binding/invalid-assignment-in-while-loop-77218.fixed @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/77218 //@ run-rustfix fn main() { let value = [7u8]; diff --git a/tests/ui/issues/issue-77218/issue-77218.rs b/tests/ui/binding/invalid-assignment-in-while-loop-77218.rs similarity index 73% rename from tests/ui/issues/issue-77218/issue-77218.rs rename to tests/ui/binding/invalid-assignment-in-while-loop-77218.rs index 14edc065d0e63..9f249180e83a2 100644 --- a/tests/ui/issues/issue-77218/issue-77218.rs +++ b/tests/ui/binding/invalid-assignment-in-while-loop-77218.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/77218 //@ run-rustfix fn main() { let value = [7u8]; diff --git a/tests/ui/issues/issue-77218/issue-77218.stderr b/tests/ui/binding/invalid-assignment-in-while-loop-77218.stderr similarity index 88% rename from tests/ui/issues/issue-77218/issue-77218.stderr rename to tests/ui/binding/invalid-assignment-in-while-loop-77218.stderr index e98e69314d91d..e6baf349d28ad 100644 --- a/tests/ui/issues/issue-77218/issue-77218.stderr +++ b/tests/ui/binding/invalid-assignment-in-while-loop-77218.stderr @@ -1,5 +1,5 @@ error[E0070]: invalid left-hand side of assignment - --> $DIR/issue-77218.rs:4:19 + --> $DIR/invalid-assignment-in-while-loop-77218.rs:5:19 | LL | while Some(0) = value.get(0) {} | - ^ diff --git a/tests/ui/issues/issue-78192.rs b/tests/ui/borrowck/incorrect-use-after-storage-end-78192.rs similarity index 82% rename from tests/ui/issues/issue-78192.rs rename to tests/ui/borrowck/incorrect-use-after-storage-end-78192.rs index bec2a82910cfa..99a1d37eb4de7 100644 --- a/tests/ui/issues/issue-78192.rs +++ b/tests/ui/borrowck/incorrect-use-after-storage-end-78192.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78192 //@ run-pass #![allow(unused_assignments)] diff --git a/tests/ui/issues/issue-7660.rs b/tests/ui/borrowck/rvalue-lifetime-match-equivalence-7660.rs similarity index 88% rename from tests/ui/issues/issue-7660.rs rename to tests/ui/borrowck/rvalue-lifetime-match-equivalence-7660.rs index 104cdad8f7bb7..90526de14e758 100644 --- a/tests/ui/issues/issue-7660.rs +++ b/tests/ui/borrowck/rvalue-lifetime-match-equivalence-7660.rs @@ -1,9 +1,9 @@ +// https://github.com/rust-lang/rust/issues/7660 //@ run-pass #![allow(unused_variables)] // Regression test for issue 7660 // rvalue lifetime too short when equivalent `match` works - use std::collections::HashMap; struct A(isize, isize); diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 5dd81f486c89b..f64481473921a 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -6,6 +6,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); | = note: expected values for `target_feature` are: `10e60` `2e3` +`32s` `3e3r1` `3e3r2` `3e3r3` diff --git a/tests/ui/issues/issue-76042.rs b/tests/ui/codegen/i128-shift-overflow-check-76042.rs similarity index 85% rename from tests/ui/issues/issue-76042.rs rename to tests/ui/codegen/i128-shift-overflow-check-76042.rs index 279e860459d2c..7ae0806216cd6 100644 --- a/tests/ui/issues/issue-76042.rs +++ b/tests/ui/codegen/i128-shift-overflow-check-76042.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/76042 //@ run-pass //@ compile-flags: -Coverflow-checks=off -Ccodegen-units=1 -Copt-level=0 diff --git a/tests/ui/issues/issue-8248.rs b/tests/ui/coercion/mut-trait-coercion-8248.rs similarity index 81% rename from tests/ui/issues/issue-8248.rs rename to tests/ui/coercion/mut-trait-coercion-8248.rs index 95f626658cc67..a45a4d94315f1 100644 --- a/tests/ui/issues/issue-8248.rs +++ b/tests/ui/coercion/mut-trait-coercion-8248.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8248 //@ run-pass trait A { diff --git a/tests/ui/issues/issue-8248.stderr b/tests/ui/coercion/mut-trait-coercion-8248.stderr similarity index 83% rename from tests/ui/issues/issue-8248.stderr rename to tests/ui/coercion/mut-trait-coercion-8248.stderr index 8570bfaefadbe..2f79a9ba1c868 100644 --- a/tests/ui/issues/issue-8248.stderr +++ b/tests/ui/coercion/mut-trait-coercion-8248.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/issue-8248.rs:4:8 + --> $DIR/mut-trait-coercion-8248.rs:5:8 | LL | trait A { | - method in this trait diff --git a/tests/ui/issues/issue-8398.rs b/tests/ui/coercion/mut-trait-object-coercion-8398.rs similarity index 79% rename from tests/ui/issues/issue-8398.rs rename to tests/ui/coercion/mut-trait-object-coercion-8398.rs index 7d100b855fd1a..d87d27582bab6 100644 --- a/tests/ui/issues/issue-8398.rs +++ b/tests/ui/coercion/mut-trait-object-coercion-8398.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8398 //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-76191.rs b/tests/ui/consts/const-range-matching-76191.rs similarity index 89% rename from tests/ui/issues/issue-76191.rs rename to tests/ui/consts/const-range-matching-76191.rs index d2de44380c372..b579a4b3258a7 100644 --- a/tests/ui/issues/issue-76191.rs +++ b/tests/ui/consts/const-range-matching-76191.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/76191 // Regression test for diagnostic issue #76191 #![allow(non_snake_case)] diff --git a/tests/ui/issues/issue-76191.stderr b/tests/ui/consts/const-range-matching-76191.stderr similarity index 92% rename from tests/ui/issues/issue-76191.stderr rename to tests/ui/consts/const-range-matching-76191.stderr index d8b54be88f4bf..5c358d0fa1cf5 100644 --- a/tests/ui/issues/issue-76191.stderr +++ b/tests/ui/consts/const-range-matching-76191.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation panicked: explicit panic - --> $DIR/issue-76191.rs:8:37 + --> $DIR/const-range-matching-76191.rs:9:37 | LL | const RANGE2: RangeInclusive = panic!(); | ^^^^^^^^ evaluation of `RANGE2` failed here error[E0308]: mismatched types - --> $DIR/issue-76191.rs:14:9 + --> $DIR/const-range-matching-76191.rs:15:9 | LL | const RANGE: RangeInclusive = 0..=255; | -------------------------------- constant defined here @@ -27,7 +27,7 @@ LL + 0..=255 => {} | error[E0308]: mismatched types - --> $DIR/issue-76191.rs:16:9 + --> $DIR/const-range-matching-76191.rs:17:9 | LL | const RANGE2: RangeInclusive = panic!(); | --------------------------------- constant defined here diff --git a/tests/ui/issues/auxiliary/issue-7899.rs b/tests/ui/cross-crate/auxiliary/aux-7899.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-7899.rs rename to tests/ui/cross-crate/auxiliary/aux-7899.rs diff --git a/tests/ui/issues/auxiliary/issue-8259.rs b/tests/ui/cross-crate/auxiliary/aux-8259.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-8259.rs rename to tests/ui/cross-crate/auxiliary/aux-8259.rs diff --git a/tests/ui/issues/issue-8259.rs b/tests/ui/cross-crate/static-regions-in-cross-crate-8259.rs similarity index 55% rename from tests/ui/issues/issue-8259.rs rename to tests/ui/cross-crate/static-regions-in-cross-crate-8259.rs index e843f7f9c5083..347cfa2aee130 100644 --- a/tests/ui/issues/issue-8259.rs +++ b/tests/ui/cross-crate/static-regions-in-cross-crate-8259.rs @@ -1,11 +1,11 @@ +// https://github.com/rust-lang/rust/issues/8259 //@ run-pass #![allow(dead_code)] #![allow(non_upper_case_globals)] -//@ aux-build:issue-8259.rs +//@ aux-build:aux-8259.rs - -extern crate issue_8259 as other; +extern crate aux_8259 as other; static a: other::Foo<'static> = other::Foo::A; pub fn main() {} diff --git a/tests/ui/cross-crate/tuple-like-structs-cross-crate-7899.rs b/tests/ui/cross-crate/tuple-like-structs-cross-crate-7899.rs new file mode 100644 index 0000000000000..ce3ea7dd5796a --- /dev/null +++ b/tests/ui/cross-crate/tuple-like-structs-cross-crate-7899.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/7899 +//@ run-pass +#![allow(unused_variables)] +//@ aux-build:aux-7899.rs + +extern crate aux_7899 as testcrate; + +fn main() { + let f = testcrate::V2(1.0f32, 2.0f32); +} diff --git a/tests/ui/issues/auxiliary/issue-8401.rs b/tests/ui/dyn-keyword/auxiliary/aux-8401.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-8401.rs rename to tests/ui/dyn-keyword/auxiliary/aux-8401.rs diff --git a/tests/ui/dyn-keyword/methods-with-mut-trait-and-polymorphic-objects-issue-8401.rs b/tests/ui/dyn-keyword/methods-with-mut-trait-and-polymorphic-objects-issue-8401.rs new file mode 100644 index 0000000000000..313c6891720ac --- /dev/null +++ b/tests/ui/dyn-keyword/methods-with-mut-trait-and-polymorphic-objects-issue-8401.rs @@ -0,0 +1,7 @@ +//@ run-pass +//@ aux-build:aux-8401.rs +// https://github.com/rust-lang/rust/issues/8401 + +extern crate aux_8401; + +pub fn main() {} diff --git a/tests/ui/issues/issue-8761.rs b/tests/ui/enum/enum-discriminant-type-mismatch-8761.rs similarity index 80% rename from tests/ui/issues/issue-8761.rs rename to tests/ui/enum/enum-discriminant-type-mismatch-8761.rs index 5883bb9669562..ae09b919dc152 100644 --- a/tests/ui/issues/issue-8761.rs +++ b/tests/ui/enum/enum-discriminant-type-mismatch-8761.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8761 enum Foo { A = 1i64, //~^ ERROR mismatched types diff --git a/tests/ui/issues/issue-8761.stderr b/tests/ui/enum/enum-discriminant-type-mismatch-8761.stderr similarity index 83% rename from tests/ui/issues/issue-8761.stderr rename to tests/ui/enum/enum-discriminant-type-mismatch-8761.stderr index 4a9db56891386..f1645183e176b 100644 --- a/tests/ui/issues/issue-8761.stderr +++ b/tests/ui/enum/enum-discriminant-type-mismatch-8761.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-8761.rs:2:9 + --> $DIR/enum-discriminant-type-mismatch-8761.rs:3:9 | LL | A = 1i64, | ^^^^ expected `isize`, found `i64` @@ -11,7 +11,7 @@ LL + A = 1isize, | error[E0308]: mismatched types - --> $DIR/issue-8761.rs:5:9 + --> $DIR/enum-discriminant-type-mismatch-8761.rs:6:9 | LL | B = 2u8 | ^^^ expected `isize`, found `u8` diff --git a/tests/ui/issues/issue-80607.rs b/tests/ui/enum/enum-variant-field-error-80607.rs similarity index 82% rename from tests/ui/issues/issue-80607.rs rename to tests/ui/enum/enum-variant-field-error-80607.rs index 63f4df359b831..aa3f2f7c526f6 100644 --- a/tests/ui/issues/issue-80607.rs +++ b/tests/ui/enum/enum-variant-field-error-80607.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/80607 // This tests makes sure the diagnostics print the offending enum variant, not just the type. pub enum Enum { V1(i32), diff --git a/tests/ui/issues/issue-80607.stderr b/tests/ui/enum/enum-variant-field-error-80607.stderr similarity index 89% rename from tests/ui/issues/issue-80607.stderr rename to tests/ui/enum/enum-variant-field-error-80607.stderr index 8f9f494c8b7a4..8d088ef04bbbf 100644 --- a/tests/ui/issues/issue-80607.stderr +++ b/tests/ui/enum/enum-variant-field-error-80607.stderr @@ -1,5 +1,5 @@ error[E0559]: variant `Enum::V1` has no field named `x` - --> $DIR/issue-80607.rs:7:16 + --> $DIR/enum-variant-field-error-80607.rs:8:16 | LL | V1(i32), | -- `Enum::V1` defined here diff --git a/tests/ui/issues/issue-8506.rs b/tests/ui/enum/simple-enum-usage-8506.rs similarity index 78% rename from tests/ui/issues/issue-8506.rs rename to tests/ui/enum/simple-enum-usage-8506.rs index 30a789a3e27bf..ebe095d84e437 100644 --- a/tests/ui/issues/issue-8506.rs +++ b/tests/ui/enum/simple-enum-usage-8506.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8506 //@ run-pass #![allow(non_upper_case_globals)] diff --git a/tests/ui/issues/issue-75283.rs b/tests/ui/extern/function-definition-in-extern-block-75283.rs similarity index 70% rename from tests/ui/issues/issue-75283.rs rename to tests/ui/extern/function-definition-in-extern-block-75283.rs index d556132e47ffd..e2b7358743ba1 100644 --- a/tests/ui/issues/issue-75283.rs +++ b/tests/ui/extern/function-definition-in-extern-block-75283.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/75283 extern "C" { fn lol() { //~ ERROR incorrect function inside `extern` block println!(""); diff --git a/tests/ui/issues/issue-75283.stderr b/tests/ui/extern/function-definition-in-extern-block-75283.stderr similarity index 91% rename from tests/ui/issues/issue-75283.stderr rename to tests/ui/extern/function-definition-in-extern-block-75283.stderr index 240d9716a5561..67be1c2959922 100644 --- a/tests/ui/issues/issue-75283.stderr +++ b/tests/ui/extern/function-definition-in-extern-block-75283.stderr @@ -1,5 +1,5 @@ error: incorrect function inside `extern` block - --> $DIR/issue-75283.rs:2:8 + --> $DIR/function-definition-in-extern-block-75283.rs:3:8 | LL | extern "C" { | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body diff --git a/tests/ui/issues/issue-86756.rs b/tests/ui/generics/duplicate-generic-parameter-error-86756.rs similarity index 89% rename from tests/ui/issues/issue-86756.rs rename to tests/ui/generics/duplicate-generic-parameter-error-86756.rs index 55a6c144839e8..acc281cb8c456 100644 --- a/tests/ui/issues/issue-86756.rs +++ b/tests/ui/generics/duplicate-generic-parameter-error-86756.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/86756 //@ edition: 2015 trait Foo {} //~^ ERROR the name `T` is already used for a generic parameter in this item's generic parameters diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/generics/duplicate-generic-parameter-error-86756.stderr similarity index 82% rename from tests/ui/issues/issue-86756.stderr rename to tests/ui/generics/duplicate-generic-parameter-error-86756.stderr index b650b32c2a367..d4b2169ffd2dd 100644 --- a/tests/ui/issues/issue-86756.stderr +++ b/tests/ui/generics/duplicate-generic-parameter-error-86756.stderr @@ -1,5 +1,5 @@ error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters - --> $DIR/issue-86756.rs:2:14 + --> $DIR/duplicate-generic-parameter-error-86756.rs:3:14 | LL | trait Foo {} | - ^ already used @@ -7,13 +7,13 @@ LL | trait Foo {} | first use of `T` error[E0412]: cannot find type `dyn` in this scope - --> $DIR/issue-86756.rs:6:10 + --> $DIR/duplicate-generic-parameter-error-86756.rs:7:10 | LL | eq:: | ^^^ not found in this scope warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/issue-86756.rs:6:15 + --> $DIR/duplicate-generic-parameter-error-86756.rs:7:15 | LL | eq:: | ^^^ @@ -27,13 +27,13 @@ LL | eq:: | +++ error[E0107]: missing generics for trait `Foo` - --> $DIR/issue-86756.rs:6:15 + --> $DIR/duplicate-generic-parameter-error-86756.rs:7:15 | LL | eq:: | ^^^ expected at least 1 generic argument | note: trait defined here, with at least 1 generic parameter: `T` - --> $DIR/issue-86756.rs:2:7 + --> $DIR/duplicate-generic-parameter-error-86756.rs:3:7 | LL | trait Foo {} | ^^^ - diff --git a/tests/ui/issues/issue-85461.rs b/tests/ui/instrument-coverage/link-regex-crate-with-instrument-coverage-85461.rs similarity index 91% rename from tests/ui/issues/issue-85461.rs rename to tests/ui/instrument-coverage/link-regex-crate-with-instrument-coverage-85461.rs index 72538081ccb3a..ffb535e69ee56 100644 --- a/tests/ui/issues/issue-85461.rs +++ b/tests/ui/instrument-coverage/link-regex-crate-with-instrument-coverage-85461.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/85461 //@ compile-flags: -Cinstrument-coverage -Ccodegen-units=4 --crate-type dylib -Copt-level=0 //@ build-pass //@ needs-profiler-runtime diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr new file mode 100644 index 0000000000000..e3f7871da3524 --- /dev/null +++ b/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr @@ -0,0 +1,4 @@ +error: `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64 + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs b/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs new file mode 100644 index 0000000000000..bc81c993d26ef --- /dev/null +++ b/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs @@ -0,0 +1,21 @@ +//@ revisions: x86 x86_64 aarch64 + +//@ compile-flags: -Zindirect-branch-cs-prefix + +//@[x86] check-pass +//@[x86] needs-llvm-components: x86 +//@[x86] compile-flags: --target i686-unknown-linux-gnu + +//@[x86_64] check-pass +//@[x86_64] needs-llvm-components: x86 +//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu + +//@[aarch64] check-fail +//@[aarch64] needs-llvm-components: aarch64 +//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu + +#![feature(no_core)] +#![no_core] +#![no_main] + +//[aarch64]~? ERROR `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64 diff --git a/tests/ui/issues/issue-77218/issue-77218-2.fixed b/tests/ui/issues/issue-77218/issue-77218-2.fixed deleted file mode 100644 index 98d79b5da6561..0000000000000 --- a/tests/ui/issues/issue-77218/issue-77218-2.fixed +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-rustfix -fn main() { - let value = [7u8]; - while let Some(0) = value.get(0) { //~ ERROR invalid left-hand side of assignment - } -} diff --git a/tests/ui/issues/issue-77218/issue-77218-2.rs b/tests/ui/issues/issue-77218/issue-77218-2.rs deleted file mode 100644 index 3be38f8f721da..0000000000000 --- a/tests/ui/issues/issue-77218/issue-77218-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-rustfix -fn main() { - let value = [7u8]; - while Some(0) = value.get(0) { //~ ERROR invalid left-hand side of assignment - } -} diff --git a/tests/ui/issues/issue-77218/issue-77218-2.stderr b/tests/ui/issues/issue-77218/issue-77218-2.stderr deleted file mode 100644 index dfed0b6e67e33..0000000000000 --- a/tests/ui/issues/issue-77218/issue-77218-2.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0070]: invalid left-hand side of assignment - --> $DIR/issue-77218-2.rs:4:19 - | -LL | while Some(0) = value.get(0) { - | - ^ - | | - | cannot assign to this expression - | -help: you might have meant to use pattern destructuring - | -LL | while let Some(0) = value.get(0) { - | +++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0070`. diff --git a/tests/ui/issues/issue-7899.rs b/tests/ui/issues/issue-7899.rs deleted file mode 100644 index 4b69f3e3d89aa..0000000000000 --- a/tests/ui/issues/issue-7899.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -#![allow(unused_variables)] -//@ aux-build:issue-7899.rs - - -extern crate issue_7899 as testcrate; - -fn main() { - let f = testcrate::V2(1.0f32, 2.0f32); -} diff --git a/tests/ui/issues/issue-8044.rs b/tests/ui/issues/issue-8044.rs deleted file mode 100644 index 3c10bbca6342b..0000000000000 --- a/tests/ui/issues/issue-8044.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:issue-8044.rs - - -extern crate issue_8044 as minimal; -use minimal::{BTree, leaf}; - -pub fn main() { - BTree:: { node: leaf(1) }; -} diff --git a/tests/ui/issues/issue-8401.rs b/tests/ui/issues/issue-8401.rs deleted file mode 100644 index 1df63516fb0be..0000000000000 --- a/tests/ui/issues/issue-8401.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass -//@ aux-build:issue-8401.rs - - -extern crate issue_8401; - -pub fn main() {} diff --git a/tests/ui/issues/issue-9123.rs b/tests/ui/issues/issue-9123.rs deleted file mode 100644 index bbf6c13341c27..0000000000000 --- a/tests/ui/issues/issue-9123.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass -//@ aux-build:issue-9123.rs - - -extern crate issue_9123; - -pub fn main() {} diff --git a/tests/ui/issues/issue-81584.fixed b/tests/ui/iterators/iterator-scope-collect-suggestion-81584.fixed similarity index 84% rename from tests/ui/issues/issue-81584.fixed rename to tests/ui/iterators/iterator-scope-collect-suggestion-81584.fixed index c3d33a1b4f8bc..0e3d48fe27d8a 100644 --- a/tests/ui/issues/issue-81584.fixed +++ b/tests/ui/iterators/iterator-scope-collect-suggestion-81584.fixed @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/81584 //@ run-rustfix fn main() { let _ = vec![vec![0, 1], vec![2]] diff --git a/tests/ui/issues/issue-81584.rs b/tests/ui/iterators/iterator-scope-collect-suggestion-81584.rs similarity index 83% rename from tests/ui/issues/issue-81584.rs rename to tests/ui/iterators/iterator-scope-collect-suggestion-81584.rs index 27db73aaa2c86..3fba39517fcc5 100644 --- a/tests/ui/issues/issue-81584.rs +++ b/tests/ui/iterators/iterator-scope-collect-suggestion-81584.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/81584 //@ run-rustfix fn main() { let _ = vec![vec![0, 1], vec![2]] diff --git a/tests/ui/issues/issue-81584.stderr b/tests/ui/iterators/iterator-scope-collect-suggestion-81584.stderr similarity index 89% rename from tests/ui/issues/issue-81584.stderr rename to tests/ui/iterators/iterator-scope-collect-suggestion-81584.stderr index eb97916ad75ef..e180183e7e387 100644 --- a/tests/ui/issues/issue-81584.stderr +++ b/tests/ui/iterators/iterator-scope-collect-suggestion-81584.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing function parameter `y` - --> $DIR/issue-81584.rs:5:22 + --> $DIR/iterator-scope-collect-suggestion-81584.rs:6:22 | LL | .map(|y| y.iter().map(|x| x + 1)) | -^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-7970a.rs b/tests/ui/macros/macro-invocation-span-error-7970.rs similarity index 51% rename from tests/ui/issues/issue-7970a.rs rename to tests/ui/macros/macro-invocation-span-error-7970.rs index dae906410ed61..df7e1cfea88bc 100644 --- a/tests/ui/issues/issue-7970a.rs +++ b/tests/ui/macros/macro-invocation-span-error-7970.rs @@ -1,5 +1,8 @@ +// https://github.com/rust-lang/rust/issues/7970 macro_rules! one_arg_macro { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr) => { + print!(concat!($fmt, "\n")) + }; } fn main() { diff --git a/tests/ui/issues/issue-7970a.stderr b/tests/ui/macros/macro-invocation-span-error-7970.stderr similarity index 73% rename from tests/ui/issues/issue-7970a.stderr rename to tests/ui/macros/macro-invocation-span-error-7970.stderr index 1e6bb92ea579e..beb54e0599248 100644 --- a/tests/ui/issues/issue-7970a.stderr +++ b/tests/ui/macros/macro-invocation-span-error-7970.stderr @@ -1,5 +1,5 @@ error: unexpected end of macro invocation - --> $DIR/issue-7970a.rs:6:5 + --> $DIR/macro-invocation-span-error-7970.rs:9:5 | LL | macro_rules! one_arg_macro { | -------------------------- when calling this macro @@ -8,9 +8,9 @@ LL | one_arg_macro!(); | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments | note: while trying to match meta-variable `$fmt:expr` - --> $DIR/issue-7970a.rs:2:6 + --> $DIR/macro-invocation-span-error-7970.rs:3:6 | -LL | ($fmt:expr) => (print!(concat!($fmt, "\n"))); +LL | ($fmt:expr) => { | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-8521.rs b/tests/ui/macros/macro-path-type-bounds-8521.rs similarity index 84% rename from tests/ui/issues/issue-8521.rs rename to tests/ui/macros/macro-path-type-bounds-8521.rs index 78ce85787d5cf..975d3dc402e1f 100644 --- a/tests/ui/issues/issue-8521.rs +++ b/tests/ui/macros/macro-path-type-bounds-8521.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8521 //@ check-pass trait Foo1 {} diff --git a/tests/ui/issues/issue-7911.rs b/tests/ui/macros/macro-self-mutability-7911.rs similarity index 95% rename from tests/ui/issues/issue-7911.rs rename to tests/ui/macros/macro-self-mutability-7911.rs index 11da4df5285f1..5313f86d97f5f 100644 --- a/tests/ui/issues/issue-7911.rs +++ b/tests/ui/macros/macro-self-mutability-7911.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7911 //@ run-pass // (Closes #7911) Test that we can use the same self expression // with different mutability in macro in two methods diff --git a/tests/ui/issues/issue-7911.stderr b/tests/ui/macros/macro-self-mutability-7911.stderr similarity index 83% rename from tests/ui/issues/issue-7911.stderr rename to tests/ui/macros/macro-self-mutability-7911.stderr index ead7ee191ac9b..7fc2abe06eb39 100644 --- a/tests/ui/issues/issue-7911.stderr +++ b/tests/ui/macros/macro-self-mutability-7911.stderr @@ -1,5 +1,5 @@ warning: method `dummy` is never used - --> $DIR/issue-7911.rs:7:8 + --> $DIR/macro-self-mutability-7911.rs:8:8 | LL | trait FooBar { | ------ method in this trait diff --git a/tests/ui/issues/issue-7867.rs b/tests/ui/match/mismatched-types-in-match-pattern-7867.rs similarity index 87% rename from tests/ui/issues/issue-7867.rs rename to tests/ui/match/mismatched-types-in-match-pattern-7867.rs index 87e7c831e6855..9ff8755c81956 100644 --- a/tests/ui/issues/issue-7867.rs +++ b/tests/ui/match/mismatched-types-in-match-pattern-7867.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7867 //@ dont-require-annotations: NOTE enum A { B, C } diff --git a/tests/ui/issues/issue-7867.stderr b/tests/ui/match/mismatched-types-in-match-pattern-7867.stderr similarity index 88% rename from tests/ui/issues/issue-7867.stderr rename to tests/ui/match/mismatched-types-in-match-pattern-7867.stderr index fcb69d775face..8997f36114a89 100644 --- a/tests/ui/issues/issue-7867.stderr +++ b/tests/ui/match/mismatched-types-in-match-pattern-7867.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-7867.rs:9:9 + --> $DIR/mismatched-types-in-match-pattern-7867.rs:10:9 | LL | enum A { B, C } | - unit variant defined here diff --git a/tests/ui/issues/issue-7575.rs b/tests/ui/methods/trait-method-self-param-error-7575.rs similarity index 83% rename from tests/ui/issues/issue-7575.rs rename to tests/ui/methods/trait-method-self-param-error-7575.rs index 8b1fdf6c851e2..9793d43cc24fc 100644 --- a/tests/ui/issues/issue-7575.rs +++ b/tests/ui/methods/trait-method-self-param-error-7575.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7575 //@ run-pass trait Foo { //~ WARN trait `Foo` is never used diff --git a/tests/ui/issues/issue-7575.stderr b/tests/ui/methods/trait-method-self-param-error-7575.stderr similarity index 74% rename from tests/ui/issues/issue-7575.stderr rename to tests/ui/methods/trait-method-self-param-error-7575.stderr index 2f987d19c80ce..5c10a7e1da9d0 100644 --- a/tests/ui/issues/issue-7575.stderr +++ b/tests/ui/methods/trait-method-self-param-error-7575.stderr @@ -1,5 +1,5 @@ warning: trait `Foo` is never used - --> $DIR/issue-7575.rs:3:7 + --> $DIR/trait-method-self-param-error-7575.rs:4:7 | LL | trait Foo { | ^^^ diff --git a/tests/ui/issues/issue-81918.rs b/tests/ui/mir/mir-cfg-unpretty-check-81918.rs similarity index 81% rename from tests/ui/issues/issue-81918.rs rename to tests/ui/mir/mir-cfg-unpretty-check-81918.rs index ee9721c2493de..4798a6543755d 100644 --- a/tests/ui/issues/issue-81918.rs +++ b/tests/ui/mir/mir-cfg-unpretty-check-81918.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/81918 //@ check-pass //@ dont-check-compiler-stdout //@ compile-flags: -Z unpretty=mir-cfg diff --git a/tests/ui/issues/issue-87490.rs b/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.rs similarity index 80% rename from tests/ui/issues/issue-87490.rs rename to tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.rs index 998f61a6bd32d..67e16ec6ce3ab 100644 --- a/tests/ui/issues/issue-87490.rs +++ b/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/87490 fn main() {} trait StreamOnce { type Position; diff --git a/tests/ui/issues/issue-87490.stderr b/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.stderr similarity index 87% rename from tests/ui/issues/issue-87490.stderr rename to tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.stderr index 5a4ec55833bea..bbd73347d0272 100644 --- a/tests/ui/issues/issue-87490.stderr +++ b/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-87490.rs:9:5 + --> $DIR/mismatched-types-in-trait-implementation-87490.rs:10:5 | LL | fn follow(_: &str) -> <&str as StreamOnce>::Position { | ------------------------------ expected `usize` because of return type diff --git a/tests/ui/issues/issue-8391.rs b/tests/ui/pattern/match-with-at-binding-8391.rs similarity index 73% rename from tests/ui/issues/issue-8391.rs rename to tests/ui/pattern/match-with-at-binding-8391.rs index 20698eed18b7b..bc4e7be798929 100644 --- a/tests/ui/issues/issue-8391.rs +++ b/tests/ui/pattern/match-with-at-binding-8391.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8391 //@ run-pass fn main() { diff --git a/tests/ui/issues/issue-8860.rs b/tests/ui/pattern/ref-in-function-parameter-patterns-8860.rs similarity index 94% rename from tests/ui/issues/issue-8860.rs rename to tests/ui/pattern/ref-in-function-parameter-patterns-8860.rs index 3af61576fe1a2..1a67caf021cf7 100644 --- a/tests/ui/issues/issue-8860.rs +++ b/tests/ui/pattern/ref-in-function-parameter-patterns-8860.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8860 //@ run-pass // FIXME(static_mut_refs): this could use an atomic #![allow(static_mut_refs)] diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.fixed b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.fixed similarity index 90% rename from tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.fixed rename to tests/ui/privacy/inaccessible-fields-pattern-matching-76077.fixed index 6fde4e390fa1a..7d648543a2071 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.fixed +++ b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.fixed @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/76077 //@ run-rustfix #![allow(dead_code, unused_variables)] diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.rs similarity index 90% rename from tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs rename to tests/ui/privacy/inaccessible-fields-pattern-matching-76077.rs index 30a8535faf5cc..f3b51187ae316 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs +++ b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/76077 //@ run-rustfix #![allow(dead_code, unused_variables)] diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.stderr similarity index 83% rename from tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr rename to tests/ui/privacy/inaccessible-fields-pattern-matching-76077.stderr index f54990d5d8618..070fa1a53a547 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr +++ b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.stderr @@ -1,5 +1,5 @@ error: pattern requires `..` due to inaccessible fields - --> $DIR/issue-76077-1.rs:13:9 + --> $DIR/inaccessible-fields-pattern-matching-76077.rs:14:9 | LL | let foo::Foo {} = foo::Foo::default(); | ^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | let foo::Foo { .. } = foo::Foo::default(); | ++ error: pattern requires `..` due to inaccessible fields - --> $DIR/issue-76077-1.rs:16:9 + --> $DIR/inaccessible-fields-pattern-matching-76077.rs:17:9 | LL | let foo::Bar { visible } = foo::Bar::default(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/privacy/macro-private-reexport.stderr b/tests/ui/privacy/macro-private-reexport.stderr index b8768f3612e61..aa02715c20298 100644 --- a/tests/ui/privacy/macro-private-reexport.stderr +++ b/tests/ui/privacy/macro-private-reexport.stderr @@ -11,6 +11,10 @@ LL | / macro_rules! bar { LL | | () => {}; LL | | } | |_____^ +help: in case you want to use the macro within this crate only, reduce the visibility to `pub(crate)` + | +LL | pub(crate) use bar as _; + | +++++++ error[E0364]: `baz` is private, and cannot be re-exported --> $DIR/macro-private-reexport.rs:14:13 diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs b/tests/ui/privacy/private-field-struct-construction-76077.rs similarity index 80% rename from tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs rename to tests/ui/privacy/private-field-struct-construction-76077.rs index 2d29093b01b02..7fc3473e8decc 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs +++ b/tests/ui/privacy/private-field-struct-construction-76077.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/76077 pub mod foo { pub struct Foo { you_cant_use_this_field: bool, diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.stderr b/tests/ui/privacy/private-field-struct-construction-76077.stderr similarity index 80% rename from tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.stderr rename to tests/ui/privacy/private-field-struct-construction-76077.stderr index 3fef5ffce30dc..5131db72fe3bf 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.stderr +++ b/tests/ui/privacy/private-field-struct-construction-76077.stderr @@ -1,5 +1,5 @@ error: cannot construct `Foo` with struct literal syntax due to private fields - --> $DIR/issue-76077.rs:8:5 + --> $DIR/private-field-struct-construction-76077.rs:9:5 | LL | foo::Foo {}; | ^^^^^^^^ diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/recursion/infinite-function-recursion-error-8727.rs similarity index 90% rename from tests/ui/issues/issue-8727.rs rename to tests/ui/recursion/infinite-function-recursion-error-8727.rs index c1b60e8e08509..a4037f761098e 100644 --- a/tests/ui/issues/issue-8727.rs +++ b/tests/ui/recursion/infinite-function-recursion-error-8727.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8727 // Verify the compiler fails with an error on infinite function // recursions. @@ -9,7 +10,6 @@ fn generic() { //~ WARN function cannot return without recursing } //~^^ ERROR reached the recursion limit while instantiating `generic:: at least once to trigger instantiation. generic::(); diff --git a/tests/ui/issues/issue-8727.stderr b/tests/ui/recursion/infinite-function-recursion-error-8727.stderr similarity index 76% rename from tests/ui/issues/issue-8727.stderr rename to tests/ui/recursion/infinite-function-recursion-error-8727.stderr index 9fb09a7d4f42d..13d57ecb3b2f0 100644 --- a/tests/ui/issues/issue-8727.stderr +++ b/tests/ui/recursion/infinite-function-recursion-error-8727.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-8727.rs:7:1 + --> $DIR/infinite-function-recursion-error-8727.rs:8:1 | LL | fn generic() { | ^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,17 +10,17 @@ LL | generic::>(); = note: `#[warn(unconditional_recursion)]` on by default error: reached the recursion limit while instantiating `generic::>>>>` - --> $DIR/issue-8727.rs:8:5 + --> $DIR/infinite-function-recursion-error-8727.rs:9:5 | LL | generic::>(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `generic` defined here - --> $DIR/issue-8727.rs:7:1 + --> $DIR/infinite-function-recursion-error-8727.rs:8:1 | LL | fn generic() { | ^^^^^^^^^^^^^^^ - = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-8727.long-type-$LONG_TYPE_HASH.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/infinite-function-recursion-error-8727.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/issues/issue-7663.rs b/tests/ui/resolve/module-import-resolution-7663.rs similarity index 91% rename from tests/ui/issues/issue-7663.rs rename to tests/ui/resolve/module-import-resolution-7663.rs index d2b2c727cab25..872806594fc40 100644 --- a/tests/ui/issues/issue-7663.rs +++ b/tests/ui/resolve/module-import-resolution-7663.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7663 //@ run-pass #![allow(unused_imports, dead_code)] diff --git a/tests/ui/rust-2018/uniform-paths/macro-rules.stderr b/tests/ui/rust-2018/uniform-paths/macro-rules.stderr index 661d667eb9a54..43eacd5413f1c 100644 --- a/tests/ui/rust-2018/uniform-paths/macro-rules.stderr +++ b/tests/ui/rust-2018/uniform-paths/macro-rules.stderr @@ -9,6 +9,10 @@ help: consider adding a `#[macro_export]` to the macro in the imported module | LL | macro_rules! legacy_macro { () => () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: in case you want to use the macro within this crate only, reduce the visibility to `pub(crate)` + | +LL | pub(crate) use legacy_macro as _; + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-8578.rs b/tests/ui/static/static-struct-with-option-8578.rs similarity index 90% rename from tests/ui/issues/issue-8578.rs rename to tests/ui/static/static-struct-with-option-8578.rs index 9baa2f70a02db..d490a3f50b419 100644 --- a/tests/ui/issues/issue-8578.rs +++ b/tests/ui/static/static-struct-with-option-8578.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8578 //@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/auxiliary/issue-8044.rs b/tests/ui/structs-enums/auxiliary/aux-8044.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-8044.rs rename to tests/ui/structs-enums/auxiliary/aux-8044.rs diff --git a/tests/ui/structs-enums/struct-and-enum-usage-8044.rs b/tests/ui/structs-enums/struct-and-enum-usage-8044.rs new file mode 100644 index 0000000000000..9b544f33f1c2d --- /dev/null +++ b/tests/ui/structs-enums/struct-and-enum-usage-8044.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/8044 +//@ run-pass +//@ aux-build:aux-8044.rs + +extern crate aux_8044 as minimal; +use minimal::{BTree, leaf}; + +pub fn main() { + BTree:: { node: leaf(1) }; +} diff --git a/tests/ui/issues/issue-8783.rs b/tests/ui/structs/destructuring-struct-type-inference-8783.rs similarity index 88% rename from tests/ui/issues/issue-8783.rs rename to tests/ui/structs/destructuring-struct-type-inference-8783.rs index d0ff79f8ac800..60bc4bf3289e5 100644 --- a/tests/ui/issues/issue-8783.rs +++ b/tests/ui/structs/destructuring-struct-type-inference-8783.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8783 //@ run-pass #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-83048.rs b/tests/ui/thir-print/break-outside-loop-error-83048.rs similarity index 72% rename from tests/ui/issues/issue-83048.rs rename to tests/ui/thir-print/break-outside-loop-error-83048.rs index 6c941133a152c..6dcebd77c27b2 100644 --- a/tests/ui/issues/issue-83048.rs +++ b/tests/ui/thir-print/break-outside-loop-error-83048.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/83048 //@ compile-flags: -Z unpretty=thir-tree pub fn main() { diff --git a/tests/ui/issues/issue-83048.stderr b/tests/ui/thir-print/break-outside-loop-error-83048.stderr similarity index 83% rename from tests/ui/issues/issue-83048.stderr rename to tests/ui/thir-print/break-outside-loop-error-83048.stderr index 672bf69a7325b..65a08e62e3df6 100644 --- a/tests/ui/issues/issue-83048.stderr +++ b/tests/ui/thir-print/break-outside-loop-error-83048.stderr @@ -1,5 +1,5 @@ error[E0268]: `break` outside of a loop or labeled block - --> $DIR/issue-83048.rs:4:5 + --> $DIR/break-outside-loop-error-83048.rs:5:5 | LL | break; | ^^^^^ cannot `break` outside of a loop or labeled block diff --git a/tests/ui/issues/issue-87707.rs b/tests/ui/track-diagnostics/track-caller-for-once-87707.rs similarity index 87% rename from tests/ui/issues/issue-87707.rs rename to tests/ui/track-diagnostics/track-caller-for-once-87707.rs index a0da8a740ac39..9b450943f5d7a 100644 --- a/tests/ui/issues/issue-87707.rs +++ b/tests/ui/track-diagnostics/track-caller-for-once-87707.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/87707 // test for #87707 //@ edition:2018 //@ run-fail diff --git a/tests/ui/issues/issue-87707.run.stderr b/tests/ui/track-diagnostics/track-caller-for-once-87707.run.stderr similarity index 50% rename from tests/ui/issues/issue-87707.run.stderr rename to tests/ui/track-diagnostics/track-caller-for-once-87707.run.stderr index 8485c0578b82c..093df62836bfa 100644 --- a/tests/ui/issues/issue-87707.run.stderr +++ b/tests/ui/track-diagnostics/track-caller-for-once-87707.run.stderr @@ -1,7 +1,7 @@ -thread 'main' ($TID) panicked at $DIR/issue-87707.rs:14:24: +thread 'main' ($TID) panicked at $DIR/track-caller-for-once-87707.rs:15:24: Here Once instance is poisoned. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread 'main' ($TID) panicked at $DIR/issue-87707.rs:16:7: +thread 'main' ($TID) panicked at $DIR/track-caller-for-once-87707.rs:17:7: Once instance has previously been poisoned diff --git a/tests/ui/issues/issue-87199.rs b/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.rs similarity index 94% rename from tests/ui/issues/issue-87199.rs rename to tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.rs index dd9dfc74ca352..f3baa4b1feb8d 100644 --- a/tests/ui/issues/issue-87199.rs +++ b/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/87199 // Regression test for issue #87199, where attempting to relax a bound // other than the only supported `?Sized` would still cause the compiler // to assume that the `Sized` bound was relaxed. diff --git a/tests/ui/issues/issue-87199.stderr b/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.stderr similarity index 80% rename from tests/ui/issues/issue-87199.stderr rename to tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.stderr index 8a930a3d704c1..16223676c067e 100644 --- a/tests/ui/issues/issue-87199.stderr +++ b/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.stderr @@ -1,23 +1,23 @@ error: bound modifier `?` can only be applied to `Sized` - --> $DIR/issue-87199.rs:8:11 + --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:9:11 | LL | fn arg(_: T) {} | ^^^^^ error: bound modifier `?` can only be applied to `Sized` - --> $DIR/issue-87199.rs:10:15 + --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:11:15 | LL | fn ref_arg(_: &T) {} | ^^^^^ error: bound modifier `?` can only be applied to `Sized` - --> $DIR/issue-87199.rs:12:40 + --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:13:40 | LL | fn ret() -> impl Iterator + ?Send { std::iter::empty() } | ^^^^^ error: bound modifier `?` can only be applied to `Sized` - --> $DIR/issue-87199.rs:12:40 + --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:13:40 | LL | fn ret() -> impl Iterator + ?Send { std::iter::empty() } | ^^^^^ @@ -25,14 +25,14 @@ LL | fn ret() -> impl Iterator + ?Send { std::iter::empty() } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/issue-87199.rs:19:15 + --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:20:15 | LL | ref_arg::<[i32]>(&[5]); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` note: required by an implicit `Sized` bound in `ref_arg` - --> $DIR/issue-87199.rs:10:12 + --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:11:12 | LL | fn ref_arg(_: &T) {} | ^ required by the implicit `Sized` requirement on this type parameter in `ref_arg` diff --git a/tests/ui/issues/auxiliary/issue-9123.rs b/tests/ui/traits/auxiliary/aux-9123.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-9123.rs rename to tests/ui/traits/auxiliary/aux-9123.rs diff --git a/tests/ui/traits/default-method-fn-call-9123.rs b/tests/ui/traits/default-method-fn-call-9123.rs new file mode 100644 index 0000000000000..266b95ca960c5 --- /dev/null +++ b/tests/ui/traits/default-method-fn-call-9123.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/9123 +//@ run-pass +//@ aux-build:aux-9123.rs + +extern crate aux_9123; + +pub fn main() {} diff --git a/tests/ui/issues/issue-8249.rs b/tests/ui/traits/mut-trait-in-struct-8249.rs similarity index 80% rename from tests/ui/issues/issue-8249.rs rename to tests/ui/traits/mut-trait-in-struct-8249.rs index 2364fc14d31ac..b6dcd848b8b34 100644 --- a/tests/ui/issues/issue-8249.rs +++ b/tests/ui/traits/mut-trait-in-struct-8249.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8249 //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/tests/ui/traits/polymorphic-trait-creation-7673.rs similarity index 85% rename from tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs rename to tests/ui/traits/polymorphic-trait-creation-7673.rs index edba3284e3175..643818ffe1e52 100644 --- a/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs +++ b/tests/ui/traits/polymorphic-trait-creation-7673.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7673 //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/tests/ui/traits/self-implements-kinds-in-default-methods-8171.rs similarity index 85% rename from tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs rename to tests/ui/traits/self-implements-kinds-in-default-methods-8171.rs index 6a03404cdca71..59ea62c7690ee 100644 --- a/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs +++ b/tests/ui/traits/self-implements-kinds-in-default-methods-8171.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8171 //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-7563.rs b/tests/ui/traits/trait-implementation-and-usage-7563.rs similarity index 91% rename from tests/ui/issues/issue-7563.rs rename to tests/ui/traits/trait-implementation-and-usage-7563.rs index 9ee8857b99960..8cfc7a14ffe66 100644 --- a/tests/ui/issues/issue-7563.rs +++ b/tests/ui/traits/trait-implementation-and-usage-7563.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7563 //@ run-pass #![allow(dead_code)] trait IDummy { diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs index 4fb2e60b5c5a3..04208fadddecf 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs @@ -24,8 +24,7 @@ type Successors<'a> = impl std::fmt::Debug + 'a; impl Terminator { #[define_opaque(Successors, Tait)] fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { - f = g; - //~^ ERROR mismatched types + f = g; //~ ERROR expected generic lifetime parameter, found `'x` } } diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr index 558792987f31c..8e6778bdd0b53 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr @@ -1,15 +1,12 @@ -error[E0308]: mismatched types +error[E0792]: expected generic lifetime parameter, found `'x` --> $DIR/higher_kinded_params3.rs:27:9 | LL | type Tait<'a> = impl std::fmt::Debug + 'a; - | ------------------------- the expected opaque type + | -- this generic parameter must be used with a generic lifetime parameter ... LL | f = g; - | ^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>` - found fn pointer `for<'a> fn(&'a ()) -> &'a ()` + | ^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs index c7f04dc07bb12..ba75b114a1188 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs @@ -8,7 +8,7 @@ fn foo<'a>(x: &'a ()) -> &'a () { #[define_opaque(Opaque)] fn test() -> for<'a> fn(&'a ()) -> Opaque<'a> { - foo //~ ERROR: mismatched types + foo //~ ERROR: expected generic lifetime parameter, found `'a` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr index b8c04185a7d14..d699059e3972c 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr @@ -1,15 +1,12 @@ -error[E0308]: mismatched types +error[E0792]: expected generic lifetime parameter, found `'a` --> $DIR/hkl_forbidden3.rs:11:5 | LL | type Opaque<'a> = impl Sized + 'a; - | --------------- the expected opaque type + | -- this generic parameter must be used with a generic lifetime parameter ... LL | foo - | ^^^ one type is more general than the other - | - = note: expected fn pointer `for<'a> fn(&'a ()) -> Opaque<'a>` - found fn pointer `for<'a> fn(&'a ()) -> &'a ()` + | ^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/issues/issue-8767.rs b/tests/ui/typeck/impl-for-nonexistent-type-error-8767.rs similarity index 59% rename from tests/ui/issues/issue-8767.rs rename to tests/ui/typeck/impl-for-nonexistent-type-error-8767.rs index 972101a0bc3ee..005c676ed39b3 100644 --- a/tests/ui/issues/issue-8767.rs +++ b/tests/ui/typeck/impl-for-nonexistent-type-error-8767.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8767 impl B { //~ ERROR cannot find type `B` in this scope } diff --git a/tests/ui/issues/issue-8767.stderr b/tests/ui/typeck/impl-for-nonexistent-type-error-8767.stderr similarity index 79% rename from tests/ui/issues/issue-8767.stderr rename to tests/ui/typeck/impl-for-nonexistent-type-error-8767.stderr index 66141628e28d2..0e37391a00f7b 100644 --- a/tests/ui/issues/issue-8767.stderr +++ b/tests/ui/typeck/impl-for-nonexistent-type-error-8767.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `B` in this scope - --> $DIR/issue-8767.rs:1:6 + --> $DIR/impl-for-nonexistent-type-error-8767.rs:2:6 | LL | impl B { | ^ not found in this scope diff --git a/typos.toml b/typos.toml index 317aafc861565..b0ff48f8fa28b 100644 --- a/typos.toml +++ b/typos.toml @@ -33,6 +33,7 @@ misformed = "misformed" targetting = "targetting" publically = "publically" clonable = "clonable" +moreso = "moreso" # this can be valid word, depends on dictionary edition #matcheable = "matcheable"