diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ed2a3a507c8ab..2f55a9eaedab3 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2566,6 +2566,18 @@ pub enum SelfKind { Explicit(P, Mutability), } +impl SelfKind { + pub fn to_ref_suggestion(&self) -> String { + match self { + SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(), + SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()), + SelfKind::Value(_) | SelfKind::Explicit(_, _) => { + unreachable!("if we had an explicit self, we wouldn't be here") + } + } + } +} + pub type ExplicitSelf = Spanned; impl Param { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 61260dbd16c51..ddcd90a2a9da6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -3394,7 +3394,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; }; - if self.can_eq(self.param_env, expected_ty, ty) { + if self.can_eq(self.param_env, expected_ty, ty) + // FIXME: this happens with macro calls. Need to figure out why the stmt + // `println!();` doesn't include the `;` in its `Span`. (#133845) + // We filter these out to avoid ICEs with debug assertions on caused by + // empty suggestions. + && stmt.span.hi() != tail_expr.span.hi() + { err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon", diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 40ffed480381a..49e6b763590b0 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -885,6 +885,12 @@ lint_unnameable_test_items = cannot test inner items lint_unnecessary_qualification = unnecessary qualification .suggestion = remove the unnecessary path segments +lint_unpredictable_fn_pointer_comparisons = function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + .note_duplicated_fn = the address of the same function can vary between different codegen units + .note_deduplicated_fn = furthermore, different functions could have the same address after being merged together + .note_visit_fn_addr_eq = for more information visit + .fn_addr_eq_suggestion = refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::` lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index e6eae7e736832..20822f23bf15d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1815,6 +1815,42 @@ pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { }, } +#[derive(LintDiagnostic)] +pub(crate) enum UnpredictableFunctionPointerComparisons<'a> { + #[diag(lint_unpredictable_fn_pointer_comparisons)] + #[note(lint_note_duplicated_fn)] + #[note(lint_note_deduplicated_fn)] + #[note(lint_note_visit_fn_addr_eq)] + Suggestion { + #[subdiagnostic] + sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a>, + }, + #[diag(lint_unpredictable_fn_pointer_comparisons)] + #[note(lint_note_duplicated_fn)] + #[note(lint_note_deduplicated_fn)] + #[note(lint_note_visit_fn_addr_eq)] + Warn, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + lint_fn_addr_eq_suggestion, + style = "verbose", + applicability = "maybe-incorrect" +)] +pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> { + pub ne: &'a str, + pub cast_right: String, + pub deref_left: &'a str, + pub deref_right: &'a str, + #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")] + pub left: Span, + #[suggestion_part(code = ", {deref_right}")] + pub middle: Span, + #[suggestion_part(code = "{cast_right})")] + pub right: Span, +} + pub(crate) struct ImproperCTypes<'a> { pub ty: Ty<'a>, pub desc: &'a str, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b1d7d4ab68951..33650be056dd1 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -23,7 +23,9 @@ use crate::lints::{ AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion, AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons, - InvalidNanComparisonsSuggestion, UnusedComparisons, VariantSizeDifferencesDiag, + InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons, + UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons, + VariantSizeDifferencesDiag, }; use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; @@ -166,6 +168,35 @@ declare_lint! { "detects ambiguous wide pointer comparisons" } +declare_lint! { + /// The `unpredictable_function_pointer_comparisons` lint checks comparison + /// of function pointer as the operands. + /// + /// ### Example + /// + /// ```rust + /// fn a() {} + /// fn b() {} + /// + /// let f: fn() = a; + /// let g: fn() = b; + /// + /// let _ = f == g; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Function pointers comparisons do not produce meaningful result since + /// they are never guaranteed to be unique and could vary between different + /// code generation units. Furthermore, different functions could have the + /// same address after being merged together. + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + Warn, + "detects unpredictable function pointer comparisons" +} + #[derive(Copy, Clone, Default)] pub(crate) struct TypeLimits { /// Id of the last visited negated expression @@ -178,7 +209,8 @@ impl_lint_pass!(TypeLimits => [ UNUSED_COMPARISONS, OVERFLOWING_LITERALS, INVALID_NAN_COMPARISONS, - AMBIGUOUS_WIDE_POINTER_COMPARISONS + AMBIGUOUS_WIDE_POINTER_COMPARISONS, + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS ]); impl TypeLimits { @@ -255,7 +287,7 @@ fn lint_nan<'tcx>( cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint); } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Copy, Clone)] enum ComparisonOp { BinOp(hir::BinOpKind), Other, @@ -383,6 +415,100 @@ fn lint_wide_pointer<'tcx>( ); } +fn lint_fn_pointer<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx hir::Expr<'tcx>, + cmpop: ComparisonOp, + l: &'tcx hir::Expr<'tcx>, + r: &'tcx hir::Expr<'tcx>, +) { + let peel_refs = |mut ty: Ty<'tcx>| -> (Ty<'tcx>, usize) { + let mut refs = 0; + + while let ty::Ref(_, inner_ty, _) = ty.kind() { + ty = *inner_ty; + refs += 1; + } + + (ty, refs) + }; + + // Left and right operands can have borrows, remove them + let l = l.peel_borrows(); + let r = r.peel_borrows(); + + let Some(l_ty) = cx.typeck_results().expr_ty_opt(l) else { return }; + let Some(r_ty) = cx.typeck_results().expr_ty_opt(r) else { return }; + + // Remove any references as `==` will deref through them (and count the + // number of references removed, for latter). + let (l_ty, l_ty_refs) = peel_refs(l_ty); + let (r_ty, r_ty_refs) = peel_refs(r_ty); + + if !l_ty.is_fn() || !r_ty.is_fn() { + return; + } + + // Let's try to suggest `ptr::fn_addr_eq` if/when possible. + + let is_eq_ne = matches!(cmpop, ComparisonOp::BinOp(hir::BinOpKind::Eq | hir::BinOpKind::Ne)); + + if !is_eq_ne { + // Neither `==` nor `!=`, we can't suggest `ptr::fn_addr_eq`, just show the warning. + return cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Warn, + ); + } + + let (Some(l_span), Some(r_span)) = + (l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span)) + else { + // No appropriate spans for the left and right operands, just show the warning. + return cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Warn, + ); + }; + + let ne = if cmpop == ComparisonOp::BinOp(hir::BinOpKind::Ne) { "!" } else { "" }; + + // `ptr::fn_addr_eq` only works with raw pointer, deref any references. + let deref_left = &*"*".repeat(l_ty_refs); + let deref_right = &*"*".repeat(r_ty_refs); + + let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo()); + let middle = l_span.shrink_to_hi().until(r_span.shrink_to_lo()); + let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi()); + + // We only check for a right cast as `FnDef` == `FnPtr` is not possible, + // only `FnPtr == FnDef` is possible. + let cast_right = if !r_ty.is_fn_ptr() { + let fn_sig = r_ty.fn_sig(cx.tcx); + format!(" as {fn_sig}") + } else { + String::new() + }; + + cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Suggestion { + sugg: UnpredictableFunctionPointerComparisonsSuggestion { + ne, + deref_left, + deref_right, + left, + middle, + right, + cast_right, + }, + }, + ); +} + impl<'tcx> LateLintPass<'tcx> for TypeLimits { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) { match e.kind { @@ -399,7 +525,9 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons); } else { lint_nan(cx, e, binop, l, r); - lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r); + let cmpop = ComparisonOp::BinOp(binop.node); + lint_wide_pointer(cx, e, cmpop, l, r); + lint_fn_pointer(cx, e, cmpop, l, r); } } } @@ -411,6 +539,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { && let Some(cmpop) = diag_item_cmpop(diag_item) => { lint_wide_pointer(cx, e, cmpop, l, r); + lint_fn_pointer(cx, e, cmpop, l, r); } hir::ExprKind::MethodCall(_, l, [r], _) if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) @@ -418,6 +547,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { && let Some(cmpop) = diag_item_cmpop(diag_item) => { lint_wide_pointer(cx, e, cmpop, l, r); + lint_fn_pointer(cx, e, cmpop, l, r); } _ => {} }; diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index f28cf84fa693e..f647486f62ade 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -84,12 +84,17 @@ mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable -mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns +mir_build_const_defined_here = constant defined here -mir_build_const_pattern_depends_on_generic_parameter = - constant pattern depends on a generic parameter +mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns + .label = can't be used in patterns +mir_build_const_param_in_pattern_def = constant defined here + +mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters + .label = `const` depends on a generic parameter mir_build_could_not_eval_const_pattern = could not evaluate constant pattern + .label = could not evaluate constant mir_build_deref_raw_pointer_requires_unsafe = dereference of raw pointer is unsafe and requires unsafe block @@ -147,7 +152,8 @@ mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = mir_build_interpreted_as_const = introduce a variable instead -mir_build_invalid_pattern = `{$non_sm_ty}` cannot be used in patterns +mir_build_invalid_pattern = {$prefix} `{$non_sm_ty}` cannot be used in patterns + .label = {$prefix} can't be used in patterns mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count -> [one] pattern @@ -244,10 +250,12 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa .label = mutation of layout constrained field mir_build_nan_pattern = cannot use NaN in patterns + .label = evaluates to `NaN`, which is not allowed in patterns .note = NaNs compare inequal to everything, even themselves, so this pattern would never match .help = try using the `is_nan` method instead mir_build_non_const_path = runtime values cannot be referenced in patterns + .label = references a runtime value mir_build_non_empty_never_pattern = mismatched types @@ -265,13 +273,15 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern -mir_build_non_partial_eq_match = - to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq` +mir_build_non_partial_eq_match = constant of non-structural type `{$ty}` in a pattern + .label = constant of non-structural type mir_build_pattern_not_covered = refutable pattern in {$origin} .pattern_ty = the matched value is of type `{$pattern_ty}` -mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon + .label = can't be used in patterns + .note = see https://github.com/rust-lang/rust/issues/70861 for details mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future @@ -283,6 +293,8 @@ mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .missing_box = `#[rustc_box]` requires the `owned_box` lang item mir_build_static_in_pattern = statics cannot be referenced in patterns + .label = can't be used in patterns +mir_build_static_in_pattern_def = `static` defined here mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits @@ -310,12 +322,12 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count -> *[other] them } into the body -mir_build_type_not_structural = - to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - +mir_build_type_not_structural = constant of non-structural type `{$ty}` in a pattern + .label = constant of non-structural type +mir_build_type_not_structural_def = `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -mir_build_type_not_structural_tip = the traits must be derived, manual `impl`s are not sufficient +mir_build_type_not_structural_tip = + the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details mir_build_unconditional_recursion = function cannot return without recursing .label = cannot return without recursing @@ -334,6 +346,7 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .label = access to union field mir_build_union_pattern = cannot use unions in constant patterns + .label = can't use a `union` here mir_build_unreachable_making_this_unreachable = collectively making this unreachable diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 58487a48184ad..3632da943e18b 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -631,20 +631,27 @@ pub(crate) struct NonExhaustiveMatchAllArmsGuarded; #[diag(mir_build_static_in_pattern, code = E0158)] pub(crate) struct StaticInPattern { #[primary_span] + #[label] pub(crate) span: Span, + #[label(mir_build_static_in_pattern_def)] + pub(crate) static_span: Span, } #[derive(Diagnostic)] #[diag(mir_build_const_param_in_pattern, code = E0158)] pub(crate) struct ConstParamInPattern { #[primary_span] + #[label] pub(crate) span: Span, + #[label(mir_build_const_param_in_pattern_def)] + pub(crate) const_span: Span, } #[derive(Diagnostic)] #[diag(mir_build_non_const_path, code = E0080)] pub(crate) struct NonConstPath { #[primary_span] + #[label] pub(crate) span: Span, } @@ -695,6 +702,7 @@ pub(crate) struct WantedConstant { #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] + #[label] pub(crate) span: Span, } @@ -702,6 +710,7 @@ pub(crate) struct ConstPatternDependsOnGenericParameter { #[diag(mir_build_could_not_eval_const_pattern)] pub(crate) struct CouldNotEvalConstPattern { #[primary_span] + #[label] pub(crate) span: Span, } @@ -867,33 +876,43 @@ pub(crate) enum Conflict { #[diag(mir_build_union_pattern)] pub(crate) struct UnionPattern { #[primary_span] + #[label] pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_type_not_structural)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] pub(crate) struct TypeNotStructural<'tcx> { #[primary_span] + #[label] pub(crate) span: Span, - pub(crate) non_sm_ty: Ty<'tcx>, + #[label(mir_build_type_not_structural_def)] + pub(crate) ty_def_span: Span, + pub(crate) ty: Ty<'tcx>, + #[note(mir_build_type_not_structural_tip)] + pub(crate) manual_partialeq_impl_span: Option, + #[note(mir_build_type_not_structural_more_info)] + pub(crate) manual_partialeq_impl_note: bool, } #[derive(Diagnostic)] #[diag(mir_build_non_partial_eq_match)] +#[note(mir_build_type_not_structural_more_info)] pub(crate) struct TypeNotPartialEq<'tcx> { #[primary_span] + #[label] pub(crate) span: Span, - pub(crate) non_peq_ty: Ty<'tcx>, + pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_invalid_pattern)] pub(crate) struct InvalidPattern<'tcx> { #[primary_span] + #[label] pub(crate) span: Span, pub(crate) non_sm_ty: Ty<'tcx>, + pub(crate) prefix: String, } #[derive(Diagnostic)] @@ -910,13 +929,16 @@ pub(crate) struct UnsizedPattern<'tcx> { #[help] pub(crate) struct NaNPattern { #[primary_span] + #[label] pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_pointer_pattern)] +#[note] pub(crate) struct PointerPattern { #[primary_span] + #[label] pub(crate) span: Span, } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 5db08f01fdbdc..aed00aecefc99 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,14 +1,17 @@ use rustc_abi::{FieldIdx, VariantIdx}; use rustc_apfloat::Float; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Diag; use rustc_hir as hir; use rustc_index::Idx; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::Obligation; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::{FieldPat, Pat, PatKind}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeVisitor, ValTree}; use rustc_middle::{mir, span_bug}; -use rustc_span::Span; +use rustc_span::def_id::DefId; +use rustc_span::{Span, sym}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; @@ -35,7 +38,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { id: hir::HirId, span: Span, ) -> Box> { - let mut convert = ConstToPat::new(self, id, span); + let mut convert = ConstToPat::new(self, id, span, c); match c.kind() { ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty), @@ -49,21 +52,26 @@ struct ConstToPat<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, span: Span, + id: hir::HirId, treat_byte_string_as_slice: bool, + + c: ty::Const<'tcx>, } impl<'tcx> ConstToPat<'tcx> { - fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self { + fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self { trace!(?pat_ctxt.typeck_results.hir_owner); ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, + id, treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice .contains(&id.local_id), + c, } } @@ -71,13 +79,32 @@ impl<'tcx> ConstToPat<'tcx> { ty.is_structural_eq_shallow(self.tcx) } + /// We errored. Signal that in the pattern, so that follow up errors can be silenced. + fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box> { + if let ty::ConstKind::Unevaluated(uv) = self.c.kind() { + let def_kind = self.tcx.def_kind(uv.def); + if let hir::def::DefKind::AssocConst = def_kind + && let Some(def_id) = uv.def.as_local() + { + // Include the container item in the output. + err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), ""); + } + if let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = def_kind { + err.span_label( + self.tcx.def_span(uv.def), + crate::fluent_generated::mir_build_const_defined_here, + ); + } + } + Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) }) + } + fn unevaluated_to_pat( &mut self, uv: ty::UnevaluatedConst<'tcx>, ty: Ty<'tcx>, ) -> Box> { trace!(self.treat_byte_string_as_slice); - let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind }); // It's not *technically* correct to be revealing opaque types here as borrowcheck has // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even @@ -96,32 +123,60 @@ impl<'tcx> ConstToPat<'tcx> { Ok(Ok(c)) => c, Err(ErrorHandled::Reported(_, _)) => { // Let's tell the use where this failing const occurs. - let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span }); - return pat_from_kind(PatKind::Error(e)); + let mut err = + self.tcx.dcx().create_err(CouldNotEvalConstPattern { span: self.span }); + // We've emitted an error on the original const, it would be redundant to complain + // on its use as well. + if let ty::ConstKind::Unevaluated(uv) = self.c.kind() + && let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = + self.tcx.def_kind(uv.def) + { + err.downgrade_to_delayed_bug(); + } + return self.mk_err(err, ty); } Err(ErrorHandled::TooGeneric(_)) => { - let e = self + let mut e = self .tcx .dcx() - .emit_err(ConstPatternDependsOnGenericParameter { span: self.span }); - return pat_from_kind(PatKind::Error(e)); + .create_err(ConstPatternDependsOnGenericParameter { span: self.span }); + for arg in uv.args { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + { + let def_id = self.tcx.hir().enclosing_body_owner(self.id); + let generics = self.tcx.generics_of(def_id); + let param = generics.type_param(*param_ty, self.tcx); + let span = self.tcx.def_span(param.def_id); + e.span_label(span, "constant depends on this generic parameter"); + if let Some(ident) = self.tcx.def_ident_span(def_id) + && self.tcx.sess.source_map().is_multiline(ident.between(span)) + { + // Display the `fn` name as well in the diagnostic, as the generic isn't + // in the same line and it could be confusing otherwise. + e.span_label(ident, ""); + } + } + } + return self.mk_err(e, ty); } Ok(Err(bad_ty)) => { // The pattern cannot be turned into a valtree. let e = match bad_ty.kind() { ty::Adt(def, ..) => { assert!(def.is_union()); - self.tcx.dcx().emit_err(UnionPattern { span: self.span }) + self.tcx.dcx().create_err(UnionPattern { span: self.span }) } ty::FnPtr(..) | ty::RawPtr(..) => { - self.tcx.dcx().emit_err(PointerPattern { span: self.span }) + self.tcx.dcx().create_err(PointerPattern { span: self.span }) } - _ => self - .tcx - .dcx() - .emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }), + _ => self.tcx.dcx().create_err(InvalidPattern { + span: self.span, + non_sm_ty: bad_ty, + prefix: bad_ty.prefix_string(self.tcx).to_string(), + }), }; - return pat_from_kind(PatKind::Error(e)); + return self.mk_err(e, ty); } }; @@ -130,42 +185,16 @@ impl<'tcx> ConstToPat<'tcx> { if !inlined_const_as_pat.references_error() { // Always check for `PartialEq` if we had no other errors yet. - if !self.type_has_partial_eq_impl(ty) { - let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty }; - let e = self.tcx.dcx().emit_err(err); - return pat_from_kind(PatKind::Error(e)); + if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 { + let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty }); + extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err); + return self.mk_err(err, ty); } } inlined_const_as_pat } - #[instrument(level = "trace", skip(self), ret)] - fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool { - let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); - // double-check there even *is* a semantic `PartialEq` to dispatch to. - // - // (If there isn't, then we can safely issue a hard - // error, because that's never worked, due to compiler - // using `PartialEq::eq` in this scenario in the past.) - let partial_eq_trait_id = - self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span)); - let partial_eq_obligation = Obligation::new( - self.tcx, - ObligationCause::dummy(), - param_env, - ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]), - ); - - // This *could* accept a type that isn't actually `PartialEq`, because region bounds get - // ignored. However that should be pretty much impossible since consts that do not depend on - // generics can only mention the `'static` lifetime, and how would one have a type that's - // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem - // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck - // can ensure that the type really implements `PartialEq`. - infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation) - } - fn field_pats( &self, vals: impl Iterator, Ty<'tcx>)>, @@ -190,10 +219,25 @@ impl<'tcx> ConstToPat<'tcx> { // Extremely important check for all ADTs! Make sure they opted-in to be used in // patterns. debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty); - let err = TypeNotStructural { span, non_sm_ty: ty }; - let e = tcx.dcx().emit_err(err); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) + let (_impls_partial_eq, derived, structural, impl_def_id) = + type_has_partial_eq_impl(self.tcx, self.typing_env, ty); + let (manual_partialeq_impl_span, manual_partialeq_impl_note) = + match (structural, impl_def_id) { + (true, _) => (None, false), + (_, Some(def_id)) if def_id.is_local() && !derived => { + (Some(tcx.def_span(def_id)), false) + } + _ => (None, true), + }; + let ty_def_span = tcx.def_span(adt_def.did()); + let err = TypeNotStructural { + span, + ty, + ty_def_span, + manual_partialeq_impl_span, + manual_partialeq_impl_note, + }; + return self.mk_err(tcx.dcx().create_err(err), ty); } ty::Adt(adt_def, args) if adt_def.is_enum() => { let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); @@ -207,7 +251,7 @@ impl<'tcx> ConstToPat<'tcx> { adt_def.variants()[variant_index] .fields .iter() - .map(|field| field.ty(self.tcx, args)), + .map(|field| field.ty(tcx, args)), ), ), } @@ -216,7 +260,7 @@ impl<'tcx> ConstToPat<'tcx> { assert!(!def.is_union()); // Valtree construction would never succeed for unions. PatKind::Leaf { subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip( - def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)), + def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)), )), } } @@ -252,10 +296,10 @@ impl<'tcx> ConstToPat<'tcx> { // deref pattern. _ => { if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() { - let err = UnsizedPattern { span, non_sm_ty: *pointee_ty }; - let e = tcx.dcx().emit_err(err); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) + return self.mk_err( + tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }), + ty, + ); } else { // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // matching against references, you can only use byte string literals. @@ -286,8 +330,7 @@ impl<'tcx> ConstToPat<'tcx> { if is_nan { // NaNs are not ever equal to anything so they make no sense as patterns. // Also see . - let e = tcx.dcx().emit_err(NaNPattern { span }); - PatKind::Error(e) + return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty); } else { PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), @@ -305,13 +348,153 @@ impl<'tcx> ConstToPat<'tcx> { ) } _ => { - let err = InvalidPattern { span, non_sm_ty: ty }; - let e = tcx.dcx().emit_err(err); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) + let err = InvalidPattern { + span, + non_sm_ty: ty, + prefix: ty.prefix_string(tcx).to_string(), + }; + return self.mk_err(tcx.dcx().create_err(err), ty); } }; Box::new(Pat { span, ty, kind }) } } + +/// Given a type with type parameters, visit every ADT looking for types that need to +/// `#[derive(PartialEq)]` for it to be a structural type. +fn extend_type_not_partial_eq<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + err: &mut Diag<'_>, +) { + /// Collect all types that need to be `StructuralPartialEq`. + struct UsedParamsNeedInstantiationVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + /// The user has written `impl PartialEq for Ty` which means it's non-structual. + adts_with_manual_partialeq: FxHashSet, + /// The type has no `PartialEq` implementation, neither manual or derived. + adts_without_partialeq: FxHashSet, + /// The user has written `impl PartialEq for Ty` which means it's non-structual, + /// but we don't have a span to point at, so we'll just add them as a `note`. + manual: Vec>, + /// The type has no `PartialEq` implementation, neither manual or derived, but + /// we don't have a span to point at, so we'll just add them as a `note`. + without: Vec>, + } + + impl<'tcx> TypeVisitor> for UsedParamsNeedInstantiationVisitor<'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if let ty::Adt(def, _args) = ty.kind() { + let ty_def_id = def.did(); + let ty_def_span = self.tcx.def_span(ty_def_id); + let (impls_partial_eq, derived, structural, impl_def_id) = + type_has_partial_eq_impl(self.tcx, self.typing_env, ty); + match (impls_partial_eq, derived, structural, impl_def_id) { + (_, _, true, _) => {} + (true, false, _, Some(def_id)) if def_id.is_local() => { + self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id)); + } + (true, false, _, _) if ty_def_id.is_local() => { + self.adts_with_manual_partialeq.insert(ty_def_span); + } + (false, _, _, _) if ty_def_id.is_local() => { + self.adts_without_partialeq.insert(ty_def_span); + } + (true, false, _, _) => { + self.manual.push(ty); + } + (false, _, _, _) => { + self.without.push(ty); + } + _ => {} + }; + } + use rustc_middle::ty::TypeSuperVisitable; + ty.super_visit_with(self) + } + } + let mut v = UsedParamsNeedInstantiationVisitor { + tcx, + typing_env, + adts_with_manual_partialeq: FxHashSet::default(), + adts_without_partialeq: FxHashSet::default(), + manual: vec![], + without: vec![], + }; + v.visit_ty(ty); + #[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering + for span in v.adts_with_manual_partialeq { + err.span_note(span, "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details"); + } + #[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering + for span in v.adts_without_partialeq { + err.span_label( + span, + "must be annotated with `#[derive(PartialEq)]` to be usable in patterns", + ); + } + for ty in v.manual { + err.note(format!( + "`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" + )); + } + for ty in v.without { + err.note(format!( + "`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns" + )); + } +} + +#[instrument(level = "trace", skip(tcx), ret)] +fn type_has_partial_eq_impl<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, +) -> ( + /* has impl */ bool, + /* is derived */ bool, + /* structural partial eq */ bool, + /* non-blanket impl */ Option, +) { + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); + // double-check there even *is* a semantic `PartialEq` to dispatch to. + // + // (If there isn't, then we can safely issue a hard + // error, because that's never worked, due to compiler + // using `PartialEq::eq` in this scenario in the past.) + let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None); + let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None); + + let partial_eq_obligation = Obligation::new( + tcx, + ObligationCause::dummy(), + param_env, + ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]), + ); + + let mut automatically_derived = false; + let mut structural_peq = false; + let mut impl_def_id = None; + for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) { + automatically_derived = tcx.has_attr(def_id, sym::automatically_derived); + impl_def_id = Some(def_id); + } + for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) { + structural_peq = true; + } + // This *could* accept a type that isn't actually `PartialEq`, because region bounds get + // ignored. However that should be pretty much impossible since consts that do not depend on + // generics can only mention the `'static` lifetime, and how would one have a type that's + // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem + // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck + // can ensure that the type really implements `PartialEq`. + ( + infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation), + automatically_derived, + structural_peq, + impl_def_id, + ) +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 08c6b4abd3b91..3ac53fa6272be 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -528,11 +528,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { | Res::SelfCtor(..) => PatKind::Leaf { subpatterns }, _ => { let e = match res { - Res::Def(DefKind::ConstParam, _) => { - self.tcx.dcx().emit_err(ConstParamInPattern { span }) + Res::Def(DefKind::ConstParam, def_id) => { + self.tcx.dcx().emit_err(ConstParamInPattern { + span, + const_span: self.tcx().def_span(def_id), + }) } - Res::Def(DefKind::Static { .. }, _) => { - self.tcx.dcx().emit_err(StaticInPattern { span }) + Res::Def(DefKind::Static { .. }, def_id) => { + self.tcx.dcx().emit_err(StaticInPattern { + span, + static_span: self.tcx().def_span(def_id), + }) } _ => self.tcx.dcx().emit_err(NonConstPath { span }), }; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 809357ec11009..b8383e734e2ba 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -747,8 +747,8 @@ fn build_call_shim<'tcx>( sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } - // FIXME(eddyb) avoid having this snippet both here and in - // `Instance::fn_sig` (introduce `InstanceKind::fn_sig`?). + // FIXME: Avoid having to adjust the signature both here and in + // `fn_sig_for_fn_abi`. if let ty::InstanceKind::VTableShim(..) = instance { // Modify fn(self, ...) to fn(self: *mut Self, ...) let mut inputs_and_output = sig.inputs_and_output.to_vec(); diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index b9a325eddd800..e5cd4622dae90 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -343,6 +343,9 @@ parse_incorrect_semicolon = .suggestion = remove this semicolon .help = {$name} declarations are not followed by a semicolon +parse_incorrect_type_on_self = type not allowed for shorthand `self` parameter + .suggestion = move the modifiers on `self` to the type + parse_incorrect_use_of_await = incorrect use of `await` .parentheses_suggestion = `await` is not a method call, remove the parentheses diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 2579e4c1f2596..14f2dd32e9232 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3409,3 +3409,22 @@ pub(crate) struct PolarityAndModifiers { pub polarity: &'static str, pub modifiers_concatenated: String, } + +#[derive(Diagnostic)] +#[diag(parse_incorrect_type_on_self)] +pub(crate) struct IncorrectTypeOnSelf { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub move_self_modifier: MoveSelfModifier, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +pub(crate) struct MoveSelfModifier { + #[suggestion_part(code = "")] + pub removal_span: Span, + #[suggestion_part(code = "{modifier}")] + pub insertion_span: Span, + pub modifier: String, +} diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 26e81b7676bb1..475cd09147f5c 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2941,6 +2941,32 @@ impl<'a> Parser<'a> { }; Ok((eself, eself_ident, eself_hi)) }; + let expect_self_ident_not_typed = + |this: &mut Self, modifier: &SelfKind, modifier_span: Span| { + let eself_ident = expect_self_ident(this); + + // Recover `: Type` after a qualified self + if this.may_recover() && this.eat_noexpect(&token::Colon) { + let snap = this.create_snapshot_for_diagnostic(); + match this.parse_ty() { + Ok(ty) => { + this.dcx().emit_err(errors::IncorrectTypeOnSelf { + span: ty.span, + move_self_modifier: errors::MoveSelfModifier { + removal_span: modifier_span, + insertion_span: ty.span.shrink_to_lo(), + modifier: modifier.to_ref_suggestion(), + }, + }); + } + Err(diag) => { + diag.cancel(); + this.restore_snapshot(snap); + } + } + } + eself_ident + }; // Recover for the grammar `*self`, `*const self`, and `*mut self`. let recover_self_ptr = |this: &mut Self| { this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span }); @@ -2978,7 +3004,9 @@ impl<'a> Parser<'a> { // `¬_self` return Ok(None); }; - (eself, expect_self_ident(self), self.prev_token.span) + let hi = self.token.span; + let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi)); + (eself, self_ident, hi) } // `*self` token::BinOp(token::Star) if is_isolated_self(self, 1) => { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 2bb503f17b4ed..94682f501a8c4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3838,6 +3838,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && self.predicate_must_hold_modulo_regions(&Obligation::misc( tcx, expr.span, body_id, param_env, pred, )) + && expr.span.hi() != rcvr.span.hi() { err.span_suggestion_verbose( expr.span.with_lo(rcvr.span.hi()), @@ -4115,6 +4116,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // the expected is a projection that we need to resolve. // && let Some(tail_ty) = typeck_results.expr_ty_opt(expr) && expected_found.found.is_unit() + // FIXME: this happens with macro calls. Need to figure out why the stmt + // `println!();` doesn't include the `;` in its `Span`. (#133845) + // We filter these out to avoid ICEs with debug assertions on caused by + // empty suggestions. + && expr.span.hi() != stmt.span.hi() { err.span_suggestion_verbose( expr.span.shrink_to_hi().with_hi(stmt.span.hi()), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 19b4125e75cdf..2fbe2e1e323be 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -16,9 +16,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; -use rustc_middle::ty::{ - self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, Ty, TyCtxt, Upcast, -}; +use rustc_middle::ty::{self, GenericArgsRef, ToPolyTraitRef, Ty, TyCtxt, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use tracing::{debug, instrument}; @@ -638,60 +636,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // higher-ranked things. // Prevent, e.g., `dyn Iterator`. for bound in self.tcx().item_bounds(assoc_type).transpose_iter() { - let arg_bound = if defs.is_empty() { - bound.instantiate(tcx, trait_predicate.trait_ref.args) - } else { - let mut args = smallvec::SmallVec::with_capacity(defs.count()); - args.extend(trait_predicate.trait_ref.args.iter()); - let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = - smallvec::SmallVec::with_capacity( - bound.skip_binder().kind().bound_vars().len() + defs.count(), - ); - bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter()); - GenericArgs::fill_single(&mut args, defs, &mut |param, _| match param.kind { - GenericParamDefKind::Type { .. } => { - let kind = ty::BoundTyKind::Param(param.def_id, param.name); - let bound_var = ty::BoundVariableKind::Ty(kind); - bound_vars.push(bound_var); - Ty::new_bound(tcx, ty::INNERMOST, ty::BoundTy { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind, - }) - .into() - } - GenericParamDefKind::Lifetime => { - let kind = ty::BoundRegionKind::Named(param.def_id, param.name); - let bound_var = ty::BoundVariableKind::Region(kind); - bound_vars.push(bound_var); - ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind, - }) - .into() - } - GenericParamDefKind::Const { .. } => { - let bound_var = ty::BoundVariableKind::Const; - bound_vars.push(bound_var); - ty::Const::new_bound( - tcx, - ty::INNERMOST, - ty::BoundVar::from_usize(bound_vars.len() - 1), - ) - .into() - } - }); - let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); - let assoc_ty_args = tcx.mk_args(&args); - let bound = - bound.map_bound(|b| b.kind().skip_binder()).instantiate(tcx, assoc_ty_args); - ty::Binder::bind_with_vars(bound, bound_vars).upcast(tcx) - }; let normalized_bound = normalize_with_depth_to( self, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - arg_bound, + bound.instantiate(tcx, trait_predicate.trait_ref.args), &mut nested, ); nested.push(obligation.with(tcx, normalized_bound)); diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index a5a9125c8b509..b746d6299efda 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -31,20 +31,20 @@ fn fn_sig_for_fn_abi<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>, typing_env: ty::TypingEnv<'tcx>, -) -> ty::PolyFnSig<'tcx> { +) -> ty::FnSig<'tcx> { if let InstanceKind::ThreadLocalShim(..) = instance.def { - return ty::Binder::dummy(tcx.mk_fn_sig( + return tcx.mk_fn_sig( [], tcx.thread_local_ptr_ty(instance.def_id()), false, hir::Safety::Safe, rustc_abi::ExternAbi::Unadjusted, - )); + ); } let ty = instance.ty(tcx, typing_env); match *ty.kind() { - ty::FnDef(..) => { + ty::FnDef(def_id, args) => { // HACK(davidtwco,eddyb): This is a workaround for polymorphization considering // parameters unused if they show up in the signature, but not in the `mir::Body` // (i.e. due to being inside a projection that got normalized, see @@ -52,9 +52,8 @@ fn fn_sig_for_fn_abi<'tcx>( // track of a polymorphization `ParamEnv` to allow normalizing later. // // We normalize the `fn_sig` again after instantiating at a later point. - let mut sig = match *ty.kind() { - ty::FnDef(def_id, args) => tcx - .fn_sig(def_id) + let mut sig = tcx.instantiate_bound_regions_with_erased( + tcx.fn_sig(def_id) .map_bound(|fn_sig| { tcx.normalize_erasing_regions( ty::TypingEnv::non_body_analysis(tcx, def_id), @@ -62,62 +61,36 @@ fn fn_sig_for_fn_abi<'tcx>( ) }) .instantiate(tcx, args), - _ => unreachable!(), - }; + ); if let ty::InstanceKind::VTableShim(..) = instance.def { - // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. - sig = sig.map_bound(|mut sig| { - let mut inputs_and_output = sig.inputs_and_output.to_vec(); - inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); - sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); - sig - }); + let mut inputs_and_output = sig.inputs_and_output.to_vec(); + inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } + sig } ty::Closure(def_id, args) => { - let sig = args.as_closure().sig(); - - let bound_vars = - tcx.mk_bound_variable_kinds_from_iter(sig.bound_vars().iter().chain(iter::once( - ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv), - ))); - let br = ty::BoundRegion { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind: ty::BoundRegionKind::ClosureEnv, - }; - let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br); + let sig = tcx.instantiate_bound_regions_with_erased(args.as_closure().sig()); let env_ty = tcx.closure_env_ty( Ty::new_closure(tcx, def_id, args), args.as_closure().kind(), - env_region, + tcx.lifetimes.re_erased, ); - let sig = sig.skip_binder(); - ty::Binder::bind_with_vars( - tcx.mk_fn_sig( - iter::once(env_ty).chain(sig.inputs().iter().cloned()), - sig.output(), - sig.c_variadic, - sig.safety, - sig.abi, - ), - bound_vars, + tcx.mk_fn_sig( + iter::once(env_ty).chain(sig.inputs().iter().cloned()), + sig.output(), + sig.c_variadic, + sig.safety, + sig.abi, ) } ty::CoroutineClosure(def_id, args) => { let coroutine_ty = Ty::new_coroutine_closure(tcx, def_id, args); let sig = args.as_coroutine_closure().coroutine_closure_sig(); - let bound_vars = - tcx.mk_bound_variable_kinds_from_iter(sig.bound_vars().iter().chain(iter::once( - ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv), - ))); - let br = ty::BoundRegion { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind: ty::BoundRegionKind::ClosureEnv, - }; - let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br); + // When this `CoroutineClosure` comes from a `ConstructCoroutineInClosureShim`, // make sure we respect the `target_kind` in that shim. // FIXME(async_closures): This shouldn't be needed, and we should be populating @@ -138,42 +111,32 @@ fn fn_sig_for_fn_abi<'tcx>( coroutine_ty } } else { - tcx.closure_env_ty(coroutine_ty, coroutine_kind, env_region) + tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) }; - let sig = sig.skip_binder(); - ty::Binder::bind_with_vars( - tcx.mk_fn_sig( - iter::once(env_ty).chain([sig.tupled_inputs_ty]), - sig.to_coroutine_given_kind_and_upvars( - tcx, - args.as_coroutine_closure().parent_args(), - tcx.coroutine_for_closure(def_id), - coroutine_kind, - env_region, - args.as_coroutine_closure().tupled_upvars_ty(), - args.as_coroutine_closure().coroutine_captures_by_ref_ty(), - ), - sig.c_variadic, - sig.safety, - sig.abi, + let sig = tcx.instantiate_bound_regions_with_erased(sig); + + tcx.mk_fn_sig( + iter::once(env_ty).chain([sig.tupled_inputs_ty]), + sig.to_coroutine_given_kind_and_upvars( + tcx, + args.as_coroutine_closure().parent_args(), + tcx.coroutine_for_closure(def_id), + coroutine_kind, + tcx.lifetimes.re_erased, + args.as_coroutine_closure().tupled_upvars_ty(), + args.as_coroutine_closure().coroutine_captures_by_ref_ty(), ), - bound_vars, + sig.c_variadic, + sig.safety, + sig.abi, ) } ty::Coroutine(did, args) => { let coroutine_kind = tcx.coroutine_kind(did).unwrap(); let sig = args.as_coroutine().sig(); - let bound_vars = tcx.mk_bound_variable_kinds_from_iter(iter::once( - ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv), - )); - let br = ty::BoundRegion { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind: ty::BoundRegionKind::ClosureEnv, - }; - - let env_ty = Ty::new_mut_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), ty); + let env_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty); let pin_did = tcx.require_lang_item(LangItem::Pin, None); let pin_adt_ref = tcx.adt_def(pin_did); @@ -268,7 +231,7 @@ fn fn_sig_for_fn_abi<'tcx>( } }; - let fn_sig = if let Some(resume_ty) = resume_ty { + if let Some(resume_ty) = resume_ty { tcx.mk_fn_sig( [env_ty, resume_ty], ret_ty, @@ -285,8 +248,7 @@ fn fn_sig_for_fn_abi<'tcx>( hir::Safety::Safe, rustc_abi::ExternAbi::Rust, ) - }; - ty::Binder::bind_with_vars(fn_sig, bound_vars) + } } _ => bug!("unexpected type {:?} in Instance::fn_sig", ty), } @@ -335,8 +297,16 @@ fn fn_abi_of_fn_ptr<'tcx>( query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let ty::PseudoCanonicalInput { typing_env, value: (sig, extra_args) } = query; + let cx = LayoutCx::new(tcx, typing_env); - fn_abi_new_uncached(&cx, sig, extra_args, None, None, false) + fn_abi_new_uncached( + &cx, + tcx.instantiate_bound_regions_with_erased(sig), + extra_args, + None, + None, + false, + ) } fn fn_abi_of_instance<'tcx>( @@ -567,7 +537,7 @@ fn fn_abi_sanity_check<'tcx>( #[tracing::instrument(level = "debug", skip(cx, caller_location, fn_def_id, force_thin_self_ptr))] fn fn_abi_new_uncached<'tcx>( cx: &LayoutCx<'tcx>, - sig: ty::PolyFnSig<'tcx>, + sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>], caller_location: Option>, fn_def_id: Option, @@ -575,7 +545,7 @@ fn fn_abi_new_uncached<'tcx>( force_thin_self_ptr: bool, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let tcx = cx.tcx(); - let sig = tcx.normalize_erasing_late_bound_regions(cx.typing_env, sig); + let sig = tcx.normalize_erasing_regions(cx.typing_env, sig); let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic); diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ab9c33ee75477..fde6887c5abae 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -345,7 +345,7 @@ pub mod net; pub mod option; pub mod panic; pub mod panicking; -#[unstable(feature = "core_pattern_types", issue = "123646")] +#[unstable(feature = "pattern_type_macro", issue = "123646")] pub mod pat; pub mod pin; #[unstable(feature = "random", issue = "130703")] diff --git a/library/core/src/pat.rs b/library/core/src/pat.rs index 1f89d960be67b..752e79c2dacee 100644 --- a/library/core/src/pat.rs +++ b/library/core/src/pat.rs @@ -6,7 +6,7 @@ /// ``` #[macro_export] #[rustc_builtin_macro(pattern_type)] -#[unstable(feature = "core_pattern_type", issue = "123646")] +#[unstable(feature = "pattern_type_macro", issue = "123646")] macro_rules! pattern_type { ($($arg:tt)*) => { /* compiler built-in */ diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 7e9773f2fb952..454b13a7ee389 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -304,6 +304,7 @@ fn test_const_nonnull_new() { #[test] #[cfg(unix)] // printf may not be available on other platforms #[allow(deprecated)] // For SipHasher +#[cfg_attr(not(bootstrap), allow(unpredictable_function_pointer_comparisons))] pub fn test_variadic_fnptr() { use core::ffi; use core::hash::{Hash, SipHasher}; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 585946c1d50e0..6be27b283b291 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -589,7 +589,7 @@ pub mod net; pub mod num; pub mod os; pub mod panic; -#[unstable(feature = "core_pattern_types", issue = "123646")] +#[unstable(feature = "pattern_type_macro", issue = "123646")] pub mod pat; pub mod path; #[unstable(feature = "anonymous_pipe", issue = "127154")] diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 74dfe2e7ec80f..ee813de1c9e26 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -48,9 +48,9 @@ fn main() { err => { drop(err); if let Ok(pid) = pid { - eprintln!("WARNING: build directory locked by process {pid}, waiting for lock"); + println!("WARNING: build directory locked by process {pid}, waiting for lock"); } else { - eprintln!("WARNING: build directory locked, waiting for lock"); + println!("WARNING: build directory locked, waiting for lock"); } let mut lock = t!(build_lock.write()); t!(lock.write(process::id().to_string().as_ref())); @@ -70,13 +70,13 @@ fn main() { // changelog warning, not the `x.py setup` message. let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); if suggest_setup { - eprintln!("WARNING: you have not made a `config.toml`"); - eprintln!( + println!("WARNING: you have not made a `config.toml`"); + println!( "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { - eprintln!("{suggestion}"); + println!("{suggestion}"); } let pre_commit = config.src.join(".git").join("hooks").join("pre-commit"); @@ -86,13 +86,13 @@ fn main() { Build::new(config).build(); if suggest_setup { - eprintln!("WARNING: you have not made a `config.toml`"); - eprintln!( + println!("WARNING: you have not made a `config.toml`"); + println!( "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { - eprintln!("{suggestion}"); + println!("{suggestion}"); } // Give a warning if the pre-commit script is in pre-commit and not pre-push. @@ -102,14 +102,14 @@ fn main() { if fs::read_to_string(pre_commit).is_ok_and(|contents| { contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570") }) { - eprintln!( + println!( "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \ Consider moving it to .git/hooks/pre-push instead, which runs less often." ); } if suggest_setup || changelog_suggestion.is_some() { - eprintln!("NOTE: this message was printed twice to make it more likely to be seen"); + println!("NOTE: this message was printed twice to make it more likely to be seen"); } if dump_bootstrap_shims { diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index e57ed488f973e..88595ff7e5198 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -306,7 +306,7 @@ fn main() { // should run on success, after this block. } if verbose > 0 { - eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); + println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); } if let Some(mut on_fail) = on_fail { diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 2af2e83db8f76..d46c0ab7fefcf 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -287,7 +287,7 @@ impl Step for CodegenBackend { fn run(self, builder: &Builder<'_>) { // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved if builder.build.config.vendor && self.backend == "gcc" { - eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); + println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); return; } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4419b11ac1971..0cacd6e4f37ac 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1611,7 +1611,7 @@ impl Step for Sysroot { let sysroot = sysroot_dir(compiler.stage); builder - .verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display())); + .verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display())); let _ = fs::remove_dir_all(&sysroot); t!(fs::create_dir_all(&sysroot)); @@ -1681,7 +1681,7 @@ impl Step for Sysroot { return true; } if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) { - builder.verbose_than(1, || eprintln!("ignoring {}", path.display())); + builder.verbose_than(1, || println!("ignoring {}", path.display())); false } else { true @@ -2240,7 +2240,7 @@ pub fn stream_cargo( cargo.arg(arg); } - builder.verbose(|| eprintln!("running: {cargo:?}")); + builder.verbose(|| println!("running: {cargo:?}")); if builder.config.dry_run() { return true; @@ -2261,12 +2261,12 @@ pub fn stream_cargo( Ok(msg) => { if builder.config.json_output { // Forward JSON to stdout. - eprintln!("{line}"); + println!("{line}"); } cb(msg) } // If this was informational, just print it out and continue - Err(_) => eprintln!("{line}"), + Err(_) => println!("{line}"), } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 57fce206f954b..0c739115165ec 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2080,7 +2080,7 @@ fn maybe_install_llvm( { let mut cmd = command(llvm_config); cmd.arg("--libfiles"); - builder.verbose(|| eprintln!("running {cmd:?}")); + builder.verbose(|| println!("running {cmd:?}")); let files = cmd.run_capture_stdout(builder).stdout(); let build_llvm_out = &builder.llvm_out(builder.config.build); let target_llvm_out = &builder.llvm_out(target); diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index d32e06d8748ac..29a96f7767281 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -107,10 +107,10 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) { if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() }; if len <= 10 { for path in paths { - eprintln!("fmt: {verb} {adjective}file {path}"); + println!("fmt: {verb} {adjective}file {path}"); } } else { - eprintln!("fmt: {verb} {len} {adjective}files"); + println!("fmt: {verb} {len} {adjective}files"); } } @@ -199,7 +199,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { match get_modified_rs_files(build) { Ok(Some(files)) => { if files.is_empty() { - eprintln!("fmt info: No modified files detected for formatting."); + println!("fmt info: No modified files detected for formatting."); return; } diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 1af7b954f5ed8..3a8f9e48c0da2 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -134,7 +134,7 @@ impl Step for Profile { t!(fs::remove_file(path)); } _ => { - eprintln!("Exiting."); + println!("Exiting."); crate::exit!(1); } } @@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) { Profile::Dist => &["dist", "build"], }; - eprintln!(); + println!(); - eprintln!("To get started, try one of the following commands:"); + println!("To get started, try one of the following commands:"); for cmd in suggestions { - eprintln!("- `x.py {cmd}`"); + println!("- `x.py {cmd}`"); } if profile != Profile::Dist { - eprintln!( + println!( "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html" ); } @@ -224,7 +224,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { t!(fs::write(path, settings)); let include_path = profile.include_path(&config.src); - eprintln!("`x.py` will now use the configuration at {}", include_path.display()); + println!("`x.py` will now use the configuration at {}", include_path.display()); } /// Creates a toolchain link for stage1 using `rustup` @@ -256,7 +256,7 @@ impl Step for Link { } if !rustup_installed(builder) { - eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); + println!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); return; } @@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) { } if try_link_toolchain(builder, stage_path) { - eprintln!( + println!( "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain" ); } else { @@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool { return false; } // The toolchain has already been linked. - eprintln!( + println!( "`stage1` toolchain already linked; not attempting to link `stage1` toolchain" ); } None => { // In this case, we don't know if the `stage1` toolchain has been linked; // but `rustup` failed, so let's not go any further. - eprintln!( + println!( "`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain" ); } @@ -389,9 +389,9 @@ pub fn interactive_path() -> io::Result { input.parse() } - eprintln!("Welcome to the Rust project! What do you want to do with x.py?"); + println!("Welcome to the Rust project! What do you want to do with x.py?"); for ((letter, _), profile) in abbrev_all() { - eprintln!("{}) {}: {}", letter, profile, profile.purpose()); + println!("{}) {}: {}", letter, profile, profile.purpose()); } let template = loop { print!( @@ -488,7 +488,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result< return Ok(()); } - eprintln!( + println!( "\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality. If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before pushing your code to ensure your code is up to par. If you decide later that this behavior is @@ -496,7 +496,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." ); if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) { - eprintln!("Ok, skipping installation!"); + println!("Ok, skipping installation!"); return Ok(()); } if !hooks_dir.exists() { @@ -513,7 +513,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." ); return Err(e); } - Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), + Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), }; Ok(()) } @@ -654,7 +654,7 @@ impl Step for Editor { if let Some(editor_kind) = editor_kind { while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {} } else { - eprintln!("Ok, skipping editor setup!"); + println!("Ok, skipping editor setup!"); } } Err(e) => eprintln!("Could not determine the editor: {e}"), @@ -687,7 +687,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu mismatched_settings = Some(false); } } - eprintln!( + println!( "\nx.py can automatically install the recommended `{settings_filename}` file for rustc development" ); @@ -706,7 +706,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu Some(PromptResult::Yes) => true, Some(PromptResult::Print) => false, _ => { - eprintln!("Ok, skipping settings!"); + println!("Ok, skipping settings!"); return Ok(true); } }; @@ -733,9 +733,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu _ => "Created", }; fs::write(&settings_path, editor.settings_template())?; - eprintln!("{verb} `{}`", settings_filename); + println!("{verb} `{}`", settings_filename); } else { - eprintln!("\n{}", editor.settings_template()); + println!("\n{}", editor.settings_template()); } Ok(should_create) } diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index 7b2d9fff8f5f0..ba9b1b2fc3317 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) { build.build(); } } else { - eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests"); + println!("HELP: consider using the `--run` flag to automatically run suggested tests"); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 6da37530d963f..161157acffe0e 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -471,11 +471,11 @@ impl Miri { // We re-use the `cargo` from above. cargo.arg("--print-sysroot"); - builder.verbose(|| eprintln!("running: {cargo:?}")); + builder.verbose(|| println!("running: {cargo:?}")); let stdout = cargo.run_capture_stdout(builder).stdout(); // Output is "\n". let sysroot = stdout.trim_end(); - builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); + builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); PathBuf::from(sysroot) } } @@ -2478,7 +2478,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> } } - builder.verbose(|| eprintln!("doc tests for: {}", markdown.display())); + builder.verbose(|| println!("doc tests for: {}", markdown.display())); let mut cmd = builder.rustdoc_cmd(compiler); builder.add_rust_test_threads(&mut cmd); // allow for unstable options such as new editions diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 38abca8b8da17..77f6edaabb248 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -523,7 +523,7 @@ impl Builder<'_> { let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8"); if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) { - eprintln!("using sysroot {sysroot_str}"); + println!("using sysroot {sysroot_str}"); } let mut rustflags = Rustflags::new(target); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index ffe3e053e7247..026c26479d355 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -392,14 +392,14 @@ impl StepDescription { fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) { if !matches!(builder.config.dry_run, DryRun::SelfCheck) { - eprintln!("Skipping {pathset:?} because it is excluded"); + println!("Skipping {pathset:?} because it is excluded"); } return true; } if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) { builder.verbose(|| { - eprintln!( + println!( "{:?} not skipped for {:?} -- not in {:?}", pathset, self.name, builder.config.skip ) @@ -1437,11 +1437,11 @@ impl<'a> Builder<'a> { panic!("{}", out); } if let Some(out) = self.cache.get(&step) { - self.verbose_than(1, || eprintln!("{}c {:?}", " ".repeat(stack.len()), step)); + self.verbose_than(1, || println!("{}c {:?}", " ".repeat(stack.len()), step)); return out; } - self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step)); + self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step)); stack.push(Box::new(step.clone())); } @@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> { let step_string = format!("{step:?}"); let brace_index = step_string.find('{').unwrap_or(0); let type_string = type_name::(); - eprintln!( + println!( "[TIMING] {} {} -- {}.{:03}", &type_string.strip_prefix("bootstrap::").unwrap_or(type_string), &step_string[brace_index..], @@ -1479,9 +1479,7 @@ impl<'a> Builder<'a> { let cur_step = stack.pop().expect("step stack empty"); assert_eq!(cur_step.downcast_ref(), Some(&step)); } - self.verbose_than(1, || { - eprintln!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step) - }); + self.verbose_than(1, || println!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)); self.cache.put(step, out.clone()); out } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index aa5cce2fb1b62..b06147055f2a7 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1293,7 +1293,7 @@ impl Config { .map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids)) { if !changes.is_empty() { - eprintln!( + println!( "WARNING: There have been changes to x.py since you last updated:\n{}", crate::human_readable_changes(&changes) ); @@ -1559,7 +1559,7 @@ impl Config { } if cargo_clippy.is_some() && rustc.is_none() { - eprintln!( + println!( "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict." ); } @@ -1841,7 +1841,7 @@ impl Config { // FIXME: Remove this option at the end of 2024. if parallel_compiler.is_some() { - eprintln!( + println!( "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" ); } @@ -1873,7 +1873,7 @@ impl Config { if available_backends.contains(&backend) { panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'."); } else { - eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ + println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ In this case, it would be referred to as '{backend}'."); } @@ -1902,7 +1902,7 @@ impl Config { // tests may fail due to using a different channel than the one used by the compiler during tests. if let Some(commit) = &config.download_rustc_commit { if is_user_configured_rust_channel { - eprintln!( + println!( "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." ); @@ -1992,10 +1992,10 @@ impl Config { if config.llvm_from_ci { let warn = |option: &str| { - eprintln!( + println!( "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build." ); - eprintln!( + println!( "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false." ); }; @@ -2014,12 +2014,12 @@ impl Config { // if they've chosen a different value. if libzstd.is_some() { - eprintln!( + println!( "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ artifacts builder config." ); - eprintln!( + println!( "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false." ); } @@ -2088,7 +2088,7 @@ impl Config { if available_backends.contains(&backend) { panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'."); } else { - eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ + println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ In this case, it would be referred to as '{backend}'."); } @@ -2304,7 +2304,7 @@ impl Config { if self.dry_run() { return Ok(()); } - self.verbose(|| eprintln!("running: {cmd:?}")); + self.verbose(|| println!("running: {cmd:?}")); build_helper::util::try_run(cmd, self.is_verbose()) } @@ -2479,7 +2479,7 @@ impl Config { // This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error // to not break CI. For non-CI environments, we should return an error. if CiEnv::is_ci() { - eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); + println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); return None; } else { panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used."); @@ -2490,8 +2490,8 @@ impl Config { let ci_config_toml = match self.get_builder_toml("ci-rustc") { Ok(ci_config_toml) => ci_config_toml, Err(e) if e.to_string().contains("unknown field") => { - eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); - eprintln!("HELP: Consider rebasing to a newer commit if available."); + println!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); + println!("HELP: Consider rebasing to a newer commit if available."); return None; }, Err(e) => { @@ -2516,7 +2516,7 @@ impl Config { .is_some_and(|s| s == "1" || s == "true"); if disable_ci_rustc_if_incompatible && res.is_err() { - eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); + println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); return None; } @@ -2701,7 +2701,7 @@ impl Config { return; } - eprintln!("Updating submodule {relative_path}"); + println!("Updating submodule {relative_path}"); self.check_run( helpers::git(Some(&self.src)) .run_always() @@ -2824,7 +2824,7 @@ impl Config { Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::String(s)) if s == "if-unchanged" => { if !self.rust_info.is_managed_git_subrepository() { - eprintln!( + println!( "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." ); crate::exit!(1); @@ -2857,10 +2857,10 @@ impl Config { if if_unchanged { return None; } - eprintln!("ERROR: could not find commit hash for downloading rustc"); - eprintln!("HELP: maybe your repository history is too shallow?"); - eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml"); - eprintln!("HELP: or fetch enough history to include one upstream commit"); + println!("ERROR: could not find commit hash for downloading rustc"); + println!("HELP: maybe your repository history is too shallow?"); + println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); + println!("HELP: or fetch enough history to include one upstream commit"); crate::exit!(1); } }; @@ -2899,7 +2899,7 @@ impl Config { let if_unchanged = || { if self.rust_info.is_from_tarball() { // Git is needed for running "if-unchanged" logic. - eprintln!( + println!( "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`." ); return false; @@ -2948,10 +2948,10 @@ impl Config { // Only commits merged by bors will have CI artifacts. let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap(); if commit.is_empty() { - eprintln!("error: could not find commit hash for downloading components from CI"); - eprintln!("help: maybe your repository history is too shallow?"); - eprintln!("help: consider disabling `{option_name}`"); - eprintln!("help: or fetch enough history to include one upstream commit"); + println!("error: could not find commit hash for downloading components from CI"); + println!("help: maybe your repository history is too shallow?"); + println!("help: consider disabling `{option_name}`"); + println!("help: or fetch enough history to include one upstream commit"); crate::exit!(1); } @@ -2963,14 +2963,14 @@ impl Config { if has_changes { if if_unchanged { if self.is_verbose() { - eprintln!( + println!( "warning: saw changes to one of {modified_paths:?} since {commit}; \ ignoring `{option_name}`" ); } return None; } - eprintln!( + println!( "warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}" ); } @@ -3007,7 +3007,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm( ($current:expr, $expected:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { - eprintln!( + println!( "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \ Current value: {:?}, Expected value(s): {}{:?}", stringify!($expected).replace("_", "-"), @@ -3112,7 +3112,7 @@ fn check_incompatible_options_for_ci_rustc( ($current:expr, $expected:expr, $config_section:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { - eprintln!( + println!( "WARNING: `{}` has no effect with `rust.download-rustc`. \ Current value: {:?}, Expected value(s): {}{:?}", format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")), diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 66b9f5ed84e64..bfeb811508c04 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -196,12 +196,12 @@ impl Flags { if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) = HelpVerboseOnly::try_parse_from(normalize_args(args)) { - eprintln!("NOTE: updating submodules before printing available paths"); + println!("NOTE: updating submodules before printing available paths"); let config = Config::parse(Self::parse(&[String::from("build")])); let build = Build::new(config); let paths = Builder::get_help(&build, subcommand); if let Some(s) = paths { - eprintln!("{s}"); + println!("{s}"); } else { panic!("No paths available for subcommand `{}`", subcommand.as_str()); } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 05b91c518cf4d..db35e6907e661 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -77,7 +77,7 @@ impl Config { if self.dry_run() && !cmd.run_always { return true; } - self.verbose(|| eprintln!("running: {cmd:?}")); + self.verbose(|| println!("running: {cmd:?}")); check_run(cmd, self.is_verbose()) } @@ -144,7 +144,7 @@ impl Config { /// Please see for more information fn fix_bin_or_dylib(&self, fname: &Path) { assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true)); - eprintln!("attempting to patch {}", fname.display()); + println!("attempting to patch {}", fname.display()); // Only build `.nix-deps` once. static NIX_DEPS_DIR: OnceLock = OnceLock::new(); @@ -206,7 +206,7 @@ impl Config { } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { - self.verbose(|| eprintln!("download {url}")); + self.verbose(|| println!("download {url}")); // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. let tempfile = self.tempdir().join(dest_path.file_name().unwrap()); // While bootstrap itself only supports http and https downloads, downstream forks might @@ -226,7 +226,7 @@ impl Config { } fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) { - eprintln!("downloading {url}"); + println!("downloading {url}"); // Try curl. If that fails and we are on windows, fallback to PowerShell. // options should be kept in sync with // src/bootstrap/src/core/download.rs @@ -341,7 +341,7 @@ impl Config { short_path = short_path.strip_prefix(pattern).unwrap_or(short_path); let dst_path = dst.join(short_path); self.verbose(|| { - eprintln!("extracting {} to {}", original_path.display(), dst.display()) + println!("extracting {} to {}", original_path.display(), dst.display()) }); if !t!(member.unpack_in(dst)) { panic!("path traversal attack ??"); @@ -365,7 +365,7 @@ impl Config { pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool { use sha2::Digest; - self.verbose(|| eprintln!("verifying {}", path.display())); + self.verbose(|| println!("verifying {}", path.display())); if self.dry_run() { return false; @@ -391,7 +391,7 @@ impl Config { let verified = checksum == expected; if !verified { - eprintln!( + println!( "invalid checksum: \n\ found: {checksum}\n\ expected: {expected}", @@ -421,7 +421,7 @@ enum DownloadSource { /// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions. impl Config { pub(crate) fn download_clippy(&self) -> PathBuf { - self.verbose(|| eprintln!("downloading stage0 clippy artifacts")); + self.verbose(|| println!("downloading stage0 clippy artifacts")); let date = &self.stage0_metadata.compiler.date; let version = &self.stage0_metadata.compiler.version; @@ -518,7 +518,7 @@ impl Config { } pub(crate) fn download_ci_rustc(&self, commit: &str) { - self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})")); + self.verbose(|| println!("using downloaded stage2 artifacts from CI (commit {commit})")); let version = self.artifact_version_part(commit); // download-rustc doesn't need its own cargo, it can just use beta's. But it does need the @@ -539,7 +539,7 @@ impl Config { #[cfg(not(feature = "bootstrap-self-test"))] pub(crate) fn download_beta_toolchain(&self) { - self.verbose(|| eprintln!("downloading stage0 beta artifacts")); + self.verbose(|| println!("downloading stage0 beta artifacts")); let date = &self.stage0_metadata.compiler.date; let version = &self.stage0_metadata.compiler.version; @@ -677,7 +677,7 @@ impl Config { return; } else { self.verbose(|| { - eprintln!( + println!( "ignoring cached file {} due to failed verification", tarball.display() ) @@ -776,10 +776,10 @@ download-rustc = false t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml)); } Err(e) if e.to_string().contains("unknown field") => { - eprintln!( + println!( "WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled." ); - eprintln!("HELP: Consider rebasing to a newer commit if available."); + println!("HELP: Consider rebasing to a newer commit if available."); } Err(e) => { eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}"); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 71e7f40f0320a..dcf68cbeeda71 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -237,11 +237,11 @@ than building it. stage0_supported_target_list.intersection(&missing_targets_hashset).collect(); if !duplicated_targets.is_empty() { - eprintln!( + println!( "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list." ); for duplicated_target in duplicated_targets { - eprintln!(" {duplicated_target}"); + println!(" {duplicated_target}"); } std::process::exit(1); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 5f778223d7dac..0ecf61ffcd903 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -406,11 +406,11 @@ impl Build { .unwrap() .trim(); if local_release.split('.').take(2).eq(version.split('.').take(2)) { - build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}")); + build.verbose(|| println!("auto-detected local-rebuild {local_release}")); build.local_rebuild = true; } - build.verbose(|| eprintln!("finding compilers")); + build.verbose(|| println!("finding compilers")); utils::cc_detect::find(&build); // When running `setup`, the profile is about to change, so any requirements we have now may // be different on the next invocation. Don't check for them until the next time x.py is @@ -418,7 +418,7 @@ impl Build { // // Similarly, for `setup` we don't actually need submodules or cargo metadata. if !matches!(build.config.cmd, Subcommand::Setup { .. }) { - build.verbose(|| eprintln!("running sanity check")); + build.verbose(|| println!("running sanity check")); crate::core::sanity::check(&mut build); // Make sure we update these before gathering metadata so we don't get an error about missing @@ -436,7 +436,7 @@ impl Build { // Now, update all existing submodules. build.update_existing_submodules(); - build.verbose(|| eprintln!("learning about cargo")); + build.verbose(|| println!("learning about cargo")); crate::core::metadata::build(&mut build); } @@ -605,7 +605,7 @@ impl Build { let stamp = dir.join(".stamp"); let mut cleared = false; if mtime(&stamp) < mtime(input) { - self.verbose(|| eprintln!("Dirty - {}", dir.display())); + self.verbose(|| println!("Dirty - {}", dir.display())); let _ = fs::remove_dir_all(dir); cleared = true; } else if stamp.exists() { @@ -890,7 +890,7 @@ impl Build { let executed_at = std::panic::Location::caller(); self.verbose(|| { - eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})") + println!("running: {command:?} (created at {created_at}, executed at {executed_at})") }); let cmd = command.as_command_mut(); @@ -947,7 +947,7 @@ Executed at: {executed_at}"#, let fail = |message: &str, output: CommandOutput| -> ! { if self.is_verbose() { - eprintln!("{message}"); + println!("{message}"); } else { let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); // If the command captures output, the user would not see any indication that @@ -957,16 +957,16 @@ Executed at: {executed_at}"#, if let Some(stdout) = output.stdout_if_present().take_if(|s| !s.trim().is_empty()) { - eprintln!("STDOUT:\n{stdout}\n"); + println!("STDOUT:\n{stdout}\n"); } if let Some(stderr) = output.stderr_if_present().take_if(|s| !s.trim().is_empty()) { - eprintln!("STDERR:\n{stderr}\n"); + println!("STDERR:\n{stderr}\n"); } - eprintln!("Command {command:?} has failed. Rerun with -v to see more details."); + println!("Command {command:?} has failed. Rerun with -v to see more details."); } else { - eprintln!("Command has failed. Rerun with -v to see more details."); + println!("Command has failed. Rerun with -v to see more details."); } } exit!(1); @@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#, match self.config.dry_run { DryRun::SelfCheck => (), DryRun::Disabled | DryRun::UserSelected => { - eprintln!("{msg}"); + println!("{msg}"); } } } @@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#, if self.config.dry_run() { return; } - self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}")); + self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}")); if src == dst { return; } @@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#, return; } let dst = dstdir.join(src.file_name().unwrap()); - self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}")); + self.verbose_than(1, || println!("Install {src:?} to {dst:?}")); t!(fs::create_dir_all(dstdir)); if !src.exists() { panic!("ERROR: File \"{}\" not found!", src.display()); diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index e8d5b60948aa8..0df0046945220 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) { build.cxx.borrow_mut().insert(target, compiler); } - build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target))); - build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple)); + build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target))); + build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple)); if let Ok(cxx) = build.cxx(target) { let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); - build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple)); - build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); + build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple)); + build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); } if let Some(ar) = ar { - build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple)); + build.verbose(|| println!("AR_{} = {ar:?}", target.triple)); build.ar.borrow_mut().insert(target, ar); } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index c0d52fd343059..923cc2dfc28ce 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -135,7 +135,7 @@ impl Drop for TimeIt { fn drop(&mut self) { let time = self.1.elapsed(); if !self.0 { - eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); + println!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); } } } @@ -267,12 +267,12 @@ pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool { let status = match cmd.as_command_mut().status() { Ok(status) => status, Err(e) => { - eprintln!("failed to execute command: {cmd:?}\nERROR: {e}"); + println!("failed to execute command: {cmd:?}\nERROR: {e}"); return false; } }; if !status.success() && print_cmd_on_fail { - eprintln!( + println!( "\n\ncommand did not execute successfully: {cmd:?}\n\ expected success, got: {status}\n\n" ); diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs index 06d3add6281f8..b51fd490535a3 100644 --- a/src/bootstrap/src/utils/metrics.rs +++ b/src/bootstrap/src/utils/metrics.rs @@ -185,7 +185,7 @@ impl BuildMetrics { if version.format_version == CURRENT_FORMAT_VERSION { t!(serde_json::from_slice::(&contents)).invocations } else { - eprintln!( + println!( "WARNING: overriding existing build/metrics.json, as it's not \ compatible with build metrics format version {CURRENT_FORMAT_VERSION}." ); diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 27e1c5d01b77a..eb2c8254dc0f4 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> let cmd = cmd.as_command_mut(); cmd.stdout(Stdio::piped()); - builder.verbose(|| eprintln!("running: {cmd:?}")); + builder.verbose(|| println!("running: {cmd:?}")); let mut process = cmd.spawn().unwrap(); @@ -71,7 +71,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> let result = process.wait_with_output().unwrap(); if !result.status.success() && builder.is_verbose() { - eprintln!( + println!( "\n\ncommand did not execute successfully: {cmd:?}\n\ expected success, got: {}", result.status @@ -135,9 +135,7 @@ impl<'a> Renderer<'a> { if self.up_to_date_tests > 0 { let n = self.up_to_date_tests; let s = if n > 1 { "s" } else { "" }; - eprintln!( - "help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n" - ); + println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"); } } @@ -192,7 +190,7 @@ impl<'a> Renderer<'a> { if let Some(exec_time) = test.exec_time { print!(" ({exec_time:.2?})"); } - eprintln!(); + println!(); } fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) { @@ -202,7 +200,7 @@ impl<'a> Renderer<'a> { let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len()); print!(" {executed}/{total}"); } - eprintln!(); + println!(); self.terse_tests_in_line = 0; } @@ -214,31 +212,31 @@ impl<'a> Renderer<'a> { fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) { // The terse output doesn't end with a newline, so we need to add it ourselves. if !self.builder.config.verbose_tests { - eprintln!(); + println!(); } if !self.failures.is_empty() { - eprintln!("\nfailures:\n"); + println!("\nfailures:\n"); for failure in &self.failures { if failure.stdout.is_some() || failure.message.is_some() { - eprintln!("---- {} stdout ----", failure.name); + println!("---- {} stdout ----", failure.name); if let Some(stdout) = &failure.stdout { - eprintln!("{stdout}"); + println!("{stdout}"); } if let Some(message) = &failure.message { - eprintln!("NOTE: {message}"); + println!("NOTE: {message}"); } } } - eprintln!("\nfailures:"); + println!("\nfailures:"); for failure in &self.failures { - eprintln!(" {}", failure.name); + println!(" {}", failure.name); } } if !self.benches.is_empty() { - eprintln!("\nbenchmarks:"); + println!("\nbenchmarks:"); let mut rows = Vec::new(); for bench in &self.benches { @@ -253,13 +251,13 @@ impl<'a> Renderer<'a> { let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0); let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0); for row in &rows { - eprintln!(" {:max_1$} {:>max_2$}", row.0, row.1, row.2); + println!(" {:max_1$} {:>max_2$}", row.0, row.1, row.2); } } print!("\ntest result: "); self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap(); - eprintln!( + println!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n", suite.passed, suite.failed, @@ -276,7 +274,7 @@ impl<'a> Renderer<'a> { fn render_message(&mut self, message: Message) { match message { Message::Suite(SuiteMessage::Started { test_count }) => { - eprintln!("\nrunning {test_count} tests"); + println!("\nrunning {test_count} tests"); self.executed_tests = 0; self.terse_tests_in_line = 0; self.tests_count = Some(test_count); @@ -316,7 +314,7 @@ impl<'a> Renderer<'a> { self.failures.push(outcome); } Message::Test(TestMessage::Timeout { name }) => { - eprintln!("test {name} has been running for a long time"); + println!("test {name} has been running for a long time"); } Message::Test(TestMessage::Started) => {} // Not useful } diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index f60498a4872c4..3c6c7a7fa180a 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -344,7 +344,7 @@ impl<'a> Tarball<'a> { // For `x install` tarball files aren't needed, so we can speed up the process by not producing them. let compression_profile = if self.builder.kind == Kind::Install { self.builder.verbose(|| { - eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.") + println!("Forcing dist.compression-profile = 'no-op' for `x install`.") }); // "no-op" indicates that the rust-installer won't produce compressed tarball sources. "no-op" diff --git a/src/doc/book b/src/doc/book index e16dd73690a6c..614c19cb40256 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit e16dd73690a6cc3ecdc5f5d94bbc3ce158a42e16 +Subproject commit 614c19cb4025636eb2ba68ebb3d44e3bd3a5e6e4 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index f48b0e842a391..128669297c8a7 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit f48b0e842a3911c63240e955d042089e9e0894c7 +Subproject commit 128669297c8a7fdf771042eaec18b8adfaeaf0cd diff --git a/src/doc/reference b/src/doc/reference index 5c86c739ec71b..ede56d1bbe132 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 5c86c739ec71b8bc839310ff47fa94e94635bba9 +Subproject commit ede56d1bbe132bac476b5029cd6d7508ca9572e9 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 787b4166ccc67..b21d99b770f9a 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 787b4166ccc67bd8f72a6e3ef6685ce9ce82909a +Subproject commit b21d99b770f9aceb0810c843847c52f86f45d2ed diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index c4a0c8f186510..022ed180ed8ca 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -744,7 +744,6 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::unit_types::LET_UNIT_VALUE_INFO, crate::unit_types::UNIT_ARG_INFO, crate::unit_types::UNIT_CMP_INFO, - crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO, crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO, crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO, crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO, diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index 77dbe9b78a182..3ea792d8b835c 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -74,6 +74,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[ #[clippy::version = "1.53.0"] ("clippy::filter_map", "clippy::manual_filter_map"), #[clippy::version = ""] + ("clippy::fn_address_comparisons", "unpredictable_function_pointer_comparisons"), + #[clippy::version = ""] ("clippy::identity_conversion", "clippy::useless_conversion"), #[clippy::version = "pre 1.29.0"] ("clippy::if_let_redundant_pattern_matching", "clippy::redundant_pattern_matching"), diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index c9064df25ac89..e80cca6e7db4b 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -363,7 +363,6 @@ mod uninhabited_references; mod uninit_vec; mod unit_return_expecting_ord; mod unit_types; -mod unnamed_address; mod unnecessary_box_returns; mod unnecessary_literal_bound; mod unnecessary_map_on_constructor; @@ -786,7 +785,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap)); store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(conf))); store.register_late_pass(|_| Box::::default()); - store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress)); store.register_late_pass(|_| Box::>::default()); store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse)); store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend)); diff --git a/src/tools/clippy/clippy_lints/src/unnamed_address.rs b/src/tools/clippy/clippy_lints/src/unnamed_address.rs deleted file mode 100644 index cd2dacc9f099c..0000000000000 --- a/src/tools/clippy/clippy_lints/src/unnamed_address.rs +++ /dev/null @@ -1,60 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use rustc_hir::{BinOpKind, Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; -use rustc_session::declare_lint_pass; - -declare_clippy_lint! { - /// ### What it does - /// Checks for comparisons with an address of a function item. - /// - /// ### Why is this bad? - /// Function item address is not guaranteed to be unique and could vary - /// between different code generation units. Furthermore different function items could have - /// the same address after being merged together. - /// - /// ### Example - /// ```no_run - /// type F = fn(); - /// fn a() {} - /// let f: F = a; - /// if f == a { - /// // ... - /// } - /// ``` - #[clippy::version = "1.44.0"] - pub FN_ADDRESS_COMPARISONS, - correctness, - "comparison with an address of a function item" -} - -declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS]); - -impl LateLintPass<'_> for UnnamedAddress { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - fn is_comparison(binop: BinOpKind) -> bool { - matches!( - binop, - BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt - ) - } - - fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - matches!(cx.typeck_results().expr_ty(expr).kind(), ty::FnDef(..)) - } - - if let ExprKind::Binary(binop, left, right) = expr.kind - && is_comparison(binop.node) - && cx.typeck_results().expr_ty_adjusted(left).is_fn_ptr() - && cx.typeck_results().expr_ty_adjusted(right).is_fn_ptr() - && (is_fn_def(cx, left) || is_fn_def(cx, right)) - { - span_lint( - cx, - FN_ADDRESS_COMPARISONS, - expr.span, - "comparing with a non-unique address of a function item", - ); - } - } -} diff --git a/src/tools/clippy/tests/ui/fn_address_comparisons.rs b/src/tools/clippy/tests/ui/fn_address_comparisons.rs deleted file mode 100644 index 35535bd4fddd0..0000000000000 --- a/src/tools/clippy/tests/ui/fn_address_comparisons.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::fmt::Debug; -use std::ptr; -use std::rc::Rc; -use std::sync::Arc; - -fn a() {} - -#[warn(clippy::fn_address_comparisons)] -fn main() { - type F = fn(); - let f: F = a; - let g: F = f; - - // These should fail: - let _ = f == a; - //~^ ERROR: comparing with a non-unique address of a function item - //~| NOTE: `-D clippy::fn-address-comparisons` implied by `-D warnings` - let _ = f != a; - //~^ ERROR: comparing with a non-unique address of a function item - - // These should be fine: - let _ = f == g; -} diff --git a/src/tools/clippy/tests/ui/fn_address_comparisons.stderr b/src/tools/clippy/tests/ui/fn_address_comparisons.stderr deleted file mode 100644 index e6de7e358075d..0000000000000 --- a/src/tools/clippy/tests/ui/fn_address_comparisons.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: comparing with a non-unique address of a function item - --> tests/ui/fn_address_comparisons.rs:15:13 - | -LL | let _ = f == a; - | ^^^^^^ - | - = note: `-D clippy::fn-address-comparisons` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::fn_address_comparisons)]` - -error: comparing with a non-unique address of a function item - --> tests/ui/fn_address_comparisons.rs:18:13 - | -LL | let _ = f != a; - | ^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 0d6e07aa546cf..47149622ef7c6 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -59,6 +59,7 @@ #![allow(unknown_lints)] #![allow(unused_labels)] #![allow(ambiguous_wide_pointer_comparisons)] +#![allow(unpredictable_function_pointer_comparisons)] #![allow(clippy::reversed_empty_ranges)] #![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range` #![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name` @@ -74,6 +75,7 @@ #![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence` #![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map` +#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` #![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion` #![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching` #![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result` diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 2ac59718786b6..7a78a5d280ddb 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -59,6 +59,7 @@ #![allow(unknown_lints)] #![allow(unused_labels)] #![allow(ambiguous_wide_pointer_comparisons)] +#![allow(unpredictable_function_pointer_comparisons)] #![allow(clippy::reversed_empty_ranges)] #![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range` #![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name` @@ -74,6 +75,7 @@ #![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence` #![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map` +#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` #![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion` #![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching` #![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result` diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index a5ae727b7ee82..dc24bc16d0ea4 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> tests/ui/rename.rs:63:9 + --> tests/ui/rename.rs:64:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -8,394 +8,400 @@ LL | #![warn(clippy::almost_complete_letter_range)] = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> tests/ui/rename.rs:64:9 + --> tests/ui/rename.rs:65:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions` - --> tests/ui/rename.rs:65:9 + --> tests/ui/rename.rs:66:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions` - --> tests/ui/rename.rs:66:9 + --> tests/ui/rename.rs:67:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions` - --> tests/ui/rename.rs:67:9 + --> tests/ui/rename.rs:68:9 | LL | #![warn(clippy::blocks_in_if_conditions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> tests/ui/rename.rs:68:9 + --> tests/ui/rename.rs:69:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> tests/ui/rename.rs:69:9 + --> tests/ui/rename.rs:70:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> tests/ui/rename.rs:70:9 + --> tests/ui/rename.rs:71:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> tests/ui/rename.rs:71:9 + --> tests/ui/rename.rs:72:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> tests/ui/rename.rs:72:9 + --> tests/ui/rename.rs:73:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> tests/ui/rename.rs:73:9 + --> tests/ui/rename.rs:74:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> tests/ui/rename.rs:74:9 + --> tests/ui/rename.rs:75:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map` - --> tests/ui/rename.rs:75:9 + --> tests/ui/rename.rs:76:9 | LL | #![warn(clippy::find_map)] | ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map` error: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map` - --> tests/ui/rename.rs:76:9 + --> tests/ui/rename.rs:77:9 | LL | #![warn(clippy::filter_map)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map` +error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons` + --> tests/ui/rename.rs:78:9 + | +LL | #![warn(clippy::fn_address_comparisons)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons` + error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> tests/ui/rename.rs:77:9 + --> tests/ui/rename.rs:79:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching` - --> tests/ui/rename.rs:78:9 + --> tests/ui/rename.rs:80:9 | LL | #![warn(clippy::if_let_redundant_pattern_matching)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> tests/ui/rename.rs:79:9 + --> tests/ui/rename.rs:81:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl` - --> tests/ui/rename.rs:80:9 + --> tests/ui/rename.rs:82:9 | LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl` error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl` - --> tests/ui/rename.rs:81:9 + --> tests/ui/rename.rs:83:9 | LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl` error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects` - --> tests/ui/rename.rs:82:9 + --> tests/ui/rename.rs:84:9 | LL | #![warn(clippy::integer_arithmetic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> tests/ui/rename.rs:83:9 + --> tests/ui/rename.rs:85:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> tests/ui/rename.rs:84:9 + --> tests/ui/rename.rs:86:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> tests/ui/rename.rs:85:9 + --> tests/ui/rename.rs:87:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> tests/ui/rename.rs:86:9 + --> tests/ui/rename.rs:88:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:87:9 + --> tests/ui/rename.rs:89:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:88:9 + --> tests/ui/rename.rs:90:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> tests/ui/rename.rs:89:9 + --> tests/ui/rename.rs:91:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks` - --> tests/ui/rename.rs:90:9 + --> tests/ui/rename.rs:92:9 | LL | #![warn(clippy::overflow_check_conditional)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> tests/ui/rename.rs:91:9 + --> tests/ui/rename.rs:93:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> tests/ui/rename.rs:92:9 + --> tests/ui/rename.rs:94:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:93:9 + --> tests/ui/rename.rs:95:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> tests/ui/rename.rs:94:9 + --> tests/ui/rename.rs:96:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> tests/ui/rename.rs:95:9 + --> tests/ui/rename.rs:97:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> tests/ui/rename.rs:96:9 + --> tests/ui/rename.rs:98:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::thread_local_initializer_can_be_made_const` has been renamed to `clippy::missing_const_for_thread_local` - --> tests/ui/rename.rs:97:9 + --> tests/ui/rename.rs:99:9 | LL | #![warn(clippy::thread_local_initializer_can_be_made_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::missing_const_for_thread_local` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> tests/ui/rename.rs:98:9 + --> tests/ui/rename.rs:100:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default` - --> tests/ui/rename.rs:99:9 + --> tests/ui/rename.rs:101:9 | LL | #![warn(clippy::unwrap_or_else_default)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> tests/ui/rename.rs:100:9 + --> tests/ui/rename.rs:102:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting` - --> tests/ui/rename.rs:101:9 + --> tests/ui/rename.rs:103:9 | LL | #![warn(clippy::cast_ref_to_mut)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> tests/ui/rename.rs:102:9 + --> tests/ui/rename.rs:104:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons` - --> tests/ui/rename.rs:103:9 + --> tests/ui/rename.rs:105:9 | LL | #![warn(clippy::cmp_nan)] | ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> tests/ui/rename.rs:104:9 + --> tests/ui/rename.rs:106:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types` - --> tests/ui/rename.rs:105:9 + --> tests/ui/rename.rs:107:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types` error: lint `clippy::drop_ref` has been renamed to `dropping_references` - --> tests/ui/rename.rs:106:9 + --> tests/ui/rename.rs:108:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references` error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks` - --> tests/ui/rename.rs:107:9 + --> tests/ui/rename.rs:109:9 | LL | #![warn(clippy::fn_null_check)] | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:108:9 + --> tests/ui/rename.rs:110:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:109:9 + --> tests/ui/rename.rs:111:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:110:9 + --> tests/ui/rename.rs:112:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types` - --> tests/ui/rename.rs:111:9 + --> tests/ui/rename.rs:113:9 | LL | #![warn(clippy::forget_copy)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types` error: lint `clippy::forget_ref` has been renamed to `forgetting_references` - --> tests/ui/rename.rs:112:9 + --> tests/ui/rename.rs:114:9 | LL | #![warn(clippy::forget_ref)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> tests/ui/rename.rs:113:9 + --> tests/ui/rename.rs:115:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> tests/ui/rename.rs:114:9 + --> tests/ui/rename.rs:116:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> tests/ui/rename.rs:115:9 + --> tests/ui/rename.rs:117:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked` - --> tests/ui/rename.rs:116:9 + --> tests/ui/rename.rs:118:9 | LL | #![warn(clippy::invalid_utf8_in_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> tests/ui/rename.rs:117:9 + --> tests/ui/rename.rs:119:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs` - --> tests/ui/rename.rs:118:9 + --> tests/ui/rename.rs:120:9 | LL | #![warn(clippy::maybe_misused_cfg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> tests/ui/rename.rs:119:9 + --> tests/ui/rename.rs:121:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs` - --> tests/ui/rename.rs:120:9 + --> tests/ui/rename.rs:122:9 | LL | #![warn(clippy::mismatched_target_os)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> tests/ui/rename.rs:121:9 + --> tests/ui/rename.rs:123:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> tests/ui/rename.rs:122:9 + --> tests/ui/rename.rs:124:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` - --> tests/ui/rename.rs:123:9 + --> tests/ui/rename.rs:125:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` - --> tests/ui/rename.rs:124:9 + --> tests/ui/rename.rs:126:9 | LL | #![warn(clippy::undropped_manually_drops)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> tests/ui/rename.rs:125:9 + --> tests/ui/rename.rs:127:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> tests/ui/rename.rs:126:9 + --> tests/ui/rename.rs:128:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons` - --> tests/ui/rename.rs:127:9 + --> tests/ui/rename.rs:129:9 | LL | #![warn(clippy::vtable_address_comparisons)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons` error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges` - --> tests/ui/rename.rs:128:9 + --> tests/ui/rename.rs:130:9 | LL | #![warn(clippy::reverse_range_loop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges` -error: aborting due to 66 previous errors +error: aborting due to 67 previous errors diff --git a/src/tools/compiletest/src/compute_diff.rs b/src/tools/compiletest/src/compute_diff.rs index 3ace6c5b6d717..92c80c27de03b 100644 --- a/src/tools/compiletest/src/compute_diff.rs +++ b/src/tools/compiletest/src/compute_diff.rs @@ -144,7 +144,7 @@ where } if !wrote_data { - eprintln!("note: diff is identical to nightly rustdoc"); + println!("note: diff is identical to nightly rustdoc"); assert!(diff_output.metadata().unwrap().len() == 0); return false; } else if verbose { diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index e75c8a5993e53..b605bc813f195 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -20,7 +20,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option> { } if config.remote_test_client.is_some() && !config.target.contains("android") { - eprintln!( + println!( "WARNING: debuginfo tests are not available when \ testing with remote" ); @@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option> { } if config.target.contains("android") { - eprintln!( + println!( "{} debug-info test uses tcp 5039 port.\ please reserve it", config.target @@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option> { config.lldb_python_dir.as_ref()?; if let Some(350) = config.lldb_version { - eprintln!( + println!( "WARNING: The used version of LLDB (350) has a \ known issue that breaks debuginfo tests. See \ issue #32520 for more information. Skipping all \ diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 447568065f51c..bf4a3124075e0 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -188,8 +188,8 @@ pub fn parse_config(args: Vec) -> Config { let (argv0, args_) = args.split_first().unwrap(); if args.len() == 1 || args[1] == "-h" || args[1] == "--help" { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); - eprintln!("{}", opts.usage(&message)); - eprintln!(); + println!("{}", opts.usage(&message)); + println!(); panic!() } @@ -200,8 +200,8 @@ pub fn parse_config(args: Vec) -> Config { if matches.opt_present("h") || matches.opt_present("help") { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); - eprintln!("{}", opts.usage(&message)); - eprintln!(); + println!("{}", opts.usage(&message)); + println!(); panic!() } @@ -501,7 +501,7 @@ pub fn run_tests(config: Arc) { // easy to miss which tests failed, and as such fail to reproduce // the failure locally. - eprintln!( + println!( "Some tests failed in compiletest suite={}{} mode={} host={} target={}", config.suite, config diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8c747a1d93f61..84269fd44a1e0 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -774,20 +774,20 @@ impl<'test> TestCx<'test> { unexpected.len(), not_found.len() )); - eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); + println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); if !unexpected.is_empty() { - eprintln!("{}", "--- unexpected errors (from JSON output) ---".green()); + println!("{}", "--- unexpected errors (from JSON output) ---".green()); for error in &unexpected { - eprintln!("{}", error.render_for_expected()); + println!("{}", error.render_for_expected()); } - eprintln!("{}", "---".green()); + println!("{}", "---".green()); } if !not_found.is_empty() { - eprintln!("{}", "--- not found errors (from test file) ---".red()); + println!("{}", "--- not found errors (from test file) ---".red()); for error in ¬_found { - eprintln!("{}", error.render_for_expected()); + println!("{}", error.render_for_expected()); } - eprintln!("{}", "---\n".red()); + println!("{}", "---\n".red()); } panic!("errors differ from expected"); } @@ -1876,18 +1876,18 @@ impl<'test> TestCx<'test> { fn maybe_dump_to_stdout(&self, out: &str, err: &str) { if self.config.verbose { - eprintln!("------stdout------------------------------"); - eprintln!("{}", out); - eprintln!("------stderr------------------------------"); - eprintln!("{}", err); - eprintln!("------------------------------------------"); + println!("------stdout------------------------------"); + println!("{}", out); + println!("------stderr------------------------------"); + println!("{}", err); + println!("------------------------------------------"); } } fn error(&self, err: &str) { match self.revision { - Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err), - None => eprintln!("\nerror: {}", err), + Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), + None => println!("\nerror: {}", err), } } @@ -1972,7 +1972,7 @@ impl<'test> TestCx<'test> { if !self.config.has_html_tidy { return; } - eprintln!("info: generating a diff against nightly rustdoc"); + println!("info: generating a diff against nightly rustdoc"); let suffix = self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); @@ -2082,7 +2082,7 @@ impl<'test> TestCx<'test> { .output() .unwrap(); assert!(output.status.success()); - eprintln!("{}", String::from_utf8_lossy(&output.stdout)); + println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); } else { use colored::Colorize; @@ -2482,7 +2482,7 @@ impl<'test> TestCx<'test> { )"# ) .replace_all(&output, |caps: &Captures<'_>| { - eprintln!("{}", &caps[0]); + println!("{}", &caps[0]); caps[0].replace(r"\", "/") }) .replace("\r\n", "\n") @@ -2581,16 +2581,16 @@ impl<'test> TestCx<'test> { if let Err(err) = fs::write(&actual_path, &actual) { self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",)); } - eprintln!("Saved the actual {stream} to {actual_path:?}"); + println!("Saved the actual {stream} to {actual_path:?}"); let expected_path = expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); if !self.config.bless { if expected.is_empty() { - eprintln!("normalized {}:\n{}\n", stream, actual); + println!("normalized {}:\n{}\n", stream, actual); } else { - eprintln!("diff of {stream}:\n"); + println!("diff of {stream}:\n"); if let Some(diff_command) = self.config.diff_command.as_deref() { let mut args = diff_command.split_whitespace(); let name = args.next().unwrap(); @@ -2625,10 +2625,10 @@ impl<'test> TestCx<'test> { if let Err(err) = fs::write(&expected_path, &actual) { self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); } - eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}"); + println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } - eprintln!("\nThe actual {0} differed from the expected {0}.", stream); + println!("\nThe actual {0} differed from the expected {0}.", stream); if self.config.bless { 0 } else { 1 } } @@ -2707,7 +2707,7 @@ impl<'test> TestCx<'test> { fs::create_dir_all(&incremental_dir).unwrap(); if self.config.verbose { - eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display()); + println!("init_incremental_test: incremental_dir={}", incremental_dir.display()); } } @@ -2765,7 +2765,7 @@ impl ProcRes { } } - eprintln!( + println!( "status: {}\ncommand: {}\n{}\n{}\n", self.status, self.cmdline, @@ -2776,7 +2776,7 @@ impl ProcRes { pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! { if let Some(e) = err { - eprintln!("\nerror: {}", e); + println!("\nerror: {}", e); } self.print_info(); on_failure(); diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs index 6acd140183d47..6c866cbef21ab 100644 --- a/src/tools/compiletest/src/runtest/codegen_units.rs +++ b/src/tools/compiletest/src/runtest/codegen_units.rs @@ -64,13 +64,13 @@ impl TestCx<'_> { if !missing.is_empty() { missing.sort(); - eprintln!("\nThese items should have been contained but were not:\n"); + println!("\nThese items should have been contained but were not:\n"); for item in &missing { - eprintln!("{}", item); + println!("{}", item); } - eprintln!("\n"); + println!("\n"); } if !unexpected.is_empty() { @@ -80,24 +80,24 @@ impl TestCx<'_> { sorted }; - eprintln!("\nThese items were contained but should not have been:\n"); + println!("\nThese items were contained but should not have been:\n"); for item in sorted { - eprintln!("{}", item); + println!("{}", item); } - eprintln!("\n"); + println!("\n"); } if !wrong_cgus.is_empty() { wrong_cgus.sort_by_key(|pair| pair.0.name.clone()); - eprintln!("\nThe following items were assigned to wrong codegen units:\n"); + println!("\nThe following items were assigned to wrong codegen units:\n"); for &(ref expected_item, ref actual_item) in &wrong_cgus { - eprintln!("{}", expected_item.name); - eprintln!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); - eprintln!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); - eprintln!(); + println!("{}", expected_item.name); + println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); + println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); + println!(); } } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 7322e730e53f8..c621c22ac993c 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -260,7 +260,7 @@ impl TestCx<'_> { cmdline, }; if adb.kill().is_err() { - eprintln!("Adb process is already finished."); + println!("Adb process is already finished."); } } else { let rust_src_root = @@ -275,7 +275,7 @@ impl TestCx<'_> { match self.config.gdb_version { Some(version) => { - eprintln!("NOTE: compiletest thinks it is using GDB version {}", version); + println!("NOTE: compiletest thinks it is using GDB version {}", version); if version > extract_gdb_version("7.4").unwrap() { // Add the directory containing the pretty printers to @@ -297,7 +297,7 @@ impl TestCx<'_> { } } _ => { - eprintln!( + println!( "NOTE: compiletest does not know which version of \ GDB it is using" ); @@ -392,10 +392,10 @@ impl TestCx<'_> { match self.config.lldb_version { Some(ref version) => { - eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version); + println!("NOTE: compiletest thinks it is using LLDB version {}", version); } _ => { - eprintln!( + println!( "NOTE: compiletest does not know which version of \ LLDB it is using" ); diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 84376d346af34..31fdb0a5d13bd 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -29,7 +29,7 @@ impl TestCx<'_> { if !res.status.success() { self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| { - eprintln!("Rustdoc Output:"); + println!("Rustdoc Output:"); proc_res.print_info(); }) } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index 414f1a6adb33d..bb747c6802926 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -109,10 +109,10 @@ impl TestCx<'_> { } if errors > 0 { - eprintln!("To update references, rerun the tests and pass the `--bless` flag"); + println!("To update references, rerun the tests and pass the `--bless` flag"); let relative_path_to_file = self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap()); - eprintln!( + println!( "To only update this specific test, also pass `--test-args {}`", relative_path_to_file.display(), ); diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 7b50e62c29bb8..bff02f1db9f02 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -30,7 +30,7 @@ fn path_div() -> &'static str { pub fn logv(config: &Config, s: String) { debug!("{}", s); if config.verbose { - eprintln!("{}", s); + println!("{}", s); } } diff --git a/src/tools/miri/tests/pass/function_pointers.rs b/src/tools/miri/tests/pass/function_pointers.rs index a5c4bc5e0d95b..7145be334a13e 100644 --- a/src/tools/miri/tests/pass/function_pointers.rs +++ b/src/tools/miri/tests/pass/function_pointers.rs @@ -1,3 +1,5 @@ +#![allow(unpredictable_function_pointer_comparisons)] + use std::mem; trait Answer { diff --git a/src/tools/miri/tests/pass/issues/issue-91636.rs b/src/tools/miri/tests/pass/issues/issue-91636.rs index 00370165812f5..d0cadcd2c70a9 100644 --- a/src/tools/miri/tests/pass/issues/issue-91636.rs +++ b/src/tools/miri/tests/pass/issues/issue-91636.rs @@ -1,3 +1,5 @@ +#![allow(unpredictable_function_pointer_comparisons)] + type BuiltIn = for<'a> fn(&str); struct Function { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index 266109765ab8c..b97dfb3b8ef8b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -3936,17 +3936,8 @@ The tracking issue for this feature is: [#117693] "##, }, Lint { - label: "core_pattern_type", - description: r##"# `core_pattern_type` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "core_pattern_types", - description: r##"# `core_pattern_types` + label: "pattern_type_macro", + description: r##"# `pattern_type_macro` This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 9dc49b57d599a..e2d1b85797ffe 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -38,7 +38,7 @@ const IGNORE_UI_TEST_CHECK: &[&str] = macro_rules! verbose_print { ($verbose:expr, $($fmt:tt)*) => { if $verbose { - eprintln!("{}", format_args!($($fmt)*)); + println!("{}", format_args!($($fmt)*)); } }; } @@ -49,8 +49,8 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut // Stage 1: create list let error_codes = extract_error_codes(root_path, &mut errors); if verbose { - eprintln!("Found {} error codes", error_codes.len()); - eprintln!("Highest error code: `{}`", error_codes.iter().max().unwrap()); + println!("Found {} error codes", error_codes.len()); + println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); } // Stage 2: check list has docs diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 4607d04157704..4f24eb2124207 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -158,14 +158,14 @@ pub fn check( .collect::>(); for &(name, _) in gate_untested.iter() { - eprintln!("Expected a gate test for the feature '{name}'."); - eprintln!( + println!("Expected a gate test for the feature '{name}'."); + println!( "Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\ \n with its failures due to missing usage of `#![feature({})]`.", name.replace("_", "-"), name ); - eprintln!( + println!( "Hint: If you already have such a test and don't want to rename it,\ \n you can also add a // gate-test-{} line to the test file.", name @@ -218,7 +218,7 @@ pub fn check( lines.sort(); for line in lines { - eprintln!("* {line}"); + println!("* {line}"); } } diff --git a/src/tools/tidy/src/fluent_period.rs b/src/tools/tidy/src/fluent_period.rs index 8bc404dc8581a..6a136e5aec698 100644 --- a/src/tools/tidy/src/fluent_period.rs +++ b/src/tools/tidy/src/fluent_period.rs @@ -18,7 +18,6 @@ const ALLOWLIST: &[&str] = &[ "const_eval_validation_failure_note", "driver_impl_ice", "incremental_corrupt_file", - "mir_build_pointer_pattern", ]; fn check_period(filename: &str, contents: &str, bad: &mut bool) { diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index 06d238ef5e476..8be25b98df0df 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -118,16 +118,16 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) { // List unstable features that don't have Unstable Book sections. // Remove the comment marker if you want the list printed. /* - eprintln!("Lib features without unstable book sections:"); + println!("Lib features without unstable book sections:"); for feature_name in &unstable_lang_feature_names - &unstable_book_lang_features_section_file_names { - eprintln!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue); + println!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue); } - eprintln!("Lang features without unstable book sections:"); + println!("Lang features without unstable book sections:"); for feature_name in &unstable_lib_feature_names- &unstable_book_lib_features_section_file_names { - eprintln!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue); + println!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue); } // */ } diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index b43d56202c998..489343561e180 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -42,7 +42,7 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { if let Some(expected) = get_x_wrapper_version(root, cargo) { if installed < expected { - return eprintln!( + return println!( "Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" ); } diff --git a/tests/codegen/pattern_type_symbols.rs b/tests/codegen/pattern_type_symbols.rs index a99b3efca415b..b504a3508f94c 100644 --- a/tests/codegen/pattern_type_symbols.rs +++ b/tests/codegen/pattern_type_symbols.rs @@ -4,8 +4,7 @@ //@ compile-flags: -Csymbol-mangling-version=v0 -Copt-level=0 --crate-type=lib #![feature(pattern_types)] -#![feature(core_pattern_types)] -#![feature(core_pattern_type)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs index b5798adc71c86..e6c80a7e54e85 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs @@ -18,17 +18,17 @@ impl Foo for Def { pub fn test(arg: EFoo) { match arg { A::X => println!("A::X"), - //~^ error: constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters B::X => println!("B::X"), - //~^ error: constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters _ => (), } } pub fn test_let_pat(arg: EFoo, A::X: EFoo) { - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters let A::X = arg; - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } fn main() { diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr index adc8f3992072d..a8256f775a68c 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr @@ -1,26 +1,57 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:20:9 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... +LL | pub fn test(arg: EFoo) { + | - constant depends on this generic parameter +LL | match arg { LL | A::X => println!("A::X"), - | ^^^^ + | ^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:22:9 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... +LL | pub fn test(arg: EFoo) { + | - constant depends on this generic parameter +... LL | B::X => println!("B::X"), - | ^^^^ + | ^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:30:9 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... +LL | pub fn test_let_pat(arg: EFoo, A::X: EFoo) { + | - constant depends on this generic parameter +LL | LL | let A::X = arg; - | ^^^^ + | ^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:28:48 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... LL | pub fn test_let_pat(arg: EFoo, A::X: EFoo) { - | ^^^^ + | - ^^^^ `const` depends on a generic parameter + | | + | constant depends on this generic parameter error: aborting due to 4 previous errors diff --git a/tests/ui/binding/const-param.rs b/tests/ui/binding/const-param.rs index 2d051808fe0be..98bc90f508ab2 100644 --- a/tests/ui/binding/const-param.rs +++ b/tests/ui/binding/const-param.rs @@ -2,7 +2,7 @@ fn check() { match 1 { - N => {} //~ ERROR const parameters cannot be referenced in patterns + N => {} //~ ERROR constant parameters cannot be referenced in patterns _ => {} } } diff --git a/tests/ui/binding/const-param.stderr b/tests/ui/binding/const-param.stderr index e68893a59e499..b0b8108945c98 100644 --- a/tests/ui/binding/const-param.stderr +++ b/tests/ui/binding/const-param.stderr @@ -1,8 +1,11 @@ -error[E0158]: const parameters cannot be referenced in patterns +error[E0158]: constant parameters cannot be referenced in patterns --> $DIR/const-param.rs:5:9 | +LL | fn check() { + | -------------- constant defined here +LL | match 1 { LL | N => {} - | ^ + | ^ can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/binop/binary-op-on-fn-ptr-eq.rs b/tests/ui/binop/binary-op-on-fn-ptr-eq.rs index a5ec63587f96e..47b79f3855f60 100644 --- a/tests/ui/binop/binary-op-on-fn-ptr-eq.rs +++ b/tests/ui/binop/binary-op-on-fn-ptr-eq.rs @@ -1,6 +1,9 @@ //@ run-pass // Tests equality between supertype and subtype of a function // See the issue #91636 + +#![allow(unpredictable_function_pointer_comparisons)] + fn foo(_a: &str) {} fn main() { diff --git a/tests/ui/box/unit/unique-ffi-symbols.rs b/tests/ui/box/unit/unique-ffi-symbols.rs index 65a9a32b2bb0c..75877f8397efe 100644 --- a/tests/ui/box/unit/unique-ffi-symbols.rs +++ b/tests/ui/box/unit/unique-ffi-symbols.rs @@ -1,6 +1,9 @@ //@ run-pass // We used to have a __rust_abi shim that resulted in duplicated symbols // whenever the item path wasn't enough to disambiguate between them. + +#![allow(unpredictable_function_pointer_comparisons)] + fn main() { let a = { extern "C" fn good() -> i32 { return 0; } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index 09f7e2ba5b1dd..270496d45a6b0 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -12,8 +12,7 @@ impl Opcode2 { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { move |i| match msg_type { - Opcode2::OP2 => unimplemented!(), - //~^ ERROR: could not evaluate constant pattern + Opcode2::OP2 => unimplemented!(), // ok, `const` already emitted an error } } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9442eac0cf54a..d95a8861230e0 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -17,13 +17,7 @@ help: you might be missing a type parameter LL | pub struct Opcode2(&'a S); | +++ -error: could not evaluate constant pattern - --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9 - | -LL | Opcode2::OP2 => unimplemented!(), - | ^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.rs b/tests/ui/consts/const-eval/const-eval-overflow-2.rs index c19a0c443ec58..bae8a7ce243e9 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-2.rs +++ b/tests/ui/consts/const-eval/const-eval-overflow-2.rs @@ -12,8 +12,7 @@ const NEG_NEG_128: i8 = -NEG_128; //~ ERROR constant fn main() { match -128i8 { - NEG_NEG_128 => println!("A"), - //~^ ERROR could not evaluate constant pattern + NEG_NEG_128 => println!("A"), // ok, `const` error already emitted _ => println!("B"), } } diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr index fc0baf11051b7..5599ff931e8e5 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr @@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed LL | const NEG_NEG_128: i8 = -NEG_128; | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow -error: could not evaluate constant pattern - --> $DIR/const-eval-overflow-2.rs:15:9 - | -LL | NEG_NEG_128 => println!("A"), - | ^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr index 8175fe6016ab8..18935626af1ca 100644 --- a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr +++ b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr @@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error: could not evaluate constant pattern - --> $DIR/ref_to_int_match.rs:7:14 - | -LL | 10..=BAR => {}, - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr index 8175fe6016ab8..18935626af1ca 100644 --- a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr +++ b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr @@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error: could not evaluate constant pattern - --> $DIR/ref_to_int_match.rs:7:14 - | -LL | 10..=BAR => {}, - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ref_to_int_match.rs b/tests/ui/consts/const-eval/ref_to_int_match.rs index c627ad97bb05b..be9420e0215d1 100644 --- a/tests/ui/consts/const-eval/ref_to_int_match.rs +++ b/tests/ui/consts/const-eval/ref_to_int_match.rs @@ -4,7 +4,7 @@ fn main() { let n: Int = 40; match n { 0..=10 => {}, - 10..=BAR => {}, //~ ERROR could not evaluate constant pattern + 10..=BAR => {}, // ok, `const` error already emitted _ => {}, } } diff --git a/tests/ui/consts/const-extern-function.rs b/tests/ui/consts/const-extern-function.rs index acc438189cb86..7629d63266acd 100644 --- a/tests/ui/consts/const-extern-function.rs +++ b/tests/ui/consts/const-extern-function.rs @@ -1,5 +1,7 @@ //@ run-pass + #![allow(non_upper_case_globals)] +#![allow(unpredictable_function_pointer_comparisons)] extern "C" fn foopy() {} diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs index 163a47f433369..f02e780f30e38 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs @@ -9,15 +9,13 @@ fn main() { let _ = Defaulted; match None { consts::SOME => panic!(), - //~^ must be annotated with `#[derive(PartialEq)]` - + //~^ ERROR constant of non-structural type `CustomEq` in a pattern _ => {} } match None { ::SOME => panic!(), - //~^ must be annotated with `#[derive(PartialEq)]` - + //~^ ERROR constant of non-structural type `CustomEq` in a pattern _ => {} } } diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr index e0f97a9abd210..7cada8836450e 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr @@ -1,19 +1,33 @@ -error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `CustomEq` in a pattern --> $DIR/cross-crate-fail.rs:11:9 | LL | consts::SOME => panic!(), - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ constant of non-structural type + | + ::: $DIR/auxiliary/consts.rs:1:1 + | +LL | pub struct CustomEq; + | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | pub const SOME: Option = Some(CustomEq); + | -------------------------------- constant defined here | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cross-crate-fail.rs:18:9 +error: constant of non-structural type `CustomEq` in a pattern + --> $DIR/cross-crate-fail.rs:17:9 | LL | ::SOME => panic!(), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type + | + ::: $DIR/auxiliary/consts.rs:1:1 + | +LL | pub struct CustomEq; + | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const SOME: Option = Some(CustomEq); + | ---------------------------- constant defined here | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr index aa208341c131d..0453a88e43db9 100644 --- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr +++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr @@ -1,26 +1,46 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9 | +LL | const C: *const u8 = &0; + | ------------------ constant defined here +... LL | C => {} - | ^ + | ^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9 | +LL | const C_INNER: (*const u8, u8) = (C, 0); + | ------------------------------ constant defined here +... LL | C_INNER => {} - | ^^^^^^^ + | ^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9 | +LL | const D: *const [u8; 4] = b"abcd"; + | ----------------------- constant defined here +... LL | D => {} - | ^ + | ^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9 | +LL | const STR: *const str = "abcd"; + | --------------------- constant defined here +... LL | STR => {} - | ^^^ + | ^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 4 previous errors diff --git a/tests/ui/consts/const_in_pattern/issue-44333.stderr b/tests/ui/consts/const_in_pattern/issue-44333.stderr index d377bfd95f9cd..61b45377c7610 100644 --- a/tests/ui/consts/const_in_pattern/issue-44333.stderr +++ b/tests/ui/consts/const_in_pattern/issue-44333.stderr @@ -1,14 +1,24 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-44333.rs:15:9 | +LL | const FOO: Func = foo; + | --------------- constant defined here +... LL | FOO => println!("foo"), - | ^^^ + | ^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-44333.rs:16:9 | +LL | const BAR: Func = bar; + | --------------- constant defined here +... LL | BAR => println!("bar"), - | ^^^ + | ^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_in_pattern/issue-65466.rs b/tests/ui/consts/const_in_pattern/issue-65466.rs index 62efce648761a..82838657b02f5 100644 --- a/tests/ui/consts/const_in_pattern/issue-65466.rs +++ b/tests/ui/consts/const_in_pattern/issue-65466.rs @@ -11,7 +11,7 @@ const C: &[O] = &[O::None]; fn main() { let x = O::None; match &[x][..] { - C => (), //~ERROR: the type must implement `PartialEq` + C => (), //~ ERROR constant of non-structural type `&[O]` in a pattern _ => (), } } diff --git a/tests/ui/consts/const_in_pattern/issue-65466.stderr b/tests/ui/consts/const_in_pattern/issue-65466.stderr index 7d5e5b5b0c64a..511a38bbc00d8 100644 --- a/tests/ui/consts/const_in_pattern/issue-65466.stderr +++ b/tests/ui/consts/const_in_pattern/issue-65466.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `&[O]` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `&[O]` in a pattern --> $DIR/issue-65466.rs:14:9 | +LL | struct B; + | -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: &[O] = &[O::None]; + | ---------------- constant defined here +... LL | C => (), - | ^ + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs index cf013c1a79061..91ef5ac53295b 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs @@ -16,8 +16,7 @@ const BAR_BAZ: Foo = if 42 == 42 { fn main() { match Foo::Qux(NoEq) { - BAR_BAZ => panic!(), - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + BAR_BAZ => panic!(), //~ ERROR constant of non-structural type `Foo` in a pattern _ => {} } } diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr index 7766c6ce683d2..154c94c6d3854 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `Foo` in a pattern --> $DIR/no-eq-branch-fail.rs:19:9 | +LL | enum Foo { + | -------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const BAR_BAZ: Foo = if 42 == 42 { + | ------------------ constant defined here +... LL | BAR_BAZ => panic!(), - | ^^^^^^^ + | ^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs index 645e141891243..e555ecfeb8f1f 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs @@ -26,7 +26,7 @@ fn main() { match None { NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), - //~^ ERROR must implement `PartialEq` + //~^ ERROR constant of non-structural type `Option` in a pattern _ => panic!("whoops"), } } diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr index ed531a1fead8d..43894f0088621 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `Option` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `Option` in a pattern --> $DIR/reject_non_partial_eq.rs:28:9 | +LL | struct NoPartialEq(u32); + | ------------------ must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const NO_PARTIAL_EQ_NONE: Option = None; + | --------------------------------------------- constant defined here +... LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index e3dcecec960a7..39e5f732a8985 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -17,9 +17,29 @@ struct NoPartialEq; #[derive(Copy, Clone, Debug)] struct NoDerive; +//~^ NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` // This impl makes `NoDerive` irreflexive. impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } +//~^ NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details impl Eq for NoDerive { } @@ -36,65 +56,55 @@ fn main() { #[derive(PartialEq, Eq, Debug)] enum Derive { Some(X), None, } - const ENUM: Derive = Derive::Some(NoDerive); + const ENUM: Derive = Derive::Some(NoDerive); //~ NOTE constant defined here match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const FIELD: OND = TrivialEq(Some(NoDerive)).0; + const FIELD: OND = TrivialEq(Some(NoDerive)).0; //~ NOTE constant defined here match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type const NO_DERIVE_SOME: OND = Some(NoDerive); - const INDIRECT: OND = NO_DERIVE_SOME; + const INDIRECT: OND = NO_DERIVE_SOME; //~ NOTE constant defined here match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const TUPLE: (OND, OND) = (None, Some(NoDerive)); + const TUPLE: (OND, OND) = (None, Some(NoDerive)); //~ NOTE constant defined here match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); + const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); //~ NOTE constant defined here match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const ARRAY: [OND; 2] = [None, Some(NoDerive)]; + const ARRAY: [OND; 2] = [None, Some(NoDerive)]; //~ NOTE constant defined here match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const REPEAT: [OND; 2] = [Some(NoDerive); 2]; + const REPEAT: [OND; 2] = [Some(NoDerive); 2]; //~ NOTE constant defined here match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - trait Trait: Sized { const ASSOC: Option; } + trait Trait: Sized { const ASSOC: Option; } //~ NOTE constant defined here impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const BLOCK: OND = { NoDerive; Some(NoDerive) }; + const BLOCK: OND = { NoDerive; Some(NoDerive) }; //~ NOTE constant defined here match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const ADDR_OF: &OND = &Some(NoDerive); + const ADDR_OF: &OND = &Some(NoDerive); //~ NOTE constant defined here match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index c068db42e4d90..fa16d0b06a7fe 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -1,92 +1,173 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:40:36 - | +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:60:36 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const ENUM: Derive = Derive::Some(NoDerive); + | ---------------------------- constant defined here LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; - | ^^^^ + | ^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:46:28 +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:65:28 | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const FIELD: OND = TrivialEq(Some(NoDerive)).0; + | ---------------- constant defined here LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:53:27 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:71:27 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const INDIRECT: OND = NO_DERIVE_SOME; + | ------------------- constant defined here LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; - | ^^^^^^^^ + | ^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:59:36 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:76:36 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const TUPLE: (OND, OND) = (None, Some(NoDerive)); + | ----------------------- constant defined here LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:65:28 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:81:28 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); + | -------------------------- constant defined here LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:71:36 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:86:36 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const ARRAY: [OND; 2] = [None, Some(NoDerive)]; + | --------------------- constant defined here LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:77:33 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:91:33 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const REPEAT: [OND; 2] = [Some(NoDerive); 2]; + | ---------------------- constant defined here LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; - | ^^^^^^ + | ^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:84:28 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:97:28 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | trait Trait: Sized { const ASSOC: Option; } + | ------------------ ------------------------- constant defined here +LL | impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:90:28 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:102:28 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const BLOCK: OND = { NoDerive; Some(NoDerive) }; + | ---------------- constant defined here LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:96:29 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:107:29 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const ADDR_OF: &OND = &Some(NoDerive); + | ------------------- constant defined here LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - | ^^^^^^^ + | ^^^^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 10 previous errors diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index a160862a0fa69..aa101cf9d8a62 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -11,7 +11,7 @@ fn invalid() { // This must be rejected here (or earlier), since it's not a valid `&bool`. match &true { - C => {} //~ERROR: could not evaluate constant pattern + C => {} // ok, `const` already emitted an error _ => {} } } @@ -27,7 +27,7 @@ fn extern_() { // This must be rejected here (or earlier), since the pattern cannot be read. match &0 { - C => {} //~ERROR: could not evaluate constant pattern + C => {} // ok, `const` already emitted an error _ => {} } } @@ -42,7 +42,7 @@ fn mutable() { // This *must not build*, the constant we are matching against // could change its value! match &42 { - C => {} //~ERROR: could not evaluate constant pattern + C => {} // ok, `const` already emitted an error _ => {} } } diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index 0153f501174b2..c9d5cb60bf779 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -31,24 +31,6 @@ LL | const C: &i32 = unsafe { &S_MUT }; HEX_DUMP } -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:14:9 - | -LL | C => {} - | ^ - -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:30:9 - | -LL | C => {} - | ^ - -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:45:9 - | -LL | C => {} - | ^ - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr index 2e48837bdcdcb..b22f99f40d351 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr @@ -11,7 +11,7 @@ error: could not evaluate constant pattern --> $DIR/invalid-inline-const-in-match-arm.rs:5:9 | LL | const { (|| {})() } => {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ could not evaluate constant error: aborting due to 2 previous errors diff --git a/tests/ui/consts/issue-43105.rs b/tests/ui/consts/issue-43105.rs index 20b78d64209e1..a4ee34c0532f3 100644 --- a/tests/ui/consts/issue-43105.rs +++ b/tests/ui/consts/issue-43105.rs @@ -5,8 +5,7 @@ const NUM: u8 = xyz(); fn main() { match 1 { - NUM => unimplemented!(), - //~^ ERROR could not evaluate constant pattern + NUM => unimplemented!(), // ok, the `const` already emitted an error _ => unimplemented!(), } } diff --git a/tests/ui/consts/issue-43105.stderr b/tests/ui/consts/issue-43105.stderr index 856a8f0dab6c0..0e08feb58de9b 100644 --- a/tests/ui/consts/issue-43105.stderr +++ b/tests/ui/consts/issue-43105.stderr @@ -6,12 +6,6 @@ LL | const NUM: u8 = xyz(); | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error: could not evaluate constant pattern - --> $DIR/issue-43105.rs:8:9 - | -LL | NUM => unimplemented!(), - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-73976-polymorphic.rs b/tests/ui/consts/issue-73976-polymorphic.rs index 2c576d1f9ef08..98b4005792dbc 100644 --- a/tests/ui/consts/issue-73976-polymorphic.rs +++ b/tests/ui/consts/issue-73976-polymorphic.rs @@ -18,7 +18,7 @@ impl GetTypeId { const fn check_type_id() -> bool { matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } pub struct GetTypeNameLen(T); @@ -29,7 +29,7 @@ impl GetTypeNameLen { const fn check_type_name_len() -> bool { matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } fn main() { diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr index 8a44eb9854fef..ec9512a261632 100644 --- a/tests/ui/consts/issue-73976-polymorphic.stderr +++ b/tests/ui/consts/issue-73976-polymorphic.stderr @@ -1,14 +1,28 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/issue-73976-polymorphic.rs:20:37 | +LL | impl GetTypeId { + | ----------------------------- +LL | pub const VALUE: TypeId = TypeId::of::(); + | ----------------------- constant defined here +... +LL | const fn check_type_id() -> bool { + | - constant depends on this generic parameter LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/issue-73976-polymorphic.rs:31:42 | +LL | impl GetTypeNameLen { + | ---------------------------------- +LL | pub const VALUE: usize = any::type_name::().len(); + | ---------------------- constant defined here +... +LL | const fn check_type_name_len() -> bool { + | - constant depends on this generic parameter LL | matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter error: aborting due to 2 previous errors diff --git a/tests/ui/consts/issue-78655.rs b/tests/ui/consts/issue-78655.rs index cd95ee32c60d2..b0f862e84181a 100644 --- a/tests/ui/consts/issue-78655.rs +++ b/tests/ui/consts/issue-78655.rs @@ -4,6 +4,5 @@ const FOO: *const u32 = { }; fn main() { - let FOO = FOO; - //~^ ERROR could not evaluate constant pattern + let FOO = FOO; // ok, the `const` already emitted an error } diff --git a/tests/ui/consts/issue-78655.stderr b/tests/ui/consts/issue-78655.stderr index ccaed03b4c1df..6a93c1a8cec91 100644 --- a/tests/ui/consts/issue-78655.stderr +++ b/tests/ui/consts/issue-78655.stderr @@ -11,12 +11,6 @@ help: consider assigning a value LL | let x = 42; | ++++ -error: could not evaluate constant pattern - --> $DIR/issue-78655.rs:7:9 - | -LL | let FOO = FOO; - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/consts/issue-79137-toogeneric.rs b/tests/ui/consts/issue-79137-toogeneric.rs index a80c9f48d7bc9..43e06f3d6766b 100644 --- a/tests/ui/consts/issue-79137-toogeneric.rs +++ b/tests/ui/consts/issue-79137-toogeneric.rs @@ -10,7 +10,7 @@ impl GetVariantCount { const fn check_variant_count() -> bool { matches!(GetVariantCount::::VALUE, GetVariantCount::::VALUE) - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } fn main() { diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr index de81512ec6d2c..33e32a7d15dca 100644 --- a/tests/ui/consts/issue-79137-toogeneric.stderr +++ b/tests/ui/consts/issue-79137-toogeneric.stderr @@ -1,8 +1,15 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/issue-79137-toogeneric.rs:12:43 | +LL | impl GetVariantCount { + | -------------------------- +LL | pub const VALUE: usize = std::mem::variant_count::(); + | ---------------------- constant defined here +... +LL | const fn check_variant_count() -> bool { + | - constant depends on this generic parameter LL | matches!(GetVariantCount::::VALUE, GetVariantCount::::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-87046.stderr b/tests/ui/consts/issue-87046.stderr index 0f965e1ac3f1b..36e2564fae6b0 100644 --- a/tests/ui/consts/issue-87046.stderr +++ b/tests/ui/consts/issue-87046.stderr @@ -1,6 +1,9 @@ error: cannot use unsized non-slice type `Username` in constant patterns --> $DIR/issue-87046.rs:28:13 | +LL | pub const ROOT_USER: &Username = Username::from_str("root"); + | ------------------------------ constant defined here +... LL | ROOT_USER => true, | ^^^^^^^^^ diff --git a/tests/ui/consts/issue-89088.rs b/tests/ui/consts/issue-89088.rs index 02a786e746513..f6dbf8f012502 100644 --- a/tests/ui/consts/issue-89088.rs +++ b/tests/ui/consts/issue-89088.rs @@ -13,7 +13,7 @@ fn main() { let var = A::Field(Cow::Borrowed("bar")); match &var { - FOO => todo!(), //~ERROR derive(PartialEq) + FOO => todo!(), //~ ERROR constant of non-structural type `Cow<'_, str>` in a pattern _ => todo!() } } diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr index 362c63a2a4569..56025e0d9b288 100644 --- a/tests/ui/consts/issue-89088.stderr +++ b/tests/ui/consts/issue-89088.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `Cow<'_, str>` in a pattern --> $DIR/issue-89088.rs:16:9 | +LL | const FOO: &A = &A::Field(Cow::Borrowed("foo")); + | ------------- constant defined here +... LL | FOO => todo!(), - | ^^^ + | ^^^ constant of non-structural type + --> $SRC_DIR/alloc/src/borrow.rs:LL:COL + | + = note: `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/match_ice.rs b/tests/ui/consts/match_ice.rs index ed1fd78809b12..477a2de09a46f 100644 --- a/tests/ui/consts/match_ice.rs +++ b/tests/ui/consts/match_ice.rs @@ -8,8 +8,7 @@ struct T; fn main() { const C: &S = &S; match C { - C => {} - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + C => {} //~ ERROR constant of non-structural type `S` in a pattern } const K: &T = &T; match K { diff --git a/tests/ui/consts/match_ice.stderr b/tests/ui/consts/match_ice.stderr index 472c24a5cbe31..95e96bbbd677d 100644 --- a/tests/ui/consts/match_ice.stderr +++ b/tests/ui/consts/match_ice.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `S` in a pattern --> $DIR/match_ice.rs:11:9 | +LL | struct S; + | -------- `S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: &S = &S; + | ----------- constant defined here +LL | match C { LL | C => {} - | ^ + | ^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index a6d75658c7580..facb21a04ef0b 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -37,16 +37,14 @@ const U8_MUT3: &u8 = { pub fn test(x: &[u8; 1]) -> bool { match x { - SLICE_MUT => true, - //~^ ERROR could not evaluate constant pattern + SLICE_MUT => true, // ok, `const` error already emitted &[1..] => false, } } pub fn test2(x: &u8) -> bool { match x { - U8_MUT => true, - //~^ ERROR could not evaluate constant pattern + U8_MUT => true, // ok, `const` error already emitted &(1..) => false, } } @@ -55,15 +53,13 @@ pub fn test2(x: &u8) -> bool { // the errors above otherwise stop compilation too early? pub fn test3(x: &u8) -> bool { match x { - U8_MUT2 => true, - //~^ ERROR could not evaluate constant pattern + U8_MUT2 => true, // ok, `const` error already emitted &(1..) => false, } } pub fn test4(x: &u8) -> bool { match x { - U8_MUT3 => true, - //~^ ERROR could not evaluate constant pattern + U8_MUT3 => true, // ok, `const` error already emitted &(1..) => false, } } diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index 147d3f238f777..8f8271cce38e9 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -37,30 +37,6 @@ error[E0080]: evaluation of constant value failed LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:40:9 - | -LL | SLICE_MUT => true, - | ^^^^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:48:9 - | -LL | U8_MUT => true, - | ^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:58:9 - | -LL | U8_MUT2 => true, - | ^^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:65:9 - | -LL | U8_MUT3 => true, - | ^^^^^^^ - -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/missing_assoc_const_type.rs b/tests/ui/consts/missing_assoc_const_type.rs index 633998e9bc157..61042bfa96d08 100644 --- a/tests/ui/consts/missing_assoc_const_type.rs +++ b/tests/ui/consts/missing_assoc_const_type.rs @@ -9,14 +9,13 @@ trait Range { struct TwoDigits; impl Range for TwoDigits { - const FIRST: = 10; - //~^ ERROR: missing type for `const` item + const FIRST: = 10; //~ ERROR missing type for `const` item const LAST: u8 = 99; } const fn digits(x: u8) -> usize { match x { - TwoDigits::FIRST..=TwoDigits::LAST => 0, //~ ERROR: could not evaluate constant pattern + TwoDigits::FIRST..=TwoDigits::LAST => 0, // ok, `const` error already emitted 0..=9 | 100..=255 => panic!(), } } diff --git a/tests/ui/consts/missing_assoc_const_type.stderr b/tests/ui/consts/missing_assoc_const_type.stderr index ef7ff962d2d12..28af1f0f321e6 100644 --- a/tests/ui/consts/missing_assoc_const_type.stderr +++ b/tests/ui/consts/missing_assoc_const_type.stderr @@ -4,11 +4,5 @@ error: missing type for `const` item LL | const FIRST: = 10; | ^ help: provide a type for the associated constant: `u8` -error: could not evaluate constant pattern - --> $DIR/missing_assoc_const_type.rs:19:9 - | -LL | TwoDigits::FIRST..=TwoDigits::LAST => 0, - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs index 44eac5b16cc0b..ffb143da2d48b 100644 --- a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs +++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs @@ -5,7 +5,7 @@ fn main() { match &b""[..] { - ZST => {} //~ ERROR: could not evaluate constant pattern + ZST => {} // ok, `const` error already emitted } } diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr index e0d658db99760..6bc7e7203aa74 100644 --- a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr +++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr @@ -7,12 +7,6 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; = note: source type: `usize` (word size) = note: target type: `&[u8]` (2 * word size) -error: could not evaluate constant pattern - --> $DIR/transmute-size-mismatch-before-typeck.rs:8:9 - | -LL | ZST => {} - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/cross-crate/const-cross-crate-extern.rs b/tests/ui/cross-crate/const-cross-crate-extern.rs index 8d48a6a520606..0ec8753c30f2f 100644 --- a/tests/ui/cross-crate/const-cross-crate-extern.rs +++ b/tests/ui/cross-crate/const-cross-crate-extern.rs @@ -1,6 +1,8 @@ //@ run-pass //@ aux-build:cci_const.rs + #![allow(non_upper_case_globals)] +#![allow(unpredictable_function_pointer_comparisons)] extern crate cci_const; use cci_const::bar; diff --git a/tests/ui/extern/extern-compare-with-return-type.rs b/tests/ui/extern/extern-compare-with-return-type.rs index 316e8b2fc7360..7d1027d5e776f 100644 --- a/tests/ui/extern/extern-compare-with-return-type.rs +++ b/tests/ui/extern/extern-compare-with-return-type.rs @@ -2,6 +2,7 @@ // Tests that we can compare various kinds of extern fn signatures. #![allow(non_camel_case_types)] +#![allow(unpredictable_function_pointer_comparisons)] // `dbg!()` differentiates these functions to ensure they won't be merged. extern "C" fn voidret1() { dbg!() } diff --git a/tests/ui/extern/extern-take-value.rs b/tests/ui/extern/extern-take-value.rs index 56ed3328614ce..f3df82b26109f 100644 --- a/tests/ui/extern/extern-take-value.rs +++ b/tests/ui/extern/extern-take-value.rs @@ -1,6 +1,8 @@ //@ run-pass //@ aux-build:extern-take-value.rs +#![allow(unpredictable_function_pointer_comparisons)] + extern crate extern_take_value; pub fn main() { diff --git a/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs b/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs index 2e1c863e0f4ca..3ec958f2ebff2 100644 --- a/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs +++ b/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs @@ -1,6 +1,8 @@ //@ compile-flags: -C opt-level=3 //@ run-pass +#![allow(unpredictable_function_pointer_comparisons)] + fn foo(_i: i32) -> i32 { 1 } diff --git a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs new file mode 100644 index 0000000000000..8eaa0c9194a80 --- /dev/null +++ b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs @@ -0,0 +1,8 @@ +// E0116 caused other unrelated errors, so check no unrelated errors are emmitted. + +fn main() { + let x = "hello"; + x.split(" "); +} + +impl Vec {} //~ ERROR E0116 diff --git a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr new file mode 100644 index 0000000000000..2a33262f83898 --- /dev/null +++ b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr @@ -0,0 +1,11 @@ +error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined + --> $DIR/no-other-unrelated-errors.rs:8:1 + | +LL | impl Vec {} + | ^^^^^^^^^^^^^^^ impl for type defined outside of crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0116`. diff --git a/tests/ui/inline-const/const-match-pat-generic.rs b/tests/ui/inline-const/const-match-pat-generic.rs index 9d76fc2ad65bc..889c015e9acb3 100644 --- a/tests/ui/inline-const/const-match-pat-generic.rs +++ b/tests/ui/inline-const/const-match-pat-generic.rs @@ -5,7 +5,7 @@ fn foo() { match 0 { const { V } => {}, - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters _ => {}, } } @@ -17,7 +17,7 @@ const fn f(x: usize) -> usize { fn bar() { match 0 { const { f(V) } => {}, - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters _ => {}, } } diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr index 26f72b34eca29..7d9e1d9e407e1 100644 --- a/tests/ui/inline-const/const-match-pat-generic.stderr +++ b/tests/ui/inline-const/const-match-pat-generic.stderr @@ -1,14 +1,14 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/const-match-pat-generic.rs:7:9 | LL | const { V } => {}, - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/const-match-pat-generic.rs:19:9 | LL | const { f(V) } => {}, - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ `const` depends on a generic parameter error: aborting due to 2 previous errors diff --git a/tests/ui/inline-const/pat-match-fndef.stderr b/tests/ui/inline-const/pat-match-fndef.stderr index b189ec51ade38..220437a0491af 100644 --- a/tests/ui/inline-const/pat-match-fndef.stderr +++ b/tests/ui/inline-const/pat-match-fndef.stderr @@ -1,8 +1,8 @@ -error: `fn() {uwu}` cannot be used in patterns +error: fn item `fn() {uwu}` cannot be used in patterns --> $DIR/pat-match-fndef.rs:8:9 | LL | const { uwu } => {} - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ fn item can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-54696.rs b/tests/ui/issues/issue-54696.rs index 75b1824f0b383..63ffbe42bcc9f 100644 --- a/tests/ui/issues/issue-54696.rs +++ b/tests/ui/issues/issue-54696.rs @@ -1,5 +1,7 @@ //@ run-pass +#![allow(unpredictable_function_pointer_comparisons)] + fn main() { // We shouldn't promote this let _ = &(main as fn() == main as fn()); diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.rs b/tests/ui/lint/fn-ptr-comparisons-weird.rs new file mode 100644 index 0000000000000..171fbfb87279d --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons-weird.rs @@ -0,0 +1,15 @@ +//@ check-pass + +fn main() { + let f: fn() = main; + let g: fn() = main; + + let _ = f > g; + //~^ WARN function pointer comparisons + let _ = f >= g; + //~^ WARN function pointer comparisons + let _ = f <= g; + //~^ WARN function pointer comparisons + let _ = f < g; + //~^ WARN function pointer comparisons +} diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.stderr b/tests/ui/lint/fn-ptr-comparisons-weird.stderr new file mode 100644 index 0000000000000..f237166392238 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons-weird.stderr @@ -0,0 +1,43 @@ +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:7:13 + | +LL | let _ = f > g; + | ^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit + = note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:9:13 + | +LL | let _ = f >= g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:11:13 + | +LL | let _ = f <= g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:13:13 + | +LL | let _ = f < g; + | ^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit + +warning: 4 warnings emitted + diff --git a/tests/ui/lint/fn-ptr-comparisons.fixed b/tests/ui/lint/fn-ptr-comparisons.fixed new file mode 100644 index 0000000000000..22f16177a0446 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons.fixed @@ -0,0 +1,58 @@ +//@ check-pass +//@ run-rustfix + +extern "C" { + fn test(); +} + +fn a() {} + +extern "C" fn c() {} + +extern "C" fn args(_a: i32) -> i32 { 0 } + +#[derive(PartialEq, Eq)] +struct A { + f: fn(), +} + +fn main() { + let f: fn() = a; + let g: fn() = f; + + let a1 = A { f }; + let a2 = A { f }; + + let _ = std::ptr::fn_addr_eq(f, a as fn()); + //~^ WARN function pointer comparisons + let _ = !std::ptr::fn_addr_eq(f, a as fn()); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(f, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(f, f); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(g, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(g, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(g, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(a as fn(), g); + //~^ WARN function pointer comparisons + + let cfn: extern "C" fn() = c; + let _ = std::ptr::fn_addr_eq(cfn, c as extern "C" fn()); + //~^ WARN function pointer comparisons + + let argsfn: extern "C" fn(i32) -> i32 = args; + let _ = std::ptr::fn_addr_eq(argsfn, args as extern "C" fn(i32) -> i32); + //~^ WARN function pointer comparisons + + let t: unsafe extern "C" fn() = test; + let _ = std::ptr::fn_addr_eq(t, test as unsafe extern "C" fn()); + //~^ WARN function pointer comparisons + + let _ = a1 == a2; // should not warn + let _ = std::ptr::fn_addr_eq(a1.f, a2.f); + //~^ WARN function pointer comparisons +} diff --git a/tests/ui/lint/fn-ptr-comparisons.rs b/tests/ui/lint/fn-ptr-comparisons.rs new file mode 100644 index 0000000000000..90a8ab5c926b6 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons.rs @@ -0,0 +1,58 @@ +//@ check-pass +//@ run-rustfix + +extern "C" { + fn test(); +} + +fn a() {} + +extern "C" fn c() {} + +extern "C" fn args(_a: i32) -> i32 { 0 } + +#[derive(PartialEq, Eq)] +struct A { + f: fn(), +} + +fn main() { + let f: fn() = a; + let g: fn() = f; + + let a1 = A { f }; + let a2 = A { f }; + + let _ = f == a; + //~^ WARN function pointer comparisons + let _ = f != a; + //~^ WARN function pointer comparisons + let _ = f == g; + //~^ WARN function pointer comparisons + let _ = f == f; + //~^ WARN function pointer comparisons + let _ = g == g; + //~^ WARN function pointer comparisons + let _ = g == g; + //~^ WARN function pointer comparisons + let _ = &g == &g; + //~^ WARN function pointer comparisons + let _ = a as fn() == g; + //~^ WARN function pointer comparisons + + let cfn: extern "C" fn() = c; + let _ = cfn == c; + //~^ WARN function pointer comparisons + + let argsfn: extern "C" fn(i32) -> i32 = args; + let _ = argsfn == args; + //~^ WARN function pointer comparisons + + let t: unsafe extern "C" fn() = test; + let _ = t == test; + //~^ WARN function pointer comparisons + + let _ = a1 == a2; // should not warn + let _ = a1.f == a2.f; + //~^ WARN function pointer comparisons +} diff --git a/tests/ui/lint/fn-ptr-comparisons.stderr b/tests/ui/lint/fn-ptr-comparisons.stderr new file mode 100644 index 0000000000000..eaba23a461ab6 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons.stderr @@ -0,0 +1,171 @@ +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:26:13 + | +LL | let _ = f == a; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit + = note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(f, a as fn()); + | +++++++++++++++++++++ ~ ++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:28:13 + | +LL | let _ = f != a; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = !std::ptr::fn_addr_eq(f, a as fn()); + | ++++++++++++++++++++++ ~ ++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:30:13 + | +LL | let _ = f == g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(f, g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:32:13 + | +LL | let _ = f == f; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(f, f); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:34:13 + | +LL | let _ = g == g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(g, g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:36:13 + | +LL | let _ = g == g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(g, g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:38:13 + | +LL | let _ = &g == &g; + | ^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(g, g); + | ~~~~~~~~~~~~~~~~~~~~~ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:40:13 + | +LL | let _ = a as fn() == g; + | ^^^^^^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(a as fn(), g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:44:13 + | +LL | let _ = cfn == c; + | ^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(cfn, c as extern "C" fn()); + | +++++++++++++++++++++ ~ +++++++++++++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:48:13 + | +LL | let _ = argsfn == args; + | ^^^^^^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(argsfn, args as extern "C" fn(i32) -> i32); + | +++++++++++++++++++++ ~ +++++++++++++++++++++++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:52:13 + | +LL | let _ = t == test; + | ^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(t, test as unsafe extern "C" fn()); + | +++++++++++++++++++++ ~ ++++++++++++++++++++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:56:13 + | +LL | let _ = a1.f == a2.f; + | ^^^^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(a1.f, a2.f); + | +++++++++++++++++++++ ~ + + +warning: 12 warnings emitted + diff --git a/tests/ui/match/issue-70972-dyn-trait.stderr b/tests/ui/match/issue-70972-dyn-trait.stderr index b0af50f8599c5..cec9c8539f416 100644 --- a/tests/ui/match/issue-70972-dyn-trait.stderr +++ b/tests/ui/match/issue-70972-dyn-trait.stderr @@ -1,8 +1,11 @@ -error: `dyn Send` cannot be used in patterns +error: trait object `dyn Send` cannot be used in patterns --> $DIR/issue-70972-dyn-trait.rs:6:9 | +LL | const F: &'static dyn Send = &7u32; + | -------------------------- constant defined here +... LL | F => panic!(), - | ^ + | ^ trait object can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.rs b/tests/ui/match/issue-72896-non-partial-eq-const.rs index f15eae83896d1..e4fc1ac057d32 100644 --- a/tests/ui/match/issue-72896-non-partial-eq-const.rs +++ b/tests/ui/match/issue-72896-non-partial-eq-const.rs @@ -16,7 +16,7 @@ const CONST_SET: EnumSet = EnumSet { __enumset_underlying: 3 }; fn main() { match CONST_SET { - CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq` + CONST_SET => { /* ok */ } //~ ERROR constant of non-structural type `EnumSet` in a pattern _ => panic!("match fell through?"), } } diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.stderr b/tests/ui/match/issue-72896-non-partial-eq-const.stderr index 4155586c16060..1f82d3e822adb 100644 --- a/tests/ui/match/issue-72896-non-partial-eq-const.stderr +++ b/tests/ui/match/issue-72896-non-partial-eq-const.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `EnumSet` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `EnumSet` in a pattern --> $DIR/issue-72896-non-partial-eq-const.rs:19:9 | +LL | enum Enum8 { } + | ---------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const CONST_SET: EnumSet = EnumSet { __enumset_underlying: 3 }; + | ------------------------------- constant defined here +... LL | CONST_SET => { /* ok */ } - | ^^^^^^^^^ + | ^^^^^^^^^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs b/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs index 44b7fae351cd2..45d519739eba8 100644 --- a/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs +++ b/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs @@ -1,6 +1,8 @@ //@ check-pass //@ compile-flags: -Zvalidate-mir +#![allow(unpredictable_function_pointer_comparisons)] + fn foo(_a: &str) {} fn main() { diff --git a/tests/ui/parser/typed-self-param.rs b/tests/ui/parser/typed-self-param.rs new file mode 100644 index 0000000000000..e3d85ab891b5b --- /dev/null +++ b/tests/ui/parser/typed-self-param.rs @@ -0,0 +1,14 @@ +struct S; + +impl S { + fn a(&self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter + fn b(&mut self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter + fn c<'c>(&'c mut self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter + fn d<'d>(&'d self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter +} + +fn main() {} diff --git a/tests/ui/parser/typed-self-param.stderr b/tests/ui/parser/typed-self-param.stderr new file mode 100644 index 0000000000000..c1ecd3b7fef43 --- /dev/null +++ b/tests/ui/parser/typed-self-param.stderr @@ -0,0 +1,50 @@ +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:4:17 + | +LL | fn a(&self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn a(&self: Self) {} +LL + fn a(self: &Self) {} + | + +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:6:21 + | +LL | fn b(&mut self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn b(&mut self: Self) {} +LL + fn b(self: &mut Self) {} + | + +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:8:28 + | +LL | fn c<'c>(&'c mut self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn c<'c>(&'c mut self: Self) {} +LL + fn c<'c>(self: &'c mut Self) {} + | + +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:10:24 + | +LL | fn d<'d>(&'d self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn d<'d>(&'d self: Self) {} +LL + fn d<'d>(self: &'d Self) {} + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/pattern/issue-115599.rs b/tests/ui/pattern/issue-115599.rs index 1521d728d9561..47fe6b87da942 100644 --- a/tests/ui/pattern/issue-115599.rs +++ b/tests/ui/pattern/issue-115599.rs @@ -3,5 +3,5 @@ const CONST_STRING: String = String::new(); fn main() { let empty_str = String::from(""); if let CONST_STRING = empty_str {} - //~^ ERROR to use a constant of type `Vec` in a pattern, `Vec` must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `Vec` in a pattern } diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr index adab4e4d241b7..69d10728ccdd7 100644 --- a/tests/ui/pattern/issue-115599.stderr +++ b/tests/ui/pattern/issue-115599.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `Vec` in a pattern, `Vec` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `Vec` in a pattern --> $DIR/issue-115599.rs:5:12 | +LL | const CONST_STRING: String = String::new(); + | -------------------------- constant defined here +... LL | if let CONST_STRING = empty_str {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ constant of non-structural type + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | + = note: `Vec` must be annotated with `#[derive(PartialEq)]` to be usable in patterns | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/pattern/issue-72565.stderr b/tests/ui/pattern/issue-72565.stderr index b503a17fe849f..e2927ada0f70b 100644 --- a/tests/ui/pattern/issue-72565.stderr +++ b/tests/ui/pattern/issue-72565.stderr @@ -1,8 +1,11 @@ -error: `dyn PartialEq` cannot be used in patterns +error: trait object `dyn PartialEq` cannot be used in patterns --> $DIR/issue-72565.rs:6:9 | +LL | const F: &'static dyn PartialEq = &7u32; + | ------------------------------------ constant defined here +... LL | F => panic!(), - | ^ + | ^ trait object can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/pattern/non-constant-in-const-path.stderr b/tests/ui/pattern/non-constant-in-const-path.stderr index 53c3974f780e4..2ba4963e6dc2d 100644 --- a/tests/ui/pattern/non-constant-in-const-path.stderr +++ b/tests/ui/pattern/non-constant-in-const-path.stderr @@ -2,25 +2,31 @@ error[E0080]: runtime values cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:8:15 | LL | let 0u8..=x = 0; - | ^ + | ^ references a runtime value error[E0158]: statics cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:10:15 | +LL | static FOO: u8 = 10; + | -------------- `static` defined here +... LL | let 0u8..=FOO = 0; - | ^^^ + | ^^^ can't be used in patterns error[E0080]: runtime values cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:13:15 | LL | 0 ..= x => {} - | ^ + | ^ references a runtime value error[E0158]: statics cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:15:15 | +LL | static FOO: u8 = 10; + | -------------- `static` defined here +... LL | 0 ..= FOO => {} - | ^^^ + | ^^^ can't be used in patterns error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr index 9075cf40ddae9..3588751bf6687 100644 --- a/tests/ui/pattern/non-structural-match-types.stderr +++ b/tests/ui/pattern/non-structural-match-types.stderr @@ -1,14 +1,14 @@ -error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns +error: closure `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns --> $DIR/non-structural-match-types.rs:9:9 | LL | const { || {} } => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ closure can't be used in patterns -error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns +error: `async` block `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns --> $DIR/non-structural-match-types.rs:12:9 | LL | const { async {} } => {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ `async` block can't be used in patterns error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs index f34093ef1498b..f09dcf8498f38 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs @@ -12,7 +12,7 @@ const CONSTANT: &&MyType = &&MyType; fn main() { if let CONSTANT = &&MyType { - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `MyType` in a pattern println!("did match!"); } } diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index 0b4d99727581b..f9da0430f2ef9 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `MyType` in a pattern --> $DIR/const-partial_eq-fallback-ice.rs:14:12 | +LL | struct MyType; + | ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const CONSTANT: &&MyType = &&MyType; + | ------------------------ constant defined here +... LL | if let CONSTANT = &&MyType { - | ^^^^^^^^ + | ^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/const-partial_eq-fallback-ice.rs:5:1 + | +LL | impl PartialEq for MyType { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 32d385eecb476..d52451d9438a1 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -1,50 +1,90 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:96:9 | +LL | const QUUX: Quux = quux; + | ---------------- constant defined here +... LL | QUUX => {} - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:97:9 | +LL | const QUUX: Quux = quux; + | ---------------- constant defined here +... LL | QUUX => {} - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:106:9 | +LL | const WRAPQUUX: Wrap = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:107:9 | +LL | const WRAPQUUX: Wrap = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:113:9 | +LL | const WRAPQUUX: Wrap = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:121:9 | +LL | const WRAPQUUX: Wrap = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:132:9 | +LL | const WHOKNOWSQUUX: WhoKnows = WhoKnows::Yay(quux); + | ---------------------------------- constant defined here +... LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:134:9 | +LL | const WHOKNOWSQUUX: WhoKnows = WhoKnows::Yay(quux); + | ---------------------------------- constant defined here +... LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: unreachable pattern --> $DIR/consts-opaque.rs:48:9 diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs index 65a85a5ed68f6..e27c804804971 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs @@ -20,7 +20,7 @@ const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0)); fn main() { match WRAP_DIRECT_INLINE { WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DIRECT_INLINE did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr index cc5d4106331d2..8787d140e17ff 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0)); + | ------------------------------------ constant defined here +... LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-direct-struct-embedded.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs index f840b4040b653..713ff23573d43 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs @@ -19,7 +19,7 @@ const WRAP_DIRECT_PARAM: WrapParam = WrapParam(NoDerive(0)); fn main() { match WRAP_DIRECT_PARAM { WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DIRECT_PARAM did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr index 3d00ef2dfbf6d..ec836db02ad8a 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-direct-struct-param.rs:21:9 | +LL | struct NoDerive(i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DIRECT_PARAM: WrapParam = WrapParam(NoDerive(0)); + | -------------------------------------------- constant defined here +... LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-direct-struct-param.rs:10:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs index 898acefc83cc0..7766a4691923d 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs @@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0) fn main() { match WRAP_DOUBLY_INDIRECT_INLINE { WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index 3636307e16c61..fdc16fe300c20 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0)); + | ------------------------------------------------ constant defined here +... LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs index 7cbaada88a30a..ed84900b6e914 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs @@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam = & &WrapParam(& & NoDe fn main() { match WRAP_DOUBLY_INDIRECT_PARAM { WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index 40fd31762b2fe..b46fc041f14b1 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-doubly-indirect-param.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam = & &WrapParam(& & NoDerive(0)); + | -------------------------------------------------------- constant defined here +... LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs index ac868efed6fd1..5743d7a24d3a3 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs @@ -20,7 +20,7 @@ const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); fn main() { match WRAP_INDIRECT_INLINE { WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index dbf1848326aa4..70f39aa01d822 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); + | ----------------------------------------- constant defined here +... LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs index cbfabec6819e9..9226f9c3ecdea 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs @@ -20,7 +20,7 @@ const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); fn main() { match WRAP_INDIRECT_PARAM { WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index 58acc11a74498..fceb3acb025eb 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-indirect-struct-param.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); + | ------------------------------------------------- constant defined here +... LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-indirect-struct-param.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr index 0bc1e7fc89b5f..cdbe72ca48f8f 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr @@ -1,62 +1,112 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:41:14 | +LL | const CFN1: Wrap = Wrap(trivial); + | ---------------------- constant defined here +... LL | Wrap(CFN1) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:49:14 | +LL | const CFN2: Wrap = Wrap(sm_to); + | ------------------------ constant defined here +... LL | Wrap(CFN2) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:57:14 | +LL | const CFN3: Wrap SM> = Wrap(to_sm); + | ---------------------------- constant defined here +... LL | Wrap(CFN3) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:65:14 | +LL | const CFN4: Wrap = Wrap(not_sm_to); + | --------------------------- constant defined here +... LL | Wrap(CFN4) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:73:14 | +LL | const CFN5: Wrap NotSM> = Wrap(to_not_sm); + | ------------------------------- constant defined here +... LL | Wrap(CFN5) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:81:14 | +LL | const CFN6: Wrap = Wrap(r_sm_to); + | ------------------------- constant defined here +... LL | Wrap(CFN6) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:89:14 | +LL | const CFN7: Wrap &SM> = Wrap(r_to_r_sm); + | -------------------------------- constant defined here +... LL | Wrap(CFN7) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:97:14 | +LL | const CFN8: Wrap = Wrap(r_not_sm_to); + | ---------------------------- constant defined here +... LL | Wrap(CFN8) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:105:14 | +LL | const CFN9: Wrap &NotSM> = Wrap(r_to_r_not_sm); + | ----------------------------------- constant defined here +... LL | Wrap(CFN9) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:127:9 | +LL | const CFOO: Foo = Foo { + | --------------- constant defined here +... LL | CFOO => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 10 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs index c01f8934c750e..95a3be517a9a5 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs @@ -12,8 +12,7 @@ const A: &[B] = &[]; pub fn main() { match &[][..] { - A => (), - //~^ ERROR must implement `PartialEq` + A => (), //~ ERROR constant of non-structural type `&[B]` in a pattern _ => (), } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr index 736e4c30c8ae3..7d3b37686b865 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `&[B]` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `&[B]` in a pattern --> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9 | +LL | struct B(i32); + | -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const A: &[B] = &[]; + | ------------- constant defined here +... LL | A => (), - | ^ + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs index 0fa2370c95bf4..843c5a3864907 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -13,27 +13,35 @@ #[derive(Debug)] struct B(i32); +//~^ NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +//~| NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns // Overriding `PartialEq` to use this strange notion of "equality" exposes // whether `match` is using structural-equality or method-dispatch // under the hood, which is the antithesis of rust-lang/rfcs#1445 impl PartialEq for B { +//~^ NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient +//~| NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 } } fn main() { const RR_B0: & & B = & & B(0); const RR_B1: & & B = & & B(1); + //~^ NOTE constant defined here + //~| NOTE constant defined here match RR_B0 { RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `B` in a pattern + //~| NOTE constant of non-structural type _ => { } } match RR_B1 { RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `B` in a pattern + //~| NOTE constant of non-structural type _ => { } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index e79b05fdf9dc6..34fffd99c2c9f 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -1,20 +1,38 @@ -error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:29:9 +error: constant of non-structural type `B` in a pattern + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9 | +LL | struct B(i32); + | -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const RR_B1: & & B = & & B(1); + | ------------------ constant defined here +... LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - | ^^^^^ + | ^^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for B { + | ^^^^^^^^^^^^^^^^^^^^ -error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9 +error: constant of non-structural type `B` in a pattern + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:42:9 | +LL | struct B(i32); + | -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const RR_B1: & & B = & & B(1); + | ------------------ constant defined here +... LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - | ^^^^^ + | ^^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for B { + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr index 7b1832ed0fa58..ea6121839be5e 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr @@ -1,14 +1,24 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-63479-match-fnptr.rs:32:7 | +LL | const TEST: Fn = my_fn; + | -------------- constant defined here +... LL | B(TEST) => println!("matched"), - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-63479-match-fnptr.rs:37:5 | +LL | const TEST2: (Fn, u8) = (TEST, 0); + | --------------------- constant defined here +... LL | TEST2 => println!("matched"), - | ^^^^^ + | ^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr index 44b05ea31e962..7c49870e5d03d 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr @@ -1,8 +1,11 @@ error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:14:9 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | NAN => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -10,8 +13,11 @@ LL | NAN => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:19:10 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | [NAN, _] => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -19,8 +25,11 @@ LL | [NAN, _] => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:24:9 | +LL | const C: MyType = MyType(f32::NAN); + | -------------------- constant defined here +... LL | C => {}, - | ^ + | ^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -28,8 +37,11 @@ LL | C => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:30:9 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | NAN..=1.0 => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -37,8 +49,11 @@ LL | NAN..=1.0 => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:31:16 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | -1.0..=NAN => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -46,8 +61,11 @@ LL | -1.0..=NAN => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:32:9 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | NAN.. => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -55,8 +73,11 @@ LL | NAN.. => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:33:11 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | ..NAN => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs index 9020eb291f5c5..74394698fbcd9 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs @@ -1,3 +1,5 @@ +// Note: It is no longer true that both `Eq` and `PartialEq` must the derived, only the later. + #[derive(Eq)] struct Foo { x: u32 @@ -15,7 +17,7 @@ fn main() { let y = Foo { x: 1 }; match y { FOO => { } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `Foo` in a pattern _ => { } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr index efd9c8c45afa9..bbcab3b62d0e3 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]` - --> $DIR/match-requires-both-partialeq-and-eq.rs:17:9 +error: constant of non-structural type `Foo` in a pattern + --> $DIR/match-requires-both-partialeq-and-eq.rs:19:9 | +LL | struct Foo { + | ---------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const FOO: Foo = Foo { x: 0 }; + | -------------- constant defined here +... LL | FOO => { } - | ^^^ + | ^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/match-requires-both-partialeq-and-eq.rs:8:1 + | +LL | impl PartialEq for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.rs b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.rs new file mode 100644 index 0000000000000..35612093aff04 --- /dev/null +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.rs @@ -0,0 +1,26 @@ +//! Regression test for suggestions that were fired on empty spans +//! involving macro-call statements. For some reason the semicolon +//! is not included in the overall span of the macro-call statement. +//! +//! Issue 1: . +//! Issue 2: . +//! See also: . + +fn foo() -> String { + let mut list = { + println!(); + }; + list //~ ERROR mismatched types +} + +fn bar() { + String::new() + .chars() + .filter(|x| !x.is_whitespace()) + .map(|x| { + println!("Child spawned with the size: {}", x); + }) + .collect::(); //~ ERROR E0277 +} + +fn main() {} diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr new file mode 100644 index 0000000000000..4b83bfff86333 --- /dev/null +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr @@ -0,0 +1,50 @@ +error[E0308]: mismatched types + --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:13:5 + | +LL | fn foo() -> String { + | ------ expected `String` because of return type +LL | let mut list = { + | ____________________- +LL | | println!(); +LL | | }; + | |_____- this block is missing a tail expression +LL | list + | ^^^^ expected `String`, found `()` + +error[E0277]: a value of type `String` cannot be built from an iterator over elements of type `()` + --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:23:20 + | +LL | .collect::(); + | ------- ^^^^^^ value of type `String` cannot be built from `std::iter::Iterator` + | | + | required by a bound introduced by this call + | + = help: the trait `FromIterator<()>` is not implemented for `String` + = help: the following other types implement trait `FromIterator`: + `String` implements `FromIterator<&char>` + `String` implements `FromIterator<&str>` + `String` implements `FromIterator>` + `String` implements `FromIterator>` + `String` implements `FromIterator` + `String` implements `FromIterator` +note: the method call chain might not have had the expected associated types + --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:20:10 + | +LL | String::new() + | ------------- this expression has type `String` +LL | .chars() + | ------- `Iterator::Item` is `char` here +LL | .filter(|x| !x.is_whitespace()) + | ------------------------------ `Iterator::Item` remains `char` here +LL | .map(|x| { + | __________^ +LL | | println!("Child spawned with the size: {}", x); +LL | | }) + | |__________^ `Iterator::Item` changed to `()` here +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr index 98d71aa9a17dc..28f5d6728a9de 100644 --- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -1,8 +1,11 @@ -error: `Bar` cannot be used in patterns +error: opaque type `Bar` cannot be used in patterns --> $DIR/structural-match-no-leak.rs:16:9 | +LL | const LEAK_FREE: bar::Bar = bar::leak_free(); + | ------------------------- constant defined here +... LL | LEAK_FREE => (), - | ^^^^^^^^^ + | ^^^^^^^^^ opaque type can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr index c7478b0a135e5..b06b31a060fb9 100644 --- a/tests/ui/type-alias-impl-trait/structural-match.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match.stderr @@ -1,8 +1,11 @@ -error: `foo::Foo` cannot be used in patterns +error: opaque type `foo::Foo` cannot be used in patterns --> $DIR/structural-match.rs:18:9 | +LL | const VALUE: Foo = value(); + | ---------------- constant defined here +... LL | VALUE => (), - | ^^^^^ + | ^^^^^ opaque type can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs index 3defe0cb44d3b..55f45ade38804 100644 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs +++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs @@ -1,4 +1,4 @@ -#![feature(pattern_types, core_pattern_type)] +#![feature(pattern_types, pattern_type_macro)] #![allow(internal_features)] type Pat = diff --git a/tests/ui/type/pattern_types/bad_pat.rs b/tests/ui/type/pattern_types/bad_pat.rs index 8ad042eeba65e..6cb2a0f1f8e74 100644 --- a/tests/ui/type/pattern_types/bad_pat.rs +++ b/tests/ui/type/pattern_types/bad_pat.rs @@ -1,6 +1,5 @@ #![feature(pattern_types)] -#![feature(core_pattern_types)] -#![feature(core_pattern_type)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/bad_pat.stderr b/tests/ui/type/pattern_types/bad_pat.stderr index f5cf7930c8328..c857cc3c3add9 100644 --- a/tests/ui/type/pattern_types/bad_pat.stderr +++ b/tests/ui/type/pattern_types/bad_pat.stderr @@ -1,5 +1,5 @@ error[E0586]: inclusive range with no end - --> $DIR/bad_pat.rs:7:43 + --> $DIR/bad_pat.rs:6:43 | LL | type NonNullU32_2 = pattern_type!(u32 is 1..=); | ^^^ @@ -12,7 +12,7 @@ LL + type NonNullU32_2 = pattern_type!(u32 is 1..); | error[E0586]: inclusive range with no end - --> $DIR/bad_pat.rs:9:40 + --> $DIR/bad_pat.rs:8:40 | LL | type Positive2 = pattern_type!(i32 is 0..=); | ^^^ @@ -25,7 +25,7 @@ LL + type Positive2 = pattern_type!(i32 is 0..); | error: wildcard patterns are not permitted for pattern types - --> $DIR/bad_pat.rs:11:33 + --> $DIR/bad_pat.rs:10:33 | LL | type Wild = pattern_type!(() is _); | ^ diff --git a/tests/ui/type/pattern_types/const_generics.rs b/tests/ui/type/pattern_types/const_generics.rs index 5bc6fd54e0fce..5cef0dc030552 100644 --- a/tests/ui/type/pattern_types/const_generics.rs +++ b/tests/ui/type/pattern_types/const_generics.rs @@ -1,8 +1,7 @@ //@ check-pass #![feature(pattern_types)] -#![feature(core_pattern_types)] -#![feature(core_pattern_type)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/derives.rs b/tests/ui/type/pattern_types/derives.rs index b8b53e61102bc..3878c47554d98 100644 --- a/tests/ui/type/pattern_types/derives.rs +++ b/tests/ui/type/pattern_types/derives.rs @@ -1,8 +1,7 @@ //! Check that pattern types don't implement traits of their base automatically #![feature(pattern_types)] -#![feature(core_pattern_types)] -#![feature(core_pattern_type)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/derives.stderr b/tests/ui/type/pattern_types/derives.stderr index 1d4d3fc55c3fa..9d4baef621be3 100644 --- a/tests/ui/type/pattern_types/derives.stderr +++ b/tests/ui/type/pattern_types/derives.stderr @@ -1,5 +1,5 @@ error[E0369]: binary operation `==` cannot be applied to type `(i32) is 0..=999999999` - --> $DIR/derives.rs:11:20 + --> $DIR/derives.rs:10:20 | LL | #[derive(Clone, Copy, PartialEq)] | --------- in this derive macro expansion diff --git a/tests/ui/type/pattern_types/feature-gate-pattern_types.rs b/tests/ui/type/pattern_types/feature-gate-pattern_types.rs index e638f3c6c40d7..b90ba4784023a 100644 --- a/tests/ui/type/pattern_types/feature-gate-pattern_types.rs +++ b/tests/ui/type/pattern_types/feature-gate-pattern_types.rs @@ -3,12 +3,12 @@ use std::pat::pattern_type; type NonNullU32 = pattern_type!(u32 is 1..); -//~^ use of unstable library feature `core_pattern_type` +//~^ use of unstable library feature `pattern_type_macro` type Percent = pattern_type!(u32 is 0..=100); -//~^ use of unstable library feature `core_pattern_type` +//~^ use of unstable library feature `pattern_type_macro` type Negative = pattern_type!(i32 is ..=0); -//~^ use of unstable library feature `core_pattern_type` +//~^ use of unstable library feature `pattern_type_macro` type Positive = pattern_type!(i32 is 0..); -//~^ use of unstable library feature `core_pattern_type` +//~^ use of unstable library feature `pattern_type_macro` type Always = pattern_type!(Option is Some(_)); -//~^ use of unstable library feature `core_pattern_type` +//~^ use of unstable library feature `pattern_type_macro` diff --git a/tests/ui/type/pattern_types/feature-gate-pattern_types.stderr b/tests/ui/type/pattern_types/feature-gate-pattern_types.stderr index 6cbadf370a7dc..69239d68bdc75 100644 --- a/tests/ui/type/pattern_types/feature-gate-pattern_types.stderr +++ b/tests/ui/type/pattern_types/feature-gate-pattern_types.stderr @@ -1,51 +1,51 @@ -error[E0658]: use of unstable library feature `core_pattern_type` +error[E0658]: use of unstable library feature `pattern_type_macro` --> $DIR/feature-gate-pattern_types.rs:5:19 | LL | type NonNullU32 = pattern_type!(u32 is 1..); | ^^^^^^^^^^^^ | = note: see issue #123646 for more information - = help: add `#![feature(core_pattern_type)]` to the crate attributes to enable + = help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `core_pattern_type` +error[E0658]: use of unstable library feature `pattern_type_macro` --> $DIR/feature-gate-pattern_types.rs:7:16 | LL | type Percent = pattern_type!(u32 is 0..=100); | ^^^^^^^^^^^^ | = note: see issue #123646 for more information - = help: add `#![feature(core_pattern_type)]` to the crate attributes to enable + = help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `core_pattern_type` +error[E0658]: use of unstable library feature `pattern_type_macro` --> $DIR/feature-gate-pattern_types.rs:9:17 | LL | type Negative = pattern_type!(i32 is ..=0); | ^^^^^^^^^^^^ | = note: see issue #123646 for more information - = help: add `#![feature(core_pattern_type)]` to the crate attributes to enable + = help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `core_pattern_type` +error[E0658]: use of unstable library feature `pattern_type_macro` --> $DIR/feature-gate-pattern_types.rs:11:17 | LL | type Positive = pattern_type!(i32 is 0..); | ^^^^^^^^^^^^ | = note: see issue #123646 for more information - = help: add `#![feature(core_pattern_type)]` to the crate attributes to enable + = help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `core_pattern_type` +error[E0658]: use of unstable library feature `pattern_type_macro` --> $DIR/feature-gate-pattern_types.rs:13:15 | LL | type Always = pattern_type!(Option is Some(_)); | ^^^^^^^^^^^^ | = note: see issue #123646 for more information - = help: add `#![feature(core_pattern_type)]` to the crate attributes to enable + = help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 5 previous errors diff --git a/tests/ui/type/pattern_types/feature-gate-pattern_types2.rs b/tests/ui/type/pattern_types/feature-gate-pattern_types2.rs index d7b3ea58e0265..50c355c8de61a 100644 --- a/tests/ui/type/pattern_types/feature-gate-pattern_types2.rs +++ b/tests/ui/type/pattern_types/feature-gate-pattern_types2.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Zno-analysis //@ check-pass -#![feature(core_pattern_type)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/missing-is.rs b/tests/ui/type/pattern_types/missing-is.rs index 2fbcc1908efcb..564b41649d899 100644 --- a/tests/ui/type/pattern_types/missing-is.rs +++ b/tests/ui/type/pattern_types/missing-is.rs @@ -1,4 +1,4 @@ -#![feature(core_pattern_type, core_pattern_types)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index 9eddc8cab7fe1..7c25edb1c3fd5 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 7bd0d826cab71..0eed7c2ce1ce8 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -37,7 +37,7 @@ error: layout_of(NonZero) = Layout { max_repr_align: None, unadjusted_abi_align: Align(4 bytes), } - --> $DIR/range_patterns.rs:11:1 + --> $DIR/range_patterns.rs:10:1 | LL | type X = std::num::NonZeroU32; | ^^^^^^ @@ -74,7 +74,7 @@ error: layout_of((u32) is 1..=) = Layout { max_repr_align: None, unadjusted_abi_align: Align(4 bytes), } - --> $DIR/range_patterns.rs:13:1 + --> $DIR/range_patterns.rs:12:1 | LL | type Y = pattern_type!(u32 is 1..); | ^^^^^^ @@ -182,7 +182,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { max_repr_align: None, unadjusted_abi_align: Align(4 bytes), } - --> $DIR/range_patterns.rs:15:1 + --> $DIR/range_patterns.rs:14:1 | LL | type Z = Option; | ^^^^^^ @@ -290,7 +290,7 @@ error: layout_of(Option>) = Layout { max_repr_align: None, unadjusted_abi_align: Align(4 bytes), } - --> $DIR/range_patterns.rs:17:1 + --> $DIR/range_patterns.rs:16:1 | LL | type A = Option; | ^^^^^^ @@ -334,7 +334,7 @@ error: layout_of(NonZeroU32New) = Layout { max_repr_align: None, unadjusted_abi_align: Align(4 bytes), } - --> $DIR/range_patterns.rs:19:1 + --> $DIR/range_patterns.rs:18:1 | LL | struct NonZeroU32New(pattern_type!(u32 is 1..)); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type/pattern_types/range_patterns_inherent_impls.rs b/tests/ui/type/pattern_types/range_patterns_inherent_impls.rs index 9653a744c4162..fe8feda0934e2 100644 --- a/tests/ui/type/pattern_types/range_patterns_inherent_impls.rs +++ b/tests/ui/type/pattern_types/range_patterns_inherent_impls.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //! check that pattern types can have traits implemented for them if diff --git a/tests/ui/type/pattern_types/range_patterns_inherent_impls.stderr b/tests/ui/type/pattern_types/range_patterns_inherent_impls.stderr index 784ebb0c9f012..ed2e4c0bd5f8c 100644 --- a/tests/ui/type/pattern_types/range_patterns_inherent_impls.stderr +++ b/tests/ui/type/pattern_types/range_patterns_inherent_impls.stderr @@ -1,12 +1,12 @@ error[E0390]: cannot define inherent `impl` for primitive types outside of `core` - --> $DIR/range_patterns_inherent_impls.rs:13:1 + --> $DIR/range_patterns_inherent_impls.rs:12:1 | LL | impl Y { | ^^^^^^ | = help: consider moving this inherent impl into `core` if possible help: alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items - --> $DIR/range_patterns_inherent_impls.rs:15:5 + --> $DIR/range_patterns_inherent_impls.rs:14:5 | LL | fn foo() {} | ^^^^^^^^ diff --git a/tests/ui/type/pattern_types/range_patterns_trait_impls.rs b/tests/ui/type/pattern_types/range_patterns_trait_impls.rs index f8c9af8628182..1731cd470fe2c 100644 --- a/tests/ui/type/pattern_types/range_patterns_trait_impls.rs +++ b/tests/ui/type/pattern_types/range_patterns_trait_impls.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //! check that pattern types can have local traits diff --git a/tests/ui/type/pattern_types/range_patterns_trait_impls2.rs b/tests/ui/type/pattern_types/range_patterns_trait_impls2.rs index acde4580c1b20..90f80a2f34645 100644 --- a/tests/ui/type/pattern_types/range_patterns_trait_impls2.rs +++ b/tests/ui/type/pattern_types/range_patterns_trait_impls2.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //! check that pattern types can have local traits diff --git a/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr b/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr index df56db031ed18..d5c539b6c52e6 100644 --- a/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr +++ b/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr @@ -1,5 +1,5 @@ error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/range_patterns_trait_impls2.rs:13:1 + --> $DIR/range_patterns_trait_impls2.rs:12:1 | LL | impl Eq for Y {} | ^^^^^^^^^^^^- diff --git a/tests/ui/type/pattern_types/range_patterns_unusable.rs b/tests/ui/type/pattern_types/range_patterns_unusable.rs index 7cde44f41335b..98f13ca0bc0bb 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable.rs +++ b/tests/ui/type/pattern_types/range_patterns_unusable.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //! Some practical niche checks. diff --git a/tests/ui/type/pattern_types/range_patterns_unusable.stderr b/tests/ui/type/pattern_types/range_patterns_unusable.stderr index aa0e592684b6b..8377d417452bb 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable.stderr +++ b/tests/ui/type/pattern_types/range_patterns_unusable.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/range_patterns_unusable.rs:14:35 + --> $DIR/range_patterns_unusable.rs:13:35 | LL | let _: Option = unsafe { std::mem::transmute(z) }; | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs index bc1ab75429d66..ece4009e1e7d8 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs +++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //! check that pattern types don't have an `Add` impl. diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr index e52d899a703f2..373615e3714e5 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr +++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr @@ -1,5 +1,5 @@ error[E0369]: cannot add `u32` to `(u32) is 1..=` - --> $DIR/range_patterns_unusable_math.rs:15:15 + --> $DIR/range_patterns_unusable_math.rs:14:15 | LL | let x = x + 1_u32; | - ^ ----- u32 diff --git a/tests/ui/type/pattern_types/range_patterns_usage.rs b/tests/ui/type/pattern_types/range_patterns_usage.rs index 2a9f736ae61d5..0ecbdcaa0f7a3 100644 --- a/tests/ui/type/pattern_types/range_patterns_usage.rs +++ b/tests/ui/type/pattern_types/range_patterns_usage.rs @@ -1,6 +1,5 @@ #![feature(pattern_types, rustc_attrs)] -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] #![allow(incomplete_features)] //@ check-pass diff --git a/tests/ui/type/pattern_types/unimplemented_pat.rs b/tests/ui/type/pattern_types/unimplemented_pat.rs index c02160ff58a6c..b2398cec7c9b5 100644 --- a/tests/ui/type/pattern_types/unimplemented_pat.rs +++ b/tests/ui/type/pattern_types/unimplemented_pat.rs @@ -1,8 +1,7 @@ //! This test ensures we do not ICE for unimplemented //! patterns unless the feature gate is enabled. -#![feature(core_pattern_type)] -#![feature(core_pattern_types)] +#![feature(pattern_type_macro)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/unimplemented_pat.stderr b/tests/ui/type/pattern_types/unimplemented_pat.stderr index 481c6017dccc2..7b0f9cbaa6a96 100644 --- a/tests/ui/type/pattern_types/unimplemented_pat.stderr +++ b/tests/ui/type/pattern_types/unimplemented_pat.stderr @@ -1,5 +1,5 @@ error[E0658]: pattern types are unstable - --> $DIR/unimplemented_pat.rs:9:15 + --> $DIR/unimplemented_pat.rs:8:15 | LL | type Always = pattern_type!(Option is Some(_)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | type Always = pattern_type!(Option is Some(_)); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pattern types are unstable - --> $DIR/unimplemented_pat.rs:12:16 + --> $DIR/unimplemented_pat.rs:11:16 | LL | type Binding = pattern_type!(Option is x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/union/union-const-pat.stderr b/tests/ui/union/union-const-pat.stderr index e9dbb275944ae..59dc89c77a47c 100644 --- a/tests/ui/union/union-const-pat.stderr +++ b/tests/ui/union/union-const-pat.stderr @@ -1,8 +1,11 @@ error: cannot use unions in constant patterns --> $DIR/union-const-pat.rs:10:9 | +LL | const C: U = U { a: 10 }; + | ---------- constant defined here +... LL | C => {} - | ^ + | ^ can't use a `union` here error: aborting due to 1 previous error diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs index 891021e876609..9af57fe4c3cd0 100644 --- a/tests/ui/unpretty/expanded-exhaustive.rs +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -8,7 +8,6 @@ #![feature(builtin_syntax)] #![feature(concat_idents)] #![feature(const_trait_impl)] -#![feature(core_pattern_type)] #![feature(decl_macro)] #![feature(deref_patterns)] #![feature(explicit_tail_calls)] @@ -18,6 +17,7 @@ #![feature(never_patterns)] #![feature(never_type)] #![feature(pattern_types)] +#![feature(pattern_type_macro)] #![feature(prelude_import)] #![feature(specialization)] #![feature(trace_macros)] diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 007626e2c4406..14a274415ca72 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -9,7 +9,6 @@ #![feature(builtin_syntax)] #![feature(concat_idents)] #![feature(const_trait_impl)] -#![feature(core_pattern_type)] #![feature(decl_macro)] #![feature(deref_patterns)] #![feature(explicit_tail_calls)] @@ -19,6 +18,7 @@ #![feature(never_patterns)] #![feature(never_type)] #![feature(pattern_types)] +#![feature(pattern_type_macro)] #![feature(prelude_import)] #![feature(specialization)] #![feature(trace_macros)]