diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 2a783cd73d9de..5d14d3fd627d0 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![cfg_attr(all(feature = "nightly", bootstrap, test), feature(assert_matches))] +#![cfg_attr(all(feature = "nightly", test), feature(assert_matches))] #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(step_trait))] diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3e34f2e5896ee..c2c07614bc0dd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -545,6 +545,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } // for dbg!(x) which may take ownership, suggest dbg!(&x) instead + // but here we actually do not check whether the macro name is `dbg!` + // so that we may extend the scope a bit larger to cover more cases fn suggest_ref_for_dbg_args( &self, body: &hir::Expr<'_>, @@ -558,41 +560,29 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }); let Some(var_info) = var_info else { return }; let arg_name = var_info.name; - struct MatchArgFinder<'tcx> { - tcx: TyCtxt<'tcx>, - move_span: Span, + struct MatchArgFinder { + expr_span: Span, + match_arg_span: Option, arg_name: Symbol, - match_arg_span: Option = None, } - impl Visitor<'_> for MatchArgFinder<'_> { + impl Visitor<'_> for MatchArgFinder { fn visit_expr(&mut self, e: &hir::Expr<'_>) { // dbg! is expanded into a match pattern, we need to find the right argument span - if let hir::ExprKind::Match(scrutinee, ..) = &e.kind - && let hir::ExprKind::Tup(args) = scrutinee.kind - && e.span.macro_backtrace().any(|expn| { - expn.macro_def_id.is_some_and(|macro_def_id| { - self.tcx.is_diagnostic_item(sym::dbg_macro, macro_def_id) - }) - }) + if let hir::ExprKind::Match(expr, ..) = &e.kind + && let hir::ExprKind::Path(hir::QPath::Resolved( + _, + path @ Path { segments: [seg], .. }, + )) = &expr.kind + && seg.ident.name == self.arg_name + && self.expr_span.source_callsite().contains(expr.span) { - for arg in args { - if let hir::ExprKind::Path(hir::QPath::Resolved( - _, - path @ Path { segments: [seg], .. }, - )) = &arg.kind - && seg.ident.name == self.arg_name - && self.move_span.source_equal(arg.span) - { - self.match_arg_span = Some(path.span); - return; - } - } + self.match_arg_span = Some(path.span); } hir::intravisit::walk_expr(self, e); } } - let mut finder = MatchArgFinder { tcx: self.infcx.tcx, move_span, arg_name, .. }; + let mut finder = MatchArgFinder { expr_span: move_span, match_arg_span: None, arg_name }; finder.visit_expr(body); if let Some(macro_arg_span) = finder.match_arg_span { err.span_suggestion_verbose( diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index bd46a40c02da1..f52f61e49c91e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,8 +2,8 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(default_field_values)] #![feature(file_buffered)] diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 9c4005c7f7f2f..f671f59f983a3 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -3,8 +3,8 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(iter_order_by)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 7120ee0afec96..6f8451b6c0174 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,8 +5,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(extern_types)] #![feature(file_buffered)] #![feature(impl_trait_in_assoc_type)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index c7e90d3b3c330..42a4985d0231a 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,6 +1,6 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(negative_impls)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index e57d719a67a42..f42701d59b405 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,7 +1,7 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] #![feature(array_try_map)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(never_type)] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b01834aa80d9d..3bc6d9bd2ec10 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,7 +10,6 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(cfg_select))] #![cfg_attr(bootstrap, feature(cold_path))] #![cfg_attr(test, feature(test))] @@ -18,6 +17,7 @@ #![feature(allocator_api)] #![feature(ascii_char)] #![feature(ascii_char_variants)] +#![feature(assert_matches)] #![feature(auto_traits)] #![feature(const_default)] #![feature(const_trait_impl)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 837a41c191e15..5ff5bd7fe29b2 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -5,7 +5,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::direct_use_of_rustc_type_ir)] -#![cfg_attr(bootstrap, feature(assert_matches))] +#![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(default_field_values)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 40e79234d0201..a571094c9dc32 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -56,8 +56,8 @@ This API is completely unstable and subject to change. */ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(default_field_values)] #![feature(gen_blocks)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 3d044c1086b06..8eb270dd1bc00 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -921,6 +921,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_did: DefId, callee_args: GenericArgsRef<'tcx>, ) { + // FIXME(const_trait_impl): We should be enforcing these effects unconditionally. + // This can be done as soon as we convert the standard library back to + // using const traits, since if we were to enforce these conditions now, + // we'd fail on basically every builtin trait call (i.e. `1 + 2`). + if !self.tcx.features().const_trait_impl() { + return; + } + // If we have `rustc_do_not_const_check`, do not check `[const]` bounds. if self.has_rustc_attrs && find_attr!(self.tcx, self.body_id, RustcDoNotConstCheck) { return; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 15e94a27d559c..a96bd2da48ccd 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,6 +1,6 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(iter_intersperse)] #![feature(iter_order_by)] diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 008b5c94a5eaa..2a1733ef63cb9 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -14,7 +14,7 @@ // tidy-alphabetical-start #![allow(rustc::direct_use_of_rustc_type_ir)] -#![cfg_attr(bootstrap, feature(assert_matches))] +#![feature(assert_matches)] #![feature(extend_one)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 34276eb76cf39..9da2125d964a3 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,8 +21,8 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(iter_order_by)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 615381b37cdb1..5f8f20147a9be 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -27,10 +27,10 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::direct_use_of_rustc_type_ir)] -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] #![cfg_attr(doc, feature(intra_doc_pointers))] #![feature(allocator_api)] +#![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_as_ptr)] #![feature(box_patterns)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 7637ea81b0106..fcb5de69f0e44 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -1,8 +1,8 @@ //! Construction of MIR from HIR. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 692591a41a15b..5f1cf12501522 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] +#![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(exact_size_is_empty)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 7dd198ed9f9cc..51e100ef308d3 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,6 +1,6 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(const_type_name)] #![feature(cow_is_borrowed)] diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 1124f5830b6e6..6a0fe91493d5d 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -1,9 +1,9 @@ //! The main parser interface. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] #![cfg_attr(test, feature(iter_order_by))] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(debug_closure_helpers)] #![feature(default_field_values)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c12281a9e0ef0..949a96bc0ab99 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -8,10 +8,10 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] #![cfg_attr(bootstrap, feature(ptr_as_ref_unchecked))] #![feature(arbitrary_self_types)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(const_default)] #![feature(const_trait_impl)] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5b079bcaf0db8..731a838530729 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -763,7 +763,6 @@ symbols! { custom_test_frameworks, d, d32, - dbg_macro, dead_code, dealloc, debug, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 35a3d0dac8afa..7e126cb6a6e95 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -88,7 +88,7 @@ //! DefPaths which are much more robust in the face of changes to the code base. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] +#![feature(assert_matches)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 5677a849d7495..72dbef0b37469 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,8 +11,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(default_field_values)] diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 2e21efbde1ac5..fbe7cdcd52977 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,8 +5,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] +#![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(iterator_try_collect)] diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 7c58cd7303ebc..8e6376b22ce61 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -916,9 +916,10 @@ impl, X: Cx> SearchGraph { /// heads from the stack. This may not necessarily mean that we've actually /// reached a fixpoint for that cycle head, which impacts the way we rebase /// provisional cache entries. -#[derive(Debug)] -enum RebaseReason { +#[derive_where(Debug; X: Cx)] +enum RebaseReason { NoCycleUsages, + Ambiguity(X::AmbiguityInfo), Overflow, /// We've actually reached a fixpoint. /// @@ -955,7 +956,7 @@ impl, X: Cx> SearchGraph { &mut self, cx: X, stack_entry: &StackEntry, - rebase_reason: RebaseReason, + rebase_reason: RebaseReason, ) { let popped_head_index = self.stack.next_index(); #[allow(rustc::potential_query_instability)] @@ -1034,6 +1035,9 @@ impl, X: Cx> SearchGraph { // is not actually equal to the final provisional result. We // need to discard the provisional cache entry in this case. RebaseReason::NoCycleUsages => return false, + RebaseReason::Ambiguity(info) => { + *result = D::propagate_ambiguity(cx, input, info); + } RebaseReason::Overflow => *result = D::fixpoint_overflow_result(cx, input), RebaseReason::ReachedFixpoint(None) => {} RebaseReason::ReachedFixpoint(Some(path_kind)) => { @@ -1348,6 +1352,27 @@ impl, X: Cx> SearchGraph { return EvaluationResult::finalize(stack_entry, encountered_overflow, result); } + // If computing this goal results in ambiguity with no constraints, + // we do not rerun it. It's incredibly difficult to get a different + // response in the next iteration in this case. These changes would + // likely either be caused by incompleteness or can change the maybe + // cause from ambiguity to overflow. Returning ambiguity always + // preserves soundness and completeness even if the goal is be known + // to succeed or fail. + // + // This prevents exponential blowup affecting multiple major crates. + // As we only get to this branch if we haven't yet reached a fixpoint, + // we also taint all provisional cache entries which depend on the + // current goal. + if let Some(info) = D::is_ambiguous_result(result) { + self.rebase_provisional_cache_entries( + cx, + &stack_entry, + RebaseReason::Ambiguity(info), + ); + return EvaluationResult::finalize(stack_entry, encountered_overflow, result); + }; + // If we've reached the fixpoint step limit, we bail with overflow and taint all // provisional cache entries which depend on the current goal. i += 1; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 73e93657b02f7..2e4b3e1e6300a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -89,6 +89,7 @@ #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(ascii_char)] +#![feature(assert_matches)] #![feature(async_fn_traits)] #![feature(async_iterator)] #![feature(bstr)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index e09d8495fdeac..4fbbf23116a5f 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -16,6 +16,7 @@ // tidy-alphabetical-start #![feature(allocator_api)] #![feature(array_into_iter_constructors)] +#![feature(assert_matches)] #![feature(char_internals)] #![feature(const_alloc_error)] #![feature(const_cmp)] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 60b26126cf6be..52f5a5382c90d 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -4,6 +4,7 @@ #![feature(const_heap)] #![feature(deque_extend_front)] #![feature(iter_array_chunks)] +#![feature(assert_matches)] #![feature(cow_is_borrowed)] #![feature(core_intrinsics)] #![feature(downcast_unchecked)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index fc9d314c7d057..c95f3cacbda2c 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -205,7 +205,7 @@ use prelude::rust_2024::*; #[macro_use] mod macros; -#[stable(feature = "assert_matches", since = "1.95.0")] +#[unstable(feature = "assert_matches", issue = "82775")] pub use crate::macros::{assert_matches, debug_assert_matches}; #[unstable(feature = "derive_from", issue = "144889")] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 49e1acd0b90fb..c2d714d2b7877 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -147,6 +147,8 @@ macro_rules! assert_ne { /// # Examples /// /// ``` +/// #![feature(assert_matches)] +/// /// use std::assert_matches; /// /// let a = Some(345); @@ -164,7 +166,7 @@ macro_rules! assert_ne { /// assert_matches!(a, Some(x) if x > 100); /// // assert_matches!(a, Some(x) if x < 100); // panics /// ``` -#[stable(feature = "assert_matches", since = "1.95.0")] +#[unstable(feature = "assert_matches", issue = "82775")] #[allow_internal_unstable(panic_internals)] #[rustc_macro_transparency = "semiopaque"] pub macro assert_matches { @@ -374,6 +376,8 @@ macro_rules! debug_assert_ne { /// # Examples /// /// ``` +/// #![feature(assert_matches)] +/// /// use std::debug_assert_matches; /// /// let a = Some(345); @@ -391,7 +395,7 @@ macro_rules! debug_assert_ne { /// debug_assert_matches!(a, Some(x) if x > 100); /// // debug_assert_matches!(a, Some(x) if x < 100); // panics /// ``` -#[stable(feature = "assert_matches", since = "1.95.0")] +#[unstable(feature = "assert_matches", issue = "82775")] #[allow_internal_unstable(assert_matches)] #[rustc_macro_transparency = "semiopaque"] pub macro debug_assert_matches($($arg:tt)*) { diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 7a344d358fdb8..7c96073a71331 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -45,10 +45,9 @@ use crate::iter::Step; use crate::ops::Bound::{self, Excluded, Included, Unbounded}; use crate::ops::{IntoBounds, RangeBounds}; -/// A (half-open) range bounded inclusively below and exclusively above -/// (`start..end` in a future edition). +/// A (half-open) range bounded inclusively below and exclusively above. /// -/// The range `start..end` contains all values with `start <= x < end`. +/// The `Range` contains all values with `start <= x < end`. /// It is empty if `start >= end`. /// /// # Examples @@ -60,6 +59,11 @@ use crate::ops::{IntoBounds, RangeBounds}; /// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum()); /// ``` +/// +/// # Edition notes +/// +/// It is planned that the syntax `start..end` will construct this +/// type in a future edition, but it does not do so today. #[lang = "RangeCopy"] #[derive(Copy, Hash)] #[derive_const(Clone, Default, PartialEq, Eq)] @@ -228,21 +232,24 @@ impl const From> for Range { } } -/// A range bounded inclusively below and above (`start..=last`). +/// A range bounded inclusively below and above. /// -/// The `RangeInclusive` `start..=last` contains all values with `x >= start` +/// The `RangeInclusive` contains all values with `x >= start` /// and `x <= last`. It is empty unless `start <= last`. /// /// # Examples /// -/// The `start..=last` syntax is a `RangeInclusive`: -/// /// ``` /// use core::range::RangeInclusive; /// /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last: 5 }); /// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum()); /// ``` +/// +/// # Edition notes +/// +/// It is planned that the syntax `start..=last` will construct this +/// type in a future edition, but it does not do so today. #[lang = "RangeInclusiveCopy"] #[derive(Clone, Copy, PartialEq, Eq, Hash)] #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] @@ -412,9 +419,9 @@ impl const From> for RangeInclusive { } } -/// A range only bounded inclusively below (`start..`). +/// A range only bounded inclusively below. /// -/// The `RangeFrom` `start..` contains all values with `x >= start`. +/// The `RangeFrom` contains all values with `x >= start`. /// /// *Note*: Overflow in the [`Iterator`] implementation (when the contained /// data type reaches its numerical limit) is allowed to panic, wrap, or @@ -429,8 +436,6 @@ impl const From> for RangeInclusive { /// /// # Examples /// -/// The `start..` syntax is a `RangeFrom`: -/// /// ``` /// #![feature(new_range_api)] /// use core::range::RangeFrom; @@ -438,6 +443,11 @@ impl const From> for RangeInclusive { /// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 }); /// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum()); /// ``` +/// +/// # Edition notes +/// +/// It is planned that the syntax `start..` will construct this +/// type in a future edition, but it does not do so today. #[lang = "RangeFromCopy"] #[derive(Copy, Hash)] #[derive_const(Clone, PartialEq, Eq)] @@ -563,15 +573,13 @@ impl const From> for RangeFrom { } } -/// A range only bounded inclusively above (`..=last`). +/// A range only bounded inclusively above. /// -/// The `RangeToInclusive` `..=last` contains all values with `x <= last`. +/// The `RangeToInclusive` contains all values with `x <= last`. /// It cannot serve as an [`Iterator`] because it doesn't have a starting point. /// /// # Examples /// -/// The `..=last` syntax is a `RangeToInclusive`: -/// /// ``` /// #![feature(new_range_api)] /// #![feature(new_range)] @@ -603,6 +611,11 @@ impl const From> for RangeFrom { /// ``` /// /// [slicing index]: crate::slice::SliceIndex +/// +/// # Edition notes +/// +/// It is planned that the syntax `..=last` will construct this +/// type in a future edition, but it does not do so today. #[lang = "RangeToInclusiveCopy"] #[doc(alias = "..=")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 629d9f8adab3c..b3425e4969ac0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -393,6 +393,7 @@ // // Only for re-exporting: // tidy-alphabetical-start +#![feature(assert_matches)] #![feature(async_iterator)] #![feature(c_variadic)] #![feature(cfg_accessible)] @@ -468,9 +469,7 @@ extern crate std as realstd; // The standard macros that are not built-in to the compiler. #[macro_use] -#[doc(hidden)] -#[unstable(feature = "std_internals", issue = "none")] -pub mod macros; +mod macros; // The runtime entry point and a few unstable public functions used by the // compiler @@ -724,7 +723,7 @@ pub use core::{ assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, r#try, unimplemented, unreachable, write, writeln, }; -#[stable(feature = "assert_matches", since = "1.95.0")] +#[unstable(feature = "assert_matches", issue = "82775")] pub use core::{assert_matches, debug_assert_matches}; // Re-export unstable derive macro defined through core. diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 5f9b383c2da37..25e2b7ea13703 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -5,9 +5,6 @@ //! library. // ignore-tidy-dbg -#[cfg(test)] -mod tests; - #[doc = include_str!("../../core/src/macros/panic.md")] #[macro_export] #[rustc_builtin_macro(std_panic)] @@ -350,71 +347,35 @@ macro_rules! eprintln { /// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html /// [`log`]: https://crates.io/crates/log #[macro_export] -#[allow_internal_unstable(std_internals)] #[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")] #[stable(feature = "dbg_macro", since = "1.32.0")] macro_rules! dbg { + // NOTE: We cannot use `concat!` to make a static string as a format argument + // of `eprintln!` because `file!` could contain a `{` or + // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` + // will be malformed. () => { $crate::eprintln!("[{}:{}:{}]", $crate::file!(), $crate::line!(), $crate::column!()) }; - ($($val:expr),+ $(,)?) => { - $crate::macros::dbg_internal!(() () ($($val),+)) - }; -} - -/// Internal macro that processes a list of expressions, binds their results -/// with `match`, calls `eprint!` with the collected information, and returns -/// all the evaluated expressions in a tuple. -/// -/// E.g. `dbg_internal!(() () (1, 2))` expands into -/// ```rust, ignore -/// match (1, 2) { -/// (tmp_1, tmp_2) => { -/// eprint!("...", &tmp_1, &tmp_2, /* some other arguments */); -/// (tmp_1, tmp_2) -/// } -/// } -/// ``` -/// -/// This is necessary so that `dbg!` outputs don't get torn, see #136703. -#[doc(hidden)] -#[rustc_macro_transparency = "semiopaque"] -pub macro dbg_internal { - (($($piece:literal),+) ($($processed:expr => $bound:ident),+) ()) => { + ($val:expr $(,)?) => { // Use of `match` here is intentional because it affects the lifetimes // of temporaries - https://stackoverflow.com/a/48732525/1063961 - // Always put the arguments in a tuple to avoid an unused parens lint on the pattern. - match ($($processed,)+) { - ($($bound,)+) => { - $crate::eprint!( - $crate::concat!($($piece),+), - $( - $crate::stringify!($processed), - // The `&T: Debug` check happens here (not in the format literal desugaring) - // to avoid format literal related messages and suggestions. - &&$bound as &dyn $crate::fmt::Debug - ),+, - // The location returned here is that of the macro invocation, so - // it will be the same for all expressions. Thus, label these - // arguments so that they can be reused in every piece of the - // formatting template. - file=$crate::file!(), - line=$crate::line!(), - column=$crate::column!() + match $val { + tmp => { + $crate::eprintln!("[{}:{}:{}] {} = {:#?}", + $crate::file!(), + $crate::line!(), + $crate::column!(), + $crate::stringify!($val), + // The `&T: Debug` check happens here (not in the format literal desugaring) + // to avoid format literal related messages and suggestions. + &&tmp as &dyn $crate::fmt::Debug, ); - // Comma separate the variables only when necessary so that this will - // not yield a tuple for a single expression, but rather just parenthesize - // the expression. - ($($bound),+) - + tmp } } - }, - (($($piece:literal),*) ($($processed:expr => $bound:ident),*) ($val:expr $(,$rest:expr)*)) => { - $crate::macros::dbg_internal!( - ($($piece,)* "[{file}:{line}:{column}] {} = {:#?}\n") - ($($processed => $bound,)* $val => tmp) - ($($rest),*) - ) - }, + }; + ($($val:expr),+ $(,)?) => { + ($($crate::dbg!($val)),+,) + }; } diff --git a/library/std/src/macros/tests.rs b/library/std/src/macros/tests.rs deleted file mode 100644 index db2be925ff30a..0000000000000 --- a/library/std/src/macros/tests.rs +++ /dev/null @@ -1,13 +0,0 @@ -// ignore-tidy-dbg - -/// Test for : -/// `dbg!` shouldn't drop arguments' temporaries. -#[test] -fn no_dropping_temps() { - fn temp() {} - - *dbg!(&temp()); - *dbg!(&temp(), 1).0; - *dbg!(0, &temp()).1; - *dbg!(0, &temp(), 2).1; -} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 541ab3d1c295e..4258073e61047 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(if_let_guard))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/", @@ -7,6 +6,7 @@ )] #![feature(ascii_char)] #![feature(ascii_char_variants)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(formatting_options)] diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs index aed9b875fd093..8d86a9f346314 100644 --- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs +++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs @@ -92,26 +92,33 @@ impl LateLintPass<'_> for DbgMacro { (macro_call.span, String::from("()")) } }, - ExprKind::Match(args, _, _) => { - let suggestion = match args.kind { - // dbg!(1) => 1 - ExprKind::Tup([val]) => { - snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability) - .to_string() + // dbg!(1) + ExprKind::Match(val, ..) => ( + macro_call.span, + snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability) + .to_string(), + ), + // dbg!(2, 3) + ExprKind::Tup( + [ + Expr { + kind: ExprKind::Match(first, ..), + .. }, - // dbg!(2, 3) => (2, 3) - ExprKind::Tup([first, .., last]) => { - let snippet = snippet_with_applicability( - cx, - first.span.source_callsite().to(last.span.source_callsite()), - "..", - &mut applicability, - ); - format!("({snippet})") + .., + Expr { + kind: ExprKind::Match(last, ..), + .. }, - _ => unreachable!(), - }; - (macro_call.span, suggestion) + ], + ) => { + let snippet = snippet_with_applicability( + cx, + first.span.source_callsite().to(last.span.source_callsite()), + "..", + &mut applicability, + ); + (macro_call.span, format!("({snippet})")) }, _ => unreachable!(), }; diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 5b0de80e67fd7..a8312a04f36f8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExpr, PatExprKind, PatKind, RangeEnd}; use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::ty; +use rustc_middle::ty::{self, TypeckResults}; use rustc_span::{ByteSymbol, ErrorGuaranteed, Span, Symbol}; use super::MATCH_SAME_ARMS; @@ -61,7 +61,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { let check_eq_with_pat = |expr_a: &Expr<'_>, expr_b: &Expr<'_>| { let mut local_map: HirIdMap = HirIdMap::default(); - let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| { + let eq_fallback = |a_typeck_results: &TypeckResults<'tcx>, + a: &Expr<'_>, + b_typeck_results: &TypeckResults<'tcx>, + b: &Expr<'_>| { if let Some(a_id) = a.res_local_id() && let Some(b_id) = b.res_local_id() && let entry = match local_map.entry(a_id) { @@ -71,7 +74,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { } // the names technically don't have to match; this makes the lint more conservative && cx.tcx.hir_name(a_id) == cx.tcx.hir_name(b_id) - && cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b) + && a_typeck_results.expr_ty(a) == b_typeck_results.expr_ty(b) && pat_contains_local(lhs.pat, a_id) && pat_contains_local(rhs.pat, b_id) { diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs index 7b10c37de42df..d2e593fc17df8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp}; use rustc_lint::LateContext; +use rustc_middle::ty::TypeckResults; use rustc_middle::ty::adjustment::Adjust; use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol}; @@ -136,7 +137,9 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // .map(|y| y[.acceptable_method()].unwrap()) && let simple_equal = (receiver.res_local_id() == Some(filter_param_id) && map_arg_peeled.res_local_id() == Some(map_param_id)) - && let eq_fallback = (|a: &Expr<'_>, b: &Expr<'_>| { + && let eq_fallback = + (|a_typeck_results: &TypeckResults<'tcx>, a: &Expr<'_>, + b_typeck_results: &TypeckResults<'tcx>, b: &Expr<'_>| { // in `filter(|x| ..)`, replace `*x` with `x` let a_path = if !is_filter_param_ref && let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind @@ -144,7 +147,7 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // let the filter closure arg and the map closure arg be equal a_path.res_local_id() == Some(filter_param_id) && b.res_local_id() == Some(map_param_id) - && cx.typeck_results().expr_ty_adjusted(a) == cx.typeck_results().expr_ty_adjusted(b) + && a_typeck_results.expr_ty_adjusted(a) == b_typeck_results.expr_ty_adjusted(b) }) && (simple_equal || SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(receiver, map_arg_peeled)) diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 74db7ae03ba0b..994ad446593af 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4761,6 +4761,8 @@ pub struct Methods { allowed_dotfiles: FxHashSet<&'static str>, format_args: FormatArgsStorage, allow_unwrap_types: Vec, + unwrap_allowed_ids: FxHashSet, + unwrap_allowed_aliases: Vec, } impl Methods { @@ -4778,6 +4780,8 @@ impl Methods { allowed_dotfiles, format_args, allow_unwrap_types: conf.allow_unwrap_types.clone(), + unwrap_allowed_ids: FxHashSet::default(), + unwrap_allowed_aliases: Vec::new(), } } } @@ -4953,6 +4957,19 @@ pub fn method_call<'tcx>(recv: &'tcx Expr<'tcx>) -> Option<(Symbol, &'tcx Expr<' } impl<'tcx> LateLintPass<'tcx> for Methods { + fn check_crate(&mut self, cx: &LateContext<'tcx>) { + for s in &self.allow_unwrap_types { + let def_ids = clippy_utils::paths::lookup_path_str(cx.tcx, clippy_utils::paths::PathNS::Type, s); + for def_id in def_ids { + if cx.tcx.def_kind(def_id) == rustc_hir::def::DefKind::TyAlias { + self.unwrap_allowed_aliases.push(def_id); + } else { + self.unwrap_allowed_ids.insert(def_id); + } + } + } + } + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { return; @@ -4976,7 +4993,8 @@ impl<'tcx> LateLintPass<'tcx> for Methods { self.allow_expect_in_tests, self.allow_unwrap_in_consts, self.allow_expect_in_consts, - &self.allow_unwrap_types, + &self.unwrap_allowed_ids, + &self.unwrap_allowed_aliases, ); }, ExprKind::MethodCall(..) => { @@ -5730,7 +5748,8 @@ impl Methods { false, self.allow_expect_in_consts, self.allow_expect_in_tests, - &self.allow_unwrap_types, + &self.unwrap_allowed_ids, + &self.unwrap_allowed_aliases, unwrap_expect_used::Variant::Expect, ); expect_fun_call::check(cx, &self.format_args, expr, method_span, recv, arg); @@ -5743,7 +5762,8 @@ impl Methods { true, self.allow_expect_in_consts, self.allow_expect_in_tests, - &self.allow_unwrap_types, + &self.unwrap_allowed_ids, + &self.unwrap_allowed_aliases, unwrap_expect_used::Variant::Expect, ); }, @@ -5764,7 +5784,8 @@ impl Methods { false, self.allow_unwrap_in_consts, self.allow_unwrap_in_tests, - &self.allow_unwrap_types, + &self.unwrap_allowed_ids, + &self.unwrap_allowed_aliases, unwrap_expect_used::Variant::Unwrap, ); }, @@ -5776,7 +5797,8 @@ impl Methods { true, self.allow_unwrap_in_consts, self.allow_unwrap_in_tests, - &self.allow_unwrap_types, + &self.unwrap_allowed_ids, + &self.unwrap_allowed_aliases, unwrap_expect_used::Variant::Unwrap, ); }, diff --git a/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs b/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs index 6d8777cbc23f8..c07c932176462 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs @@ -44,7 +44,8 @@ pub(super) fn check( is_err: bool, allow_unwrap_in_consts: bool, allow_unwrap_in_tests: bool, - allow_unwrap_types: &[String], + unwrap_allowed_ids: &rustc_data_structures::fx::FxHashSet, + unwrap_allowed_aliases: &[rustc_hir::def_id::DefId], variant: Variant, ) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); @@ -66,51 +67,39 @@ pub(super) fn check( let method_suffix = if is_err { "_err" } else { "" }; - let ty_name = ty.to_string(); - if allow_unwrap_types - .iter() - .any(|allowed_type| ty_name.starts_with(allowed_type) || ty_name == *allowed_type) + if let ty::Adt(adt, _) = ty.kind() + && unwrap_allowed_ids.contains(&adt.did()) { return; } - for s in allow_unwrap_types { - let def_ids = clippy_utils::paths::lookup_path_str(cx.tcx, clippy_utils::paths::PathNS::Type, s); - for def_id in def_ids { - if let ty::Adt(adt, _) = ty.kind() - && adt.did() == def_id - { - return; - } - if cx.tcx.def_kind(def_id) == DefKind::TyAlias { - let alias_ty = cx.tcx.type_of(def_id).instantiate_identity(); - if let (ty::Adt(adt, substs), ty::Adt(alias_adt, alias_substs)) = (ty.kind(), alias_ty.kind()) - && adt.did() == alias_adt.did() - { - let mut all_match = true; - for (arg, alias_arg) in substs.iter().zip(alias_substs.iter()) { - if let (Some(arg_ty), Some(alias_arg_ty)) = (arg.as_type(), alias_arg.as_type()) { - if matches!(alias_arg_ty.kind(), ty::Param(_)) { - continue; - } - if let (ty::Adt(arg_adt, _), ty::Adt(alias_arg_adt, _)) = - (arg_ty.peel_refs().kind(), alias_arg_ty.peel_refs().kind()) - { - if arg_adt.did() != alias_arg_adt.did() { - all_match = false; - break; - } - } else if arg_ty != alias_arg_ty { - all_match = false; - break; - } - } + for &def_id in unwrap_allowed_aliases { + let alias_ty = cx.tcx.type_of(def_id).instantiate_identity(); + if let (ty::Adt(adt, substs), ty::Adt(alias_adt, alias_substs)) = (ty.kind(), alias_ty.kind()) + && adt.did() == alias_adt.did() + { + let mut all_match = true; + for (arg, alias_arg) in substs.iter().zip(alias_substs.iter()) { + if let (Some(arg_ty), Some(alias_arg_ty)) = (arg.as_type(), alias_arg.as_type()) { + if matches!(alias_arg_ty.kind(), ty::Param(_)) { + continue; } - if all_match { - return; + if let (ty::Adt(arg_adt, _), ty::Adt(alias_arg_adt, _)) = + (arg_ty.peel_refs().kind(), alias_arg_ty.peel_refs().kind()) + { + if arg_adt.did() != alias_arg_adt.did() { + all_match = false; + break; + } + } else if arg_ty != alias_arg_ty { + all_match = false; + break; } } } + if all_match { + return; + } } } @@ -149,7 +138,8 @@ pub(super) fn check_call( allow_unwrap_in_tests: bool, allow_expect_in_consts: bool, allow_expect_in_tests: bool, - allow_unwrap_types: &[String], + unwrap_allowed_ids: &rustc_data_structures::fx::FxHashSet, + unwrap_allowed_aliases: &[rustc_hir::def_id::DefId], ) { let Some(recv) = args.first() else { return; @@ -167,7 +157,8 @@ pub(super) fn check_call( false, allow_unwrap_in_consts, allow_unwrap_in_tests, - allow_unwrap_types, + unwrap_allowed_ids, + unwrap_allowed_aliases, Variant::Unwrap, ); }, @@ -179,7 +170,8 @@ pub(super) fn check_call( false, allow_expect_in_consts, allow_expect_in_tests, - allow_unwrap_types, + unwrap_allowed_ids, + unwrap_allowed_aliases, Variant::Expect, ); }, @@ -191,7 +183,8 @@ pub(super) fn check_call( true, allow_unwrap_in_consts, allow_unwrap_in_tests, - allow_unwrap_types, + unwrap_allowed_ids, + unwrap_allowed_aliases, Variant::Unwrap, ); }, @@ -203,7 +196,8 @@ pub(super) fn check_call( true, allow_expect_in_consts, allow_expect_in_tests, - allow_unwrap_types, + unwrap_allowed_ids, + unwrap_allowed_aliases, Variant::Expect, ); }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 3ff40f2fb722b..1018b1eb37b0d 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -26,7 +26,8 @@ use std::slice; /// Callback that is called when two expressions are not equal in the sense of `SpanlessEq`, but /// other conditions would make them equal. -type SpanlessEqCallback<'a> = dyn FnMut(&Expr<'_>, &Expr<'_>) -> bool + 'a; +type SpanlessEqCallback<'a, 'tcx> = + dyn FnMut(&TypeckResults<'tcx>, &Expr<'_>, &TypeckResults<'tcx>, &Expr<'_>) -> bool + 'a; /// Determines how paths are hashed and compared for equality. #[derive(Copy, Clone, Debug, Default)] @@ -59,7 +60,7 @@ pub struct SpanlessEq<'a, 'tcx> { cx: &'a LateContext<'tcx>, maybe_typeck_results: Option<(&'tcx TypeckResults<'tcx>, &'tcx TypeckResults<'tcx>)>, allow_side_effects: bool, - expr_fallback: Option>>, + expr_fallback: Option>>, path_check: PathCheck, } @@ -94,7 +95,10 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { } #[must_use] - pub fn expr_fallback(self, expr_fallback: impl FnMut(&Expr<'_>, &Expr<'_>) -> bool + 'a) -> Self { + pub fn expr_fallback( + self, + expr_fallback: impl FnMut(&TypeckResults<'tcx>, &Expr<'_>, &TypeckResults<'tcx>, &Expr<'_>) -> bool + 'a, + ) -> Self { Self { expr_fallback: Some(Box::new(expr_fallback)), ..self @@ -505,7 +509,7 @@ impl HirEqInterExpr<'_, '_, '_> { (ExprKind::Block(l, _), ExprKind::Block(r, _)) => self.eq_block(l, r), (ExprKind::Binary(l_op, ll, lr), ExprKind::Binary(r_op, rl, rr)) => { l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) - || swap_binop(self.inner.cx, l_op.node, ll, lr).is_some_and(|(l_op, ll, lr)| { + || self.swap_binop(l_op.node, ll, lr).is_some_and(|(l_op, ll, lr)| { l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) }) }, @@ -639,7 +643,15 @@ impl HirEqInterExpr<'_, '_, '_> { ) => false, }; (is_eq && (!self.should_ignore(left) || !self.should_ignore(right))) - || self.inner.expr_fallback.as_mut().is_some_and(|f| f(left, right)) + || self + .inner + .maybe_typeck_results + .is_some_and(|(left_typeck_results, right_typeck_results)| { + self.inner + .expr_fallback + .as_mut() + .is_some_and(|f| f(left_typeck_results, left, right_typeck_results, right)) + }) } fn eq_exprs(&mut self, left: &[Expr<'_>], right: &[Expr<'_>]) -> bool { @@ -921,6 +933,40 @@ impl HirEqInterExpr<'_, '_, '_> { self.right_ctxt = right; true } + + fn swap_binop<'a>( + &self, + binop: BinOpKind, + lhs: &'a Expr<'a>, + rhs: &'a Expr<'a>, + ) -> Option<(BinOpKind, &'a Expr<'a>, &'a Expr<'a>)> { + match binop { + // `==` and `!=`, are commutative + BinOpKind::Eq | BinOpKind::Ne => Some((binop, rhs, lhs)), + // Comparisons can be reversed + BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)), + BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)), + BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)), + BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)), + // Non-commutative operators + BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Rem | BinOpKind::Sub | BinOpKind::Div => None, + // We know that those operators are commutative for primitive types, + // and we don't assume anything for other types + BinOpKind::Mul + | BinOpKind::Add + | BinOpKind::And + | BinOpKind::Or + | BinOpKind::BitAnd + | BinOpKind::BitXor + | BinOpKind::BitOr => self.inner.maybe_typeck_results.and_then(|(typeck_lhs, _)| { + typeck_lhs + .expr_ty_adjusted(lhs) + .peel_refs() + .is_primitive() + .then_some((binop, rhs, lhs)) + }), + } + } } /// Some simple reductions like `{ return }` => `return` @@ -966,39 +1012,6 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &' } } -fn swap_binop<'a>( - cx: &LateContext<'_>, - binop: BinOpKind, - lhs: &'a Expr<'a>, - rhs: &'a Expr<'a>, -) -> Option<(BinOpKind, &'a Expr<'a>, &'a Expr<'a>)> { - match binop { - // `==` and `!=`, are commutative - BinOpKind::Eq | BinOpKind::Ne => Some((binop, rhs, lhs)), - // Comparisons can be reversed - BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)), - BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)), - BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)), - BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)), - // Non-commutative operators - BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Rem | BinOpKind::Sub | BinOpKind::Div => None, - // We know that those operators are commutative for primitive types, - // and we don't assume anything for other types - BinOpKind::Mul - | BinOpKind::Add - | BinOpKind::And - | BinOpKind::Or - | BinOpKind::BitAnd - | BinOpKind::BitXor - | BinOpKind::BitOr => cx - .typeck_results() - .expr_ty_adjusted(lhs) - .peel_refs() - .is_primitive() - .then_some((binop, rhs, lhs)), - } -} - /// Checks if the two `Option`s are both `None` or some equal values as per /// `eq_fn`. pub fn both(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index f2f8cd583f31f..9f7f3e89cbe25 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -3,7 +3,7 @@ #![feature(macro_metavar_expr)] #![feature(never_type)] #![feature(rustc_private)] -#![cfg_attr(bootstrap, feature(assert_matches))] +#![feature(assert_matches)] #![feature(unwrap_infallible)] #![recursion_limit = "512"] #![allow(clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::must_use_candidate)] diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs index a7171cff66f90..250e73afd4f00 100644 --- a/src/tools/clippy/clippy_utils/src/sym.rs +++ b/src/tools/clippy/clippy_utils/src/sym.rs @@ -199,6 +199,7 @@ generate! { cx, cycle, cyclomatic_complexity, + dbg_macro, de, debug_struct, deprecated_in_future, diff --git a/src/tools/clippy/tests/ui/if_same_then_else.rs b/src/tools/clippy/tests/ui/if_same_then_else.rs index 6e0e2c5ea7202..6982a9d143e4c 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else.rs +++ b/src/tools/clippy/tests/ui/if_same_then_else.rs @@ -305,3 +305,20 @@ fn issue16416_prim(x: bool, a: u32, b: u32) { //~v if_same_then_else _ = if x { a >= b } else { b <= a }; } + +mod issue16505 { + macro_rules! foo { + (< $hi:literal : $lo:literal > | $N:tt bits) => {{ + const NEW_N_: usize = $hi - $lo + 1; + NEW_N_ + }}; + } + + fn bar(x: bool) { + _ = if x { + foo!(<2:0> | 3 bits) == foo!(<3:1> | 3 bits) + } else { + foo!(<3:1> | 3 bits) == foo!(<2:0> | 3 bits) + }; + } +} diff --git a/src/tools/clippy/tests/ui/match_same_arms.fixed b/src/tools/clippy/tests/ui/match_same_arms.fixed index 31684a5759fe9..8b16fd3193f5f 100644 --- a/src/tools/clippy/tests/ui/match_same_arms.fixed +++ b/src/tools/clippy/tests/ui/match_same_arms.fixed @@ -140,3 +140,19 @@ fn main() { _ => false, }; } + +fn issue16678() { + // ICE in Rust 1.94.0 + match true { + true => { + fn wrapper(_arg: ()) { + _arg; + } + }, + false => { + fn wrapper(_arg: ()) { + _arg; + } + }, + } +} diff --git a/src/tools/clippy/tests/ui/match_same_arms.rs b/src/tools/clippy/tests/ui/match_same_arms.rs index 39bee01bac22b..3b2d585c579d3 100644 --- a/src/tools/clippy/tests/ui/match_same_arms.rs +++ b/src/tools/clippy/tests/ui/match_same_arms.rs @@ -149,3 +149,19 @@ fn main() { _ => false, }; } + +fn issue16678() { + // ICE in Rust 1.94.0 + match true { + true => { + fn wrapper(_arg: ()) { + _arg; + } + }, + false => { + fn wrapper(_arg: ()) { + _arg; + } + }, + } +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr index 4f06a1afa50fe..afc2cb214842e 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr @@ -2,7 +2,7 @@ error: Undefined Behavior: memory access failed: ALLOC has been freed, so this p --> tests/fail/dangling_pointers/dangling_primitive.rs:LL:CC | LL | dbg!(*ptr); - | ^^^^ Undefined Behavior occurred here + | ^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr index 88d5694c4736d..364a4b4a74418 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr @@ -7,7 +7,7 @@ error: Undefined Behavior: reading memory at ALLOC[0x0..0x4], but memory is unin --> tests/fail/function_calls/return_pointer_on_unwind.rs:LL:CC | LL | dbg!(x.0); - | ^^^ Undefined Behavior occurred here + | ^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/crashes/137187.rs b/tests/crashes/137187.rs index 554275441ff0e..f63b459de9d03 100644 --- a/tests/crashes/137187.rs +++ b/tests/crashes/137187.rs @@ -1,13 +1,10 @@ //@ known-bug: #137187 -#![feature(const_trait_impl, const_ops)] - use std::ops::Add; + const trait A where - *const Self: const Add, + *const Self: Add, { fn b(c: *const Self) -> <*const Self as Add>::Output { c + c } } - -fn main() {} diff --git a/tests/ui-fulldeps/rustc_public/check_abi.rs b/tests/ui-fulldeps/rustc_public/check_abi.rs index 8e97b773db567..256e267b7d303 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi.rs @@ -6,6 +6,7 @@ //@ ignore-remote #![feature(rustc_private)] +#![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] extern crate rustc_driver; diff --git a/tests/ui-fulldeps/rustc_public/check_allocation.rs b/tests/ui-fulldeps/rustc_public/check_allocation.rs index 580ce98329dc7..1acddc74cc0fd 100644 --- a/tests/ui-fulldeps/rustc_public/check_allocation.rs +++ b/tests/ui-fulldeps/rustc_public/check_allocation.rs @@ -8,6 +8,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; diff --git a/tests/ui-fulldeps/rustc_public/check_assoc_items.rs b/tests/ui-fulldeps/rustc_public/check_assoc_items.rs index ee0efd083588a..194d6be88a764 100644 --- a/tests/ui-fulldeps/rustc_public/check_assoc_items.rs +++ b/tests/ui-fulldeps/rustc_public/check_assoc_items.rs @@ -8,6 +8,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs b/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs index f988452fd52ba..75f4f1f5bf4c0 100644 --- a/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs +++ b/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs @@ -7,6 +7,7 @@ //@ edition: 2024 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_crate_defs.rs b/tests/ui-fulldeps/rustc_public/check_crate_defs.rs index 2b6a2ff8199ce..7d949eae39106 100644 --- a/tests/ui-fulldeps/rustc_public/check_crate_defs.rs +++ b/tests/ui-fulldeps/rustc_public/check_crate_defs.rs @@ -6,6 +6,7 @@ //@ ignore-remote #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_hir; extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_def_ty.rs b/tests/ui-fulldeps/rustc_public/check_def_ty.rs index 19ea731834b70..5984d6f8821a9 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_ty.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_ty.rs @@ -8,6 +8,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_defs.rs b/tests/ui-fulldeps/rustc_public/check_defs.rs index f3e27cdeb6043..0d472e156b40f 100644 --- a/tests/ui-fulldeps/rustc_public/check_defs.rs +++ b/tests/ui-fulldeps/rustc_public/check_defs.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_foreign.rs b/tests/ui-fulldeps/rustc_public/check_foreign.rs index 4670fd409b8f0..ea6d6585e51ec 100644 --- a/tests/ui-fulldeps/rustc_public/check_foreign.rs +++ b/tests/ui-fulldeps/rustc_public/check_foreign.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_instance.rs b/tests/ui-fulldeps/rustc_public/check_instance.rs index defea9d2f54bb..fd7523963fa9b 100644 --- a/tests/ui-fulldeps/rustc_public/check_instance.rs +++ b/tests/ui-fulldeps/rustc_public/check_instance.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_intrinsics.rs b/tests/ui-fulldeps/rustc_public/check_intrinsics.rs index 0cbb9659182a5..e3538a39f3371 100644 --- a/tests/ui-fulldeps/rustc_public/check_intrinsics.rs +++ b/tests/ui-fulldeps/rustc_public/check_intrinsics.rs @@ -10,6 +10,7 @@ //@ ignore-remote #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; extern crate rustc_hir; diff --git a/tests/ui-fulldeps/rustc_public/check_item_kind.rs b/tests/ui-fulldeps/rustc_public/check_item_kind.rs index b75ac70d86e3c..c687b3af1c632 100644 --- a/tests/ui-fulldeps/rustc_public/check_item_kind.rs +++ b/tests/ui-fulldeps/rustc_public/check_item_kind.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_trait_queries.rs b/tests/ui-fulldeps/rustc_public/check_trait_queries.rs index 44b7275a3df60..5603add82f591 100644 --- a/tests/ui-fulldeps/rustc_public/check_trait_queries.rs +++ b/tests/ui-fulldeps/rustc_public/check_trait_queries.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_transform.rs b/tests/ui-fulldeps/rustc_public/check_transform.rs index f8aa40e474468..815dec57b8be3 100644 --- a/tests/ui-fulldeps/rustc_public/check_transform.rs +++ b/tests/ui-fulldeps/rustc_public/check_transform.rs @@ -6,6 +6,7 @@ //@ ignore-remote #![feature(rustc_private)] +#![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; diff --git a/tests/ui-fulldeps/rustc_public/check_ty_fold.rs b/tests/ui-fulldeps/rustc_public/check_ty_fold.rs index 9ac7f14570e57..93cd304934409 100644 --- a/tests/ui-fulldeps/rustc_public/check_ty_fold.rs +++ b/tests/ui-fulldeps/rustc_public/check_ty_fold.rs @@ -8,6 +8,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_variant.rs b/tests/ui-fulldeps/rustc_public/check_variant.rs index 54ae8b8f83b97..9bdd0c9d80ba4 100644 --- a/tests/ui-fulldeps/rustc_public/check_variant.rs +++ b/tests/ui-fulldeps/rustc_public/check_variant.rs @@ -8,6 +8,7 @@ //@ edition: 2024 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/closure-generic-body.rs b/tests/ui-fulldeps/rustc_public/closure-generic-body.rs index a328bc396c544..46aeca76ba650 100644 --- a/tests/ui-fulldeps/rustc_public/closure-generic-body.rs +++ b/tests/ui-fulldeps/rustc_public/closure-generic-body.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/closure_body.rs b/tests/ui-fulldeps/rustc_public/closure_body.rs index 880d7dde34b68..43cbca8baab87 100644 --- a/tests/ui-fulldeps/rustc_public/closure_body.rs +++ b/tests/ui-fulldeps/rustc_public/closure_body.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/compilation-result.rs b/tests/ui-fulldeps/rustc_public/compilation-result.rs index 351ca2c8295f4..d33e602e8191a 100644 --- a/tests/ui-fulldeps/rustc_public/compilation-result.rs +++ b/tests/ui-fulldeps/rustc_public/compilation-result.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/crate-info.rs b/tests/ui-fulldeps/rustc_public/crate-info.rs index 3729aa7609b51..9bf865c54eeef 100644 --- a/tests/ui-fulldeps/rustc_public/crate-info.rs +++ b/tests/ui-fulldeps/rustc_public/crate-info.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_hir; extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/projections.rs b/tests/ui-fulldeps/rustc_public/projections.rs index e864bb9648db5..53baace827a02 100644 --- a/tests/ui-fulldeps/rustc_public/projections.rs +++ b/tests/ui-fulldeps/rustc_public/projections.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_hir; extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/smir_internal.rs b/tests/ui-fulldeps/rustc_public/smir_internal.rs index 98335da19dbde..b74bdfe4eb194 100644 --- a/tests/ui-fulldeps/rustc_public/smir_internal.rs +++ b/tests/ui-fulldeps/rustc_public/smir_internal.rs @@ -8,6 +8,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_driver; extern crate rustc_interface; diff --git a/tests/ui-fulldeps/rustc_public/smir_serde.rs b/tests/ui-fulldeps/rustc_public/smir_serde.rs index 6a345023de171..972bc5efe206c 100644 --- a/tests/ui-fulldeps/rustc_public/smir_serde.rs +++ b/tests/ui-fulldeps/rustc_public/smir_serde.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_driver; diff --git a/tests/ui-fulldeps/rustc_public/smir_visitor.rs b/tests/ui-fulldeps/rustc_public/smir_visitor.rs index 1ea2ab6f560ff..9438f46a59b5a 100644 --- a/tests/ui-fulldeps/rustc_public/smir_visitor.rs +++ b/tests/ui-fulldeps/rustc_public/smir_visitor.rs @@ -7,6 +7,7 @@ //@ edition: 2021 #![feature(rustc_private)] +#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui/borrowck/dbg-issue-120327.rs b/tests/ui/borrowck/dbg-issue-120327.rs index 45605acc34334..2de43f634877a 100644 --- a/tests/ui/borrowck/dbg-issue-120327.rs +++ b/tests/ui/borrowck/dbg-issue-120327.rs @@ -1,44 +1,67 @@ -//! Diagnostic test for : suggest borrowing -//! variables passed to `dbg!` that are later used. -//@ dont-require-annotations: HELP - fn s() -> String { let a = String::new(); - dbg!(a); //~ HELP consider borrowing instead of transferring ownership + dbg!(a); return a; //~ ERROR use of moved value: } fn m() -> String { let a = String::new(); - dbg!(1, 2, a, 1, 2); //~ HELP consider borrowing instead of transferring ownership + dbg!(1, 2, a, 1, 2); return a; //~ ERROR use of moved value: } fn t(a: String) -> String { let b: String = "".to_string(); - dbg!(a, b); //~ HELP consider borrowing instead of transferring ownership + dbg!(a, b); return b; //~ ERROR use of moved value: } fn x(a: String) -> String { let b: String = "".to_string(); - dbg!(a, b); //~ HELP consider borrowing instead of transferring ownership + dbg!(a, b); return a; //~ ERROR use of moved value: } -fn two_of_them(a: String) -> String { - dbg!(a, a); //~ ERROR use of moved value - //~| HELP consider borrowing instead of transferring ownership - //~| HELP consider borrowing instead of transferring ownership - return a; //~ ERROR use of moved value +macro_rules! my_dbg { + () => { + eprintln!("[{}:{}:{}]", file!(), line!(), column!()) + }; + ($val:expr $(,)?) => { + match $val { + tmp => { + eprintln!("[{}:{}:{}] {} = {:#?}", + file!(), line!(), column!(), stringify!($val), &tmp); + tmp + } + } + }; + ($($val:expr),+ $(,)?) => { + ($(my_dbg!($val)),+,) + }; +} + +fn test_my_dbg() -> String { + let b: String = "".to_string(); + my_dbg!(b, 1); + return b; //~ ERROR use of moved value: +} + +fn test_not_macro() -> String { + let a = String::new(); + let _b = match a { + tmp => { + eprintln!("dbg: {}", tmp); + tmp + } + }; + return a; //~ ERROR use of moved value: } fn get_expr(_s: String) {} -// The suggestion is purely syntactic; applying it here will result in a type error. fn test() { let a: String = "".to_string(); - let _res = get_expr(dbg!(a)); //~ HELP consider borrowing instead of transferring ownership + let _res = get_expr(dbg!(a)); let _l = a.len(); //~ ERROR borrow of moved value } diff --git a/tests/ui/borrowck/dbg-issue-120327.stderr b/tests/ui/borrowck/dbg-issue-120327.stderr index e7a7151e541dd..efacc0c3f1341 100644 --- a/tests/ui/borrowck/dbg-issue-120327.stderr +++ b/tests/ui/borrowck/dbg-issue-120327.stderr @@ -1,133 +1,112 @@ error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:8:12 + --> $DIR/dbg-issue-120327.rs:4:12 | LL | let a = String::new(); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | dbg!(a); - | - value moved here + | ------- value moved here LL | return a; | ^ value used here after move | -help: consider cloning the value if the performance cost is acceptable - | -LL | dbg!(a.clone()); - | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(&a); | + error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:14:12 + --> $DIR/dbg-issue-120327.rs:10:12 | LL | let a = String::new(); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | dbg!(1, 2, a, 1, 2); - | - value moved here + | ------------------- value moved here LL | return a; | ^ value used here after move | -help: consider cloning the value if the performance cost is acceptable - | -LL | dbg!(1, 2, a.clone(), 1, 2); - | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(1, 2, &a, 1, 2); | + error[E0382]: use of moved value: `b` - --> $DIR/dbg-issue-120327.rs:20:12 + --> $DIR/dbg-issue-120327.rs:16:12 | LL | let b: String = "".to_string(); | - move occurs because `b` has type `String`, which does not implement the `Copy` trait LL | dbg!(a, b); - | - value moved here + | ---------- value moved here LL | return b; | ^ value used here after move | -help: consider cloning the value if the performance cost is acceptable - | -LL | dbg!(a, b.clone()); - | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(a, &b); | + error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:26:12 + --> $DIR/dbg-issue-120327.rs:22:12 | LL | fn x(a: String) -> String { | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | let b: String = "".to_string(); LL | dbg!(a, b); - | - value moved here + | ---------- value moved here LL | return a; | ^ value used here after move | -help: consider cloning the value if the performance cost is acceptable - | -LL | dbg!(a.clone(), b); - | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(&a, b); | + -error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:30:13 - | -LL | fn two_of_them(a: String) -> String { - | - move occurs because `a` has type `String`, which does not implement the `Copy` trait -LL | dbg!(a, a); - | - ^ value used here after move - | | - | value moved here +error[E0382]: use of moved value: `b` + --> $DIR/dbg-issue-120327.rs:46:12 | -help: consider cloning the value if the performance cost is acceptable +LL | tmp => { + | --- value moved here +... +LL | let b: String = "".to_string(); + | - move occurs because `b` has type `String`, which does not implement the `Copy` trait +LL | my_dbg!(b, 1); +LL | return b; + | ^ value used here after move | -LL | dbg!(a.clone(), a); - | ++++++++ help: consider borrowing instead of transferring ownership | -LL | dbg!(&a, a); - | + +LL | my_dbg!(&b, 1); + | + +help: borrow this binding in the pattern to avoid moving the value + | +LL | ref tmp => { + | +++ error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:33:12 + --> $DIR/dbg-issue-120327.rs:57:12 | -LL | fn two_of_them(a: String) -> String { - | - move occurs because `a` has type `String`, which does not implement the `Copy` trait -LL | dbg!(a, a); - | - value moved here +LL | let a = String::new(); + | - move occurs because `a` has type `String`, which does not implement the `Copy` trait +LL | let _b = match a { +LL | tmp => { + | --- value moved here ... LL | return a; | ^ value used here after move | -help: consider cloning the value if the performance cost is acceptable - | -LL | dbg!(a, a.clone()); - | ++++++++ -help: consider borrowing instead of transferring ownership +help: borrow this binding in the pattern to avoid moving the value | -LL | dbg!(a, &a); - | + +LL | ref tmp => { + | +++ error[E0382]: borrow of moved value: `a` - --> $DIR/dbg-issue-120327.rs:42:14 + --> $DIR/dbg-issue-120327.rs:65:14 | LL | let a: String = "".to_string(); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | let _res = get_expr(dbg!(a)); - | - value moved here + | ------- value moved here LL | let _l = a.len(); | ^ value borrowed here after move | -help: consider cloning the value if the performance cost is acceptable - | -LL | let _res = get_expr(dbg!(a.clone())); - | ++++++++ help: consider borrowing instead of transferring ownership | LL | let _res = get_expr(dbg!(&a)); diff --git a/tests/ui/coercion/coerce-loop-issue-122561.rs b/tests/ui/coercion/coerce-loop-issue-122561.rs index 5f6f91e37d2ed..d79dfa28b0daf 100644 --- a/tests/ui/coercion/coerce-loop-issue-122561.rs +++ b/tests/ui/coercion/coerce-loop-issue-122561.rs @@ -42,8 +42,6 @@ fn for_single_line() -> bool { for i in 0.. { return false; } } // that it's readable fn for_in_arg(a: &[(); for x in 0..2 {}]) -> bool { //~^ ERROR mismatched types - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied true } @@ -88,8 +86,6 @@ fn loop_() -> bool { const C: i32 = { for i in 0.. { //~^ ERROR mismatched types - //~| ERROR `std::ops::RangeFrom<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::RangeFrom<{integer}>: const Iterator` is not satisfied } }; @@ -97,8 +93,6 @@ fn main() { let _ = [10; { for i in 0..5 { //~^ ERROR mismatched types - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied } }]; @@ -111,6 +105,4 @@ fn main() { let _ = |a: &[(); for x in 0..2 {}]| {}; //~^ ERROR mismatched types - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied } diff --git a/tests/ui/coercion/coerce-loop-issue-122561.stderr b/tests/ui/coercion/coerce-loop-issue-122561.stderr index a7621e0d9363d..3fd6671565f18 100644 --- a/tests/ui/coercion/coerce-loop-issue-122561.stderr +++ b/tests/ui/coercion/coerce-loop-issue-122561.stderr @@ -1,5 +1,5 @@ warning: denote infinite loops with `loop { ... }` - --> $DIR/coerce-loop-issue-122561.rs:51:5 + --> $DIR/coerce-loop-issue-122561.rs:49:5 | LL | while true { | ^^^^^^^^^^ help: use `loop` @@ -7,30 +7,11 @@ LL | while true { = note: `#[warn(while_true)]` on by default warning: denote infinite loops with `loop { ... }` - --> $DIR/coerce-loop-issue-122561.rs:75:5 + --> $DIR/coerce-loop-issue-122561.rs:73:5 | LL | while true { | ^^^^^^^^^^ help: use `loop` -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:43:33 - | -LL | fn for_in_arg(a: &[(); for x in 0..2 {}]) -> bool { - | ^^^^ required by a bound introduced by this call - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` - -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:43:33 - | -LL | fn for_in_arg(a: &[(); for x in 0..2 {}]) -> bool { - | ^^^^ - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - error[E0308]: mismatched types --> $DIR/coerce-loop-issue-122561.rs:43:24 | @@ -131,7 +112,7 @@ LL | fn for_single_line() -> bool { for i in 0.. { return false; } /* `bool` val | ++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:51:5 + --> $DIR/coerce-loop-issue-122561.rs:49:5 | LL | fn while_inifinite() -> bool { | ---- expected `bool` because of return type @@ -150,7 +131,7 @@ LL + /* `bool` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:60:5 + --> $DIR/coerce-loop-issue-122561.rs:58:5 | LL | fn while_finite() -> bool { | ---- expected `bool` because of return type @@ -170,7 +151,7 @@ LL + /* `bool` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:68:5 + --> $DIR/coerce-loop-issue-122561.rs:66:5 | LL | fn while_zero_times() -> bool { | ---- expected `bool` because of return type @@ -188,7 +169,7 @@ LL + /* `bool` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:75:5 + --> $DIR/coerce-loop-issue-122561.rs:73:5 | LL | fn while_never_type() -> ! { | - expected `!` because of return type @@ -206,30 +187,11 @@ LL ~ } LL + /* `loop {}` or `panic!("...")` */ | -error[E0277]: the trait bound `std::ops::RangeFrom<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:89:14 - | -LL | for i in 0.. { - | ^^^ required by a bound introduced by this call - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::RangeFrom<{integer}>` to implement `const IntoIterator` - -error[E0277]: the trait bound `std::ops::RangeFrom<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:89:14 - | -LL | for i in 0.. { - | ^^^ - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:89:5 + --> $DIR/coerce-loop-issue-122561.rs:87:5 | LL | / for i in 0.. { -... | +LL | | LL | | } | |_____^ expected `i32`, found `()` | @@ -240,30 +202,11 @@ LL ~ } LL + /* `i32` value */ | -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:98:18 - | -LL | for i in 0..5 { - | ^^^^ required by a bound introduced by this call - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` - -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:98:18 - | -LL | for i in 0..5 { - | ^^^^ - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:98:9 + --> $DIR/coerce-loop-issue-122561.rs:94:9 | LL | / for i in 0..5 { -... | +LL | | LL | | } | |_________^ expected `usize`, found `()` | @@ -275,7 +218,7 @@ LL + /* `usize` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:106:9 + --> $DIR/coerce-loop-issue-122561.rs:100:9 | LL | / while false { LL | | @@ -289,27 +232,8 @@ LL ~ } LL + /* `usize` value */ | -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:112:32 - | -LL | let _ = |a: &[(); for x in 0..2 {}]| {}; - | ^^^^ required by a bound introduced by this call - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` - -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/coerce-loop-issue-122561.rs:112:32 - | -LL | let _ = |a: &[(); for x in 0..2 {}]| {}; - | ^^^^ - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:112:23 + --> $DIR/coerce-loop-issue-122561.rs:106:23 | LL | let _ = |a: &[(); for x in 0..2 {}]| {}; | ^^^^^^^^^^^^^^^^ expected `usize`, found `()` @@ -320,7 +244,6 @@ help: consider returning a value here LL | let _ = |a: &[(); for x in 0..2 {} /* `usize` value */]| {}; | +++++++++++++++++++ -error: aborting due to 22 previous errors; 2 warnings emitted +error: aborting due to 14 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.stable.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops.stable.stderr index c39048c8f283c..2c7e6e8671351 100644 --- a/tests/ui/consts/const-eval/const_raw_ptr_ops.stable.stderr +++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.stable.stderr @@ -1,23 +1,18 @@ -error[E0277]: pointers cannot be reliably compared during const eval +error: pointers cannot be reliably compared during const eval --> $DIR/const_raw_ptr_ops.rs:7:26 | LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: trait `PartialEq` is implemented but not `const` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL = note: see issue #53020 for more information -error[E0277]: pointers cannot be reliably compared during const eval +error: pointers cannot be reliably compared during const eval --> $DIR/const_raw_ptr_ops.rs:9:27 | LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: trait `PartialEq` is implemented but not `const` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL = note: see issue #53020 for more information error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/const-fn-error.rs b/tests/ui/consts/const-fn-error.rs index 67053225e0a53..b71517824232f 100644 --- a/tests/ui/consts/const-fn-error.rs +++ b/tests/ui/consts/const-fn-error.rs @@ -3,8 +3,8 @@ const X : usize = 2; const fn f(x: usize) -> usize { let mut sum = 0; for i in 0..x { - //~^ ERROR `std::ops::Range: [const] Iterator` is not satisfied - //~| ERROR `std::ops::Range: [const] Iterator` is not satisfied + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` sum += i; } sum diff --git a/tests/ui/consts/const-fn-error.stderr b/tests/ui/consts/const-fn-error.stderr index f95cb47f22c5e..3d4cf6539c896 100644 --- a/tests/ui/consts/const-fn-error.stderr +++ b/tests/ui/consts/const-fn-error.stderr @@ -1,22 +1,20 @@ -error[E0277]: the trait bound `std::ops::Range: [const] Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constant functions --> $DIR/const-fn-error.rs:5:14 | LL | for i in 0..x { - | ^^^^ required by a bound introduced by this call + | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range` to implement `[const] IntoIterator` + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `std::ops::Range: [const] Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constant functions --> $DIR/const-fn-error.rs:5:14 | LL | for i in 0..x { | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-for-feature-gate.rs b/tests/ui/consts/const-for-feature-gate.rs index f361efdce8e3e..b643e63c09690 100644 --- a/tests/ui/consts/const-for-feature-gate.rs +++ b/tests/ui/consts/const-for-feature-gate.rs @@ -2,8 +2,8 @@ const _: () = { for _ in 0..5 {} - //~^ ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` }; fn main() {} diff --git a/tests/ui/consts/const-for-feature-gate.stderr b/tests/ui/consts/const-for-feature-gate.stderr index 3369ba8147a1b..29db5d24ac866 100644 --- a/tests/ui/consts/const-for-feature-gate.stderr +++ b/tests/ui/consts/const-for-feature-gate.stderr @@ -1,22 +1,20 @@ -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/const-for-feature-gate.rs:4:14 | LL | for _ in 0..5 {} - | ^^^^ required by a bound introduced by this call + | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/const-for-feature-gate.rs:4:14 | LL | for _ in 0..5 {} | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-for.rs b/tests/ui/consts/const-for.rs index b6d5ca70cfeb3..6f7895457c53d 100644 --- a/tests/ui/consts/const-for.rs +++ b/tests/ui/consts/const-for.rs @@ -2,8 +2,8 @@ const _: () = { for _ in 0..5 {} - //~^ ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` }; fn main() {} diff --git a/tests/ui/consts/const-for.stderr b/tests/ui/consts/const-for.stderr index 3cb4816fdbe4e..d1308a8dedc85 100644 --- a/tests/ui/consts/const-for.stderr +++ b/tests/ui/consts/const-for.stderr @@ -1,22 +1,20 @@ -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/const-for.rs:4:14 | LL | for _ in 0..5 {} - | ^^^^ required by a bound introduced by this call + | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/const-for.rs:4:14 | LL | for _ in 0..5 {} | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/control-flow/loop.rs b/tests/ui/consts/control-flow/loop.rs index 5311daec6143f..b02c31c4c25b5 100644 --- a/tests/ui/consts/control-flow/loop.rs +++ b/tests/ui/consts/control-flow/loop.rs @@ -51,14 +51,14 @@ const _: i32 = { let mut x = 0; for i in 0..4 { - //~^ ERROR: `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR: `std::ops::Range<{integer}>: const Iterator` is not satisfied + //~^ ERROR: cannot use `for` + //~| ERROR: cannot use `for` x += i; } for i in 0..4 { - //~^ ERROR: `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR: `std::ops::Range<{integer}>: const Iterator` is not satisfied + //~^ ERROR: cannot use `for` + //~| ERROR: cannot use `for` x += i; } diff --git a/tests/ui/consts/control-flow/loop.stderr b/tests/ui/consts/control-flow/loop.stderr index ec821d23a619c..b91371f9dc218 100644 --- a/tests/ui/consts/control-flow/loop.stderr +++ b/tests/ui/consts/control-flow/loop.stderr @@ -1,41 +1,37 @@ -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/loop.rs:53:14 | LL | for i in 0..4 { - | ^^^^ required by a bound introduced by this call + | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/loop.rs:53:14 | LL | for i in 0..4 { | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/loop.rs:59:14 | LL | for i in 0..4 { - | ^^^^ required by a bound introduced by this call + | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::Range` in constants --> $DIR/loop.rs:59:14 | LL | for i in 0..4 { | ^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stable.stderr b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stable.stderr index f13e0c6661814..92b09e7db0d45 100644 --- a/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stable.stderr +++ b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stable.stderr @@ -1,13 +1,10 @@ -error[E0277]: pointers cannot be reliably compared during const eval +error: pointers cannot be reliably compared during const eval --> $DIR/different-fn-ptr-binders-during-ctfe.rs:5:5 | LL | x == y | ^^^^^^ | -note: trait `PartialEq` is implemented but not `const` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL = note: see issue #53020 for more information error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/issue-25826.stderr b/tests/ui/consts/issue-25826.stderr index 9c03f1270d656..7d21020da6477 100644 --- a/tests/ui/consts/issue-25826.stderr +++ b/tests/ui/consts/issue-25826.stderr @@ -1,13 +1,10 @@ -error[E0277]: pointers cannot be reliably compared during const eval +error: pointers cannot be reliably compared during const eval --> $DIR/issue-25826.rs:3:30 | LL | const A: bool = unsafe { id:: as *const () < id:: as *const () }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: trait `PartialOrd` is implemented but not `const` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL = note: see issue #53020 for more information error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr index 47887a6c68b92..bfaccf1db1ca4 100644 --- a/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr +++ b/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr @@ -1,13 +1,10 @@ -error[E0277]: pointers cannot be reliably compared during const eval +error: pointers cannot be reliably compared during const eval --> $DIR/cmp_fn_pointers.rs:2:14 | LL | unsafe { x == y } | ^^^^^^ | -note: trait `PartialEq` is implemented but not `const` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL = note: see issue #53020 for more information error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/uninhabited-field.rs b/tests/ui/coroutine/uninhabited-field.rs index 6debd89ef4a9e..bc1f8d7733716 100644 --- a/tests/ui/coroutine/uninhabited-field.rs +++ b/tests/ui/coroutine/uninhabited-field.rs @@ -1,6 +1,7 @@ // Test that uninhabited saved local doesn't make the entire variant uninhabited. //@ run-pass #![allow(unused)] +#![feature(assert_matches)] #![feature(coroutine_trait)] #![feature(coroutines, stmt_expr_attributes)] #![feature(never_type)] diff --git a/tests/ui/feature-gates/feature-gate-diagnostic-on-const.rs b/tests/ui/feature-gates/feature-gate-diagnostic-on-const.rs index 890e4aa5a601d..398fa30e74047 100644 --- a/tests/ui/feature-gates/feature-gate-diagnostic-on-const.rs +++ b/tests/ui/feature-gates/feature-gate-diagnostic-on-const.rs @@ -10,7 +10,7 @@ use diagnostic_on_const::Foo; const fn foo() { Foo == Foo; - //~^ ERROR: the trait bound `Foo: [const] PartialEq` is not satisfied + //~^ ERROR: cannot call non-const operator in constant functions } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-diagnostic-on-const.stderr b/tests/ui/feature-gates/feature-gate-diagnostic-on-const.stderr index 4e2a573f72d78..04c901f4f938b 100644 --- a/tests/ui/feature-gates/feature-gate-diagnostic-on-const.stderr +++ b/tests/ui/feature-gates/feature-gate-diagnostic-on-const.stderr @@ -1,15 +1,16 @@ -error[E0277]: the trait bound `Foo: [const] PartialEq` is not satisfied +error[E0015]: cannot call non-const operator in constant functions --> $DIR/feature-gate-diagnostic-on-const.rs:12:5 | LL | Foo == Foo; | ^^^^^^^^^^ | -note: trait `PartialEq` is implemented but not `const` +note: impl defined here, but it is not `const` --> $DIR/auxiliary/diagnostic-on-const.rs:4:1 | LL | impl PartialEq for Foo { | ^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs index d40b869cd0cd8..4a3a197a582fc 100644 --- a/tests/ui/issues/issue-25901.rs +++ b/tests/ui/issues/issue-25901.rs @@ -2,13 +2,16 @@ struct A; struct B; static S: &'static B = &A; -//~^ ERROR the trait bound `A: const Deref` is not satisfied +//~^ ERROR cannot perform non-const deref coercion on `A` in statics use std::ops::Deref; impl Deref for A { type Target = B; - fn deref(&self)->&B { static B_: B = B; &B_ } + fn deref(&self) -> &B { + static B_: B = B; + &B_ + } } -fn main(){} +fn main() {} diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index 9b65366b969a5..233b5bfee5075 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -1,14 +1,23 @@ -error[E0277]: the trait bound `A: const Deref` is not satisfied +error[E0015]: cannot perform non-const deref coercion on `A` in statics --> $DIR/issue-25901.rs:4:24 | LL | static S: &'static B = &A; | ^^ | -help: make the `impl` of trait `Deref` `const` + = note: attempting to deref into `B` +note: deref defined here + --> $DIR/issue-25901.rs:10:5 | -LL | impl const Deref for A { - | +++++ +LL | type Target = B; + | ^^^^^^^^^^^ +note: impl defined here, but it is not `const` + --> $DIR/issue-25901.rs:9:1 + | +LL | impl Deref for A { + | ^^^^^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/liveness/liveness-upvars.rs b/tests/ui/liveness/liveness-upvars.rs index 0e198f1dea10b..be58b48a40576 100644 --- a/tests/ui/liveness/liveness-upvars.rs +++ b/tests/ui/liveness/liveness-upvars.rs @@ -98,7 +98,7 @@ pub fn g(mut v: T) { } pub fn h() { - let mut z = T::default(); //~ WARN unused variable: `z` + let mut z = T::default(); let _ = move |b| { loop { if b { diff --git a/tests/ui/liveness/liveness-upvars.stderr b/tests/ui/liveness/liveness-upvars.stderr index 0bb5786ab3e2e..cfed2830164ad 100644 --- a/tests/ui/liveness/liveness-upvars.stderr +++ b/tests/ui/liveness/liveness-upvars.stderr @@ -156,14 +156,6 @@ LL | z = T::default(); | = help: maybe it is overwritten before being read? -warning: unused variable: `z` - --> $DIR/liveness-upvars.rs:101:9 - | -LL | let mut z = T::default(); - | ^^^^^ help: if this is intentional, prefix it with an underscore: `_z` - | - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` - warning: value captured by `state` is never read --> $DIR/liveness-upvars.rs:131:9 | @@ -204,5 +196,5 @@ LL | s = yield (); | = help: maybe it is overwritten before being read? -warning: 25 warnings emitted +warning: 24 warnings emitted diff --git a/tests/ui/macros/assert-matches-macro-msg.rs b/tests/ui/macros/assert-matches-macro-msg.rs index 17900936a299b..8f4cd254f56b7 100644 --- a/tests/ui/macros/assert-matches-macro-msg.rs +++ b/tests/ui/macros/assert-matches-macro-msg.rs @@ -4,6 +4,8 @@ //@ error-pattern: right: 3 //@ needs-subprocess +#![feature(assert_matches)] + use std::assert_matches; fn main() { diff --git a/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.rs b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.rs index 1197eac72706a..4abef0bee81bd 100644 --- a/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.rs +++ b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.rs @@ -2,6 +2,4 @@ fn main() { |y: Vec<[(); for x in 0..2 {}]>| {}; //~^ ERROR mismatched types - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied - //~| ERROR `std::ops::Range<{integer}>: const Iterator` is not satisfied } diff --git a/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.stderr b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.stderr index 31287eda9600d..d60d97a02ab12 100644 --- a/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.stderr +++ b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.stderr @@ -1,22 +1,3 @@ -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/for-loop-in-vec-type-mismatchrs-50585.rs:3:27 - | -LL | |y: Vec<[(); for x in 0..2 {}]>| {}; - | ^^^^ required by a bound introduced by this call - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` - -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/for-loop-in-vec-type-mismatchrs-50585.rs:3:27 - | -LL | |y: Vec<[(); for x in 0..2 {}]>| {}; - | ^^^^ - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - error[E0308]: mismatched types --> $DIR/for-loop-in-vec-type-mismatchrs-50585.rs:3:18 | @@ -29,7 +10,6 @@ help: consider returning a value here LL | |y: Vec<[(); for x in 0..2 {} /* `usize` value */]>| {}; | +++++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/never_type/issue-52443.rs b/tests/ui/never_type/issue-52443.rs index f505719bfcee4..0e454eeb9ad35 100644 --- a/tests/ui/never_type/issue-52443.rs +++ b/tests/ui/never_type/issue-52443.rs @@ -7,6 +7,6 @@ fn main() { //~^ WARN denote infinite loops with [(); { for _ in 0usize.. {}; 0}]; - //~^ ERROR `std::ops::RangeFrom: const Iterator` is not satisfied - //~| ERROR `std::ops::RangeFrom: const Iterator` is not satisfied + //~^ ERROR cannot use `for` loop on `std::ops::RangeFrom` in constants + //~| ERROR cannot use `for` loop on `std::ops::RangeFrom` in constants } diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr index d754bc415781c..bb60c33595c25 100644 --- a/tests/ui/never_type/issue-52443.stderr +++ b/tests/ui/never_type/issue-52443.stderr @@ -31,26 +31,24 @@ help: give the `break` a value of the expected type LL | [(); loop { break 42 }]; | ++ -error[E0277]: the trait bound `std::ops::RangeFrom: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::RangeFrom` in constants --> $DIR/issue-52443.rs:9:21 | LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ required by a bound introduced by this call + | ^^^^^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::RangeFrom` to implement `const IntoIterator` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `std::ops::RangeFrom: const Iterator` is not satisfied +error[E0015]: cannot use `for` loop on `std::ops::RangeFrom` in constants --> $DIR/issue-52443.rs:9:21 | LL | [(); { for _ in 0usize.. {}; 0}]; | ^^^^^^^^ | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0308. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr index 7ce5ebf81e310..f8ef315b9cc78 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr @@ -1,21 +1,13 @@ error[E0382]: use of moved value: `a` - --> $DIR/dbg-macro-move-semantics.rs:9:18 + --> $DIR/dbg-macro-move-semantics.rs:9:13 | LL | let a = NoCopy(0); | - move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait LL | let _ = dbg!(a); - | - value moved here + | ------- value moved here LL | let _ = dbg!(a); - | ^ value used here after move + | ^^^^^^^ value used here after move | -note: if `NoCopy` implemented `Clone`, you could clone the value - --> $DIR/dbg-macro-move-semantics.rs:4:1 - | -LL | struct NoCopy(usize); - | ^^^^^^^^^^^^^ consider implementing `Clone` for this type -... -LL | let _ = dbg!(a); - | - you could clone this value help: consider borrowing instead of transferring ownership | LL | let _ = dbg!(&a); diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs index da3f385a3bcbc..46e4afd8532e1 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs @@ -9,8 +9,9 @@ struct Foo(u32); impl Foo { const fn get>(self: R) -> u32 { //~^ ERROR invalid generic `self` parameter type + //~| ERROR destructor of `R` cannot be evaluated at compile-time self.0 - //~^ ERROR the trait bound `R: [const] Deref` is not satisfied + //~^ ERROR cannot perform non-const deref coercion on `R` in constant functions } } diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index 0ea6b68d232ca..f217370b024b5 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -1,8 +1,20 @@ -error[E0277]: the trait bound `R: [const] Deref` is not satisfied - --> $DIR/arbitrary-self-from-method-substs-ice.rs:12:9 +error[E0015]: cannot perform non-const deref coercion on `R` in constant functions + --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 | LL | self.0 - | ^^^^ + | ^^^^^^ + | + = note: attempting to deref into `Foo` + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0493]: destructor of `R` cannot be evaluated at compile-time + --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43 + | +LL | const fn get>(self: R) -> u32 { + | ^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here error[E0801]: invalid generic `self` parameter type: `R` --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49 @@ -13,7 +25,7 @@ LL | const fn get>(self: R) -> u32 { = note: type of `self` must not be a method generic parameter type = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0801. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0493, E0801. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/stdlib-unit-tests/matches2021.rs b/tests/ui/stdlib-unit-tests/matches2021.rs index 0958e82f43e42..c3276cd883471 100644 --- a/tests/ui/stdlib-unit-tests/matches2021.rs +++ b/tests/ui/stdlib-unit-tests/matches2021.rs @@ -3,6 +3,8 @@ // regression test for https://github.com/rust-lang/rust/pull/85678 +#![feature(assert_matches)] + use std::assert_matches; fn main() { diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs index ae5899f084465..e61ae2760aab8 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs @@ -10,6 +10,6 @@ impl Default for A { #[derive_const(Default)] pub struct S(A); -//~^ ERROR: `A: [const] Default` is not satisfied +//~^ ERROR: cannot call non-const associated function fn main() {} diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr index ba6fb140f424e..5589579853283 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `A: [const] Default` is not satisfied +error[E0015]: cannot call non-const associated function `::default` in constant functions --> $DIR/derive-const-non-const-type.rs:12:14 | LL | #[derive_const(Default)] @@ -6,11 +6,8 @@ LL | #[derive_const(Default)] LL | pub struct S(A); | ^ | -help: make the `impl` of trait `Default` `const` - | -LL | impl const Default for A { - | +++++ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/cross-crate.rs b/tests/ui/traits/const-traits/cross-crate.rs index a91201e3566b4..b07aa8944c05d 100644 --- a/tests/ui/traits/const-traits/cross-crate.rs +++ b/tests/ui/traits/const-traits/cross-crate.rs @@ -17,9 +17,10 @@ fn non_const_context() { const fn const_context() { #[cfg(any(stocknc, gatednc))] NonConst.func(); - //[stocknc,gatednc]~^ ERROR: the trait bound + //[stocknc]~^ ERROR: cannot call + //[gatednc]~^^ ERROR: the trait bound Const.func(); - //[stock]~^ ERROR: cannot call + //[stock,stocknc]~^ ERROR: cannot call } fn main() {} diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr index 606793cd3149d..44a60c99ae9ea 100644 --- a/tests/ui/traits/const-traits/cross-crate.stock.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr @@ -1,5 +1,5 @@ error[E0658]: cannot call conditionally-const method `::func` in constant functions - --> $DIR/cross-crate.rs:21:11 + --> $DIR/cross-crate.rs:22:11 | LL | Const.func(); | ^^^^^^ diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr index 45e06c78cfb25..766c20aa8211f 100644 --- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr @@ -1,15 +1,23 @@ -error[E0277]: the trait bound `cross_crate::NonConst: [const] cross_crate::MyTrait` is not satisfied +error[E0015]: cannot call non-const method `::func` in constant functions --> $DIR/cross-crate.rs:19:14 | LL | NonConst.func(); - | ^^^^ + | ^^^^^^ | -note: trait `MyTrait` is implemented but not `const` - --> $DIR/auxiliary/cross-crate.rs:11:1 + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0658]: cannot call conditionally-const method `::func` in constant functions + --> $DIR/cross-crate.rs:22:11 + | +LL | Const.func(); + | ^^^^^^ | -LL | impl MyTrait for NonConst { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: see issue #143874 for more information + = help: add `#![feature(const_trait_impl)]` 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 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0658. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/gate.rs b/tests/ui/traits/const-traits/gate.rs index 3f348c8413930..d1c93ab9f95af 100644 --- a/tests/ui/traits/const-traits/gate.rs +++ b/tests/ui/traits/const-traits/gate.rs @@ -3,7 +3,6 @@ fn main() { (const || {})(); //~^ ERROR: const closures are experimental - //~| ERROR: the trait bound `{closure@$DIR/gate.rs:4:6: 4:14}: [const] Fn()` is not satisfied } macro_rules! e { diff --git a/tests/ui/traits/const-traits/gate.stderr b/tests/ui/traits/const-traits/gate.stderr index 6bef2c511ce7d..19fd54ff36983 100644 --- a/tests/ui/traits/const-traits/gate.stderr +++ b/tests/ui/traits/const-traits/gate.stderr @@ -9,7 +9,7 @@ LL | (const || {})(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const closures are experimental - --> $DIR/gate.rs:13:5 + --> $DIR/gate.rs:12:5 | LL | e!((const || {})); | ^^^^^ @@ -18,13 +18,6 @@ LL | e!((const || {})); = help: add `#![feature(const_closures)]` 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[E0277]: the trait bound `{closure@$DIR/gate.rs:4:6: 4:14}: [const] Fn()` is not satisfied - --> $DIR/gate.rs:4:5 - | -LL | (const || {})(); - | ^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0658. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr index 42b051cd8df82..1c56aa1297944 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr @@ -83,13 +83,15 @@ help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `co LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} | +++++ -error[E0277]: the trait bound `T: [const] Foo` is not satisfied +error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); - | ^ + | ^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 9 previous errors -Some errors have detailed explanations: E0277, E0658. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0658. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs index 55e8d3ca6e6ad..7dd434c528d09 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs @@ -36,8 +36,8 @@ const fn foo(x: &T) { //[yyn,ynn,nyn,nnn]~| ERROR: `[const]` can only be applied to `const` traits //[nyy,nyn,nny,nnn]~^^^ ERROR: const trait impls are experimental x.a(); - //[yyn,nyn]~^ ERROR: the trait bound `T: [const] Foo` is not satisfied - //[ynn,yny,nny,nnn]~^^ ERROR: cannot call non-const method `::a` in constant functions + //[yyn]~^ ERROR: the trait bound `T: [const] Foo` is not satisfied + //[ynn,yny,nny,nnn,nyn]~^^ ERROR: cannot call non-const method `::a` in constant functions //[nyy]~^^^ ERROR: cannot call conditionally-const method `::a` in constant functions } diff --git a/tests/ui/traits/next-solver/global-where-bound-normalization.rs b/tests/ui/traits/next-solver/global-where-bound-normalization.rs deleted file mode 100644 index e57fbf378a0d2..0000000000000 --- a/tests/ui/traits/next-solver/global-where-bound-normalization.rs +++ /dev/null @@ -1,45 +0,0 @@ -//@ check-pass -//@ compile-flags: -Znext-solver - -// Regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/257. - -#![feature(rustc_attrs)] -#![expect(internal_features)] -#![rustc_no_implicit_bounds] - -pub trait Bound {} -impl Bound for u8 {} - -pub trait Proj { - type Assoc; -} -impl Proj for U { - type Assoc = U; -} -impl Proj for MyField { - type Assoc = u8; -} - -// While wf-checking the global bounds of `fn foo`, elaborating this outlives predicate triggered a -// cycle in the search graph along a particular probe path, which was not an actual solution. -// That cycle then resulted in a forced false-positive ambiguity due to a performance hack in the -// search graph and then ended up floundering the root goal evaluation. -pub trait Field: Proj {} - -struct MyField; -impl Field for MyField {} - -trait IdReqField { - type This; -} -impl IdReqField for F { - type This = F; -} - -fn foo() -where - ::This: Field, -{ -} - -fn main() {} diff --git a/tests/ui/typeck/for-in-const-eval.rs b/tests/ui/typeck/for-in-const-eval.rs index 8de969e3eee05..f187a9ef30771 100644 --- a/tests/ui/typeck/for-in-const-eval.rs +++ b/tests/ui/typeck/for-in-const-eval.rs @@ -2,6 +2,4 @@ fn main() { Vec::<[(); 1 + for x in 0..1 {}]>::new(); //~^ ERROR cannot add - //~| ERROR const Iterator` is not satisfied - //~| ERROR const Iterator` is not satisfied } diff --git a/tests/ui/typeck/for-in-const-eval.stderr b/tests/ui/typeck/for-in-const-eval.stderr index 343da0f25ecd1..e7a2558495813 100644 --- a/tests/ui/typeck/for-in-const-eval.stderr +++ b/tests/ui/typeck/for-in-const-eval.stderr @@ -1,22 +1,3 @@ -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/for-in-const-eval.rs:3:29 - | -LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); - | ^^^^ required by a bound introduced by this call - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - = note: required for `std::ops::Range<{integer}>` to implement `const IntoIterator` - -error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied - --> $DIR/for-in-const-eval.rs:3:29 - | -LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); - | ^^^^ - | -note: trait `Iterator` is implemented but not `const` - --> $SRC_DIR/core/src/iter/range.rs:LL:COL - error[E0277]: cannot add `()` to `{integer}` --> $DIR/for-in-const-eval.rs:3:18 | @@ -35,6 +16,6 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); `&f64` implements `Add` and 56 others -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.